QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsresamplingutils.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsresamplingutils.cpp
3 --------------------
4 begin : 12/06/2020
5 copyright : (C) 2020 Even Rouault
6 email : even.rouault at spatialys.com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include "qgsrasterlayer.h"
20#include "qgsrasterresampler.h"
22#include "qgsresamplingutils.h"
25
26#include <QObject>
27#include <QComboBox>
28#include <QDoubleSpinBox>
29#include <QCheckBox>
30
32
33QgsResamplingUtils::QgsResamplingUtils() = default;
34
35void QgsResamplingUtils::initWidgets( QgsRasterLayer *rasterLayer,
36 QComboBox *zoomedInResamplingComboBox,
37 QComboBox *zoomedOutResamplingComboBox,
38 QDoubleSpinBox *maximumOversamplingSpinBox,
39 QCheckBox *cbEarlyResampling )
40{
41 mRasterLayer = rasterLayer;
42 mZoomedInResamplingComboBox = zoomedInResamplingComboBox;
43 mZoomedOutResamplingComboBox = zoomedOutResamplingComboBox;
44 mMaximumOversamplingSpinBox = maximumOversamplingSpinBox;
45 mCbEarlyResampling = cbEarlyResampling;
46
47 for ( QComboBox *combo : {mZoomedInResamplingComboBox, mZoomedOutResamplingComboBox } )
48 {
49 combo->addItem( QObject::tr( "Nearest Neighbour" ), static_cast<int>( QgsRasterDataProvider::ResamplingMethod::Nearest ) );
50 combo->addItem( QObject::tr( "Bilinear (2x2 Kernel)" ), static_cast<int>( QgsRasterDataProvider::ResamplingMethod::Bilinear ) );
51 combo->addItem( QObject::tr( "Cubic (4x4 Kernel)" ), static_cast<int>( QgsRasterDataProvider::ResamplingMethod::Cubic ) );
52 }
53
54 if ( mCbEarlyResampling->isChecked() )
55 {
56 addExtraEarlyResamplingMethodsToCombos();
57 }
58
59 QObject::connect( mCbEarlyResampling, &QCheckBox::toggled, this, [ = ]( bool state )
60 {
61 if ( state )
62 addExtraEarlyResamplingMethodsToCombos();
63 else
64 removeExtraEarlyResamplingMethodsFromCombos();
65 } );
66}
67
68void QgsResamplingUtils::refreshWidgetsFromLayer()
69{
70 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
71 mCbEarlyResampling->setVisible(
73 mCbEarlyResampling->setChecked( mRasterLayer->resamplingStage() == Qgis::RasterResamplingStage::Provider );
74
75 switch ( mRasterLayer->resamplingStage() )
76 {
78 removeExtraEarlyResamplingMethodsFromCombos();
79 break;
81 addExtraEarlyResamplingMethodsToCombos();
82 break;
83 }
84
85 if ( provider && mRasterLayer->resamplingStage() == Qgis::RasterResamplingStage::Provider )
86 {
87 mZoomedInResamplingComboBox->setCurrentIndex( mZoomedInResamplingComboBox->findData( static_cast<int>( provider->zoomedInResamplingMethod() ) ) );
88 mZoomedOutResamplingComboBox->setCurrentIndex( mZoomedOutResamplingComboBox->findData( static_cast<int>( provider->zoomedOutResamplingMethod() ) ) );
89
90 mMaximumOversamplingSpinBox->setValue( provider->maxOversampling() );
91 }
92 else
93 {
94 const QgsRasterResampleFilter *resampleFilter = mRasterLayer->resampleFilter();
95 //set combo boxes to current resampling types
96 if ( resampleFilter )
97 {
98 const QgsRasterResampler *zoomedInResampler = resampleFilter->zoomedInResampler();
99 if ( zoomedInResampler )
100 {
101 if ( zoomedInResampler->type() == QLatin1String( "bilinear" ) )
102 {
103 mZoomedInResamplingComboBox->setCurrentIndex( mZoomedInResamplingComboBox->findData( static_cast<int>( QgsRasterDataProvider::ResamplingMethod::Bilinear ) ) );
104 }
105 else if ( zoomedInResampler->type() == QLatin1String( "cubic" ) )
106 {
107 mZoomedInResamplingComboBox->setCurrentIndex( mZoomedInResamplingComboBox->findData( static_cast<int>( QgsRasterDataProvider::ResamplingMethod::Cubic ) ) );
108 }
109 }
110 else
111 {
112 mZoomedInResamplingComboBox->setCurrentIndex( mZoomedInResamplingComboBox->findData( static_cast<int>( QgsRasterDataProvider::ResamplingMethod::Nearest ) ) );
113 }
114
115 const QgsRasterResampler *zoomedOutResampler = resampleFilter->zoomedOutResampler();
116 if ( zoomedOutResampler )
117 {
118 if ( zoomedOutResampler->type() == QLatin1String( "bilinear" ) )
119 {
120 mZoomedOutResamplingComboBox->setCurrentIndex( mZoomedOutResamplingComboBox->findData( static_cast<int>( QgsRasterDataProvider::ResamplingMethod::Bilinear ) ) );
121 }
122 else if ( zoomedOutResampler->type() == QLatin1String( "cubic" ) )
123 {
124 mZoomedOutResamplingComboBox->setCurrentIndex( mZoomedOutResamplingComboBox->findData( static_cast<int>( QgsRasterDataProvider::ResamplingMethod::Cubic ) ) );
125 }
126 }
127 else
128 {
129 mZoomedOutResamplingComboBox->setCurrentIndex( mZoomedOutResamplingComboBox->findData( static_cast<int>( QgsRasterDataProvider::ResamplingMethod::Nearest ) ) );
130 }
131 mMaximumOversamplingSpinBox->setValue( resampleFilter->maxOversampling() );
132 }
133 }
134}
135
136
137void QgsResamplingUtils::refreshLayerFromWidgets()
138{
139 const QgsRasterDataProvider::ResamplingMethod zoomedInMethod =
141 mZoomedInResamplingComboBox->itemData( mZoomedInResamplingComboBox->currentIndex() ).toInt() );
142 const QgsRasterDataProvider::ResamplingMethod zoomedOutMethod =
144 mZoomedOutResamplingComboBox->itemData( mZoomedOutResamplingComboBox->currentIndex() ).toInt() );
145
146 mRasterLayer->setResamplingStage( mCbEarlyResampling->isChecked() ? Qgis::RasterResamplingStage::Provider : Qgis::RasterResamplingStage::ResampleFilter );
147 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
148 if ( provider )
149 {
150 provider->setZoomedInResamplingMethod( zoomedInMethod );
151 provider->setZoomedOutResamplingMethod( zoomedOutMethod );
152
153 provider->setMaxOversampling( mMaximumOversamplingSpinBox->value() );
154 }
155
156 QgsRasterResampleFilter *resampleFilter = mRasterLayer->resampleFilter();
157 if ( resampleFilter )
158 {
159 std::unique_ptr< QgsRasterResampler > zoomedInResampler;
160
161 switch ( zoomedInMethod )
162 {
164 break;
165
167 zoomedInResampler = std::make_unique< QgsBilinearRasterResampler >();
168 break;
169
171 zoomedInResampler = std::make_unique< QgsCubicRasterResampler >();
172 break;
173
179
180 // not supported as late resampler methods
181 break;
182 }
183
184 resampleFilter->setZoomedInResampler( zoomedInResampler.release() );
185
186 //raster resampling
187 std::unique_ptr< QgsRasterResampler > zoomedOutResampler;
188
189 switch ( zoomedOutMethod )
190 {
192 break;
193
195 zoomedOutResampler = std::make_unique< QgsBilinearRasterResampler >();
196 break;
197
199 zoomedOutResampler = std::make_unique< QgsCubicRasterResampler >();
200 break;
201
202
208 // not supported as late resampler methods
209 break;
210 }
211
212 resampleFilter->setZoomedOutResampler( zoomedOutResampler.release() );
213
214 resampleFilter->setMaxOversampling( mMaximumOversamplingSpinBox->value() );
215 }
216}
217
218void QgsResamplingUtils::addExtraEarlyResamplingMethodsToCombos()
219{
220 if ( mZoomedInResamplingComboBox->findData( static_cast<int>( QgsRasterDataProvider::ResamplingMethod::CubicSpline ) ) != -1 )
221 return; // already present
222
223 for ( QComboBox *combo : {mZoomedInResamplingComboBox, mZoomedOutResamplingComboBox } )
224 {
225 combo->addItem( QObject::tr( "Cubic B-Spline (4x4 Kernel)" ), static_cast<int>( QgsRasterDataProvider::ResamplingMethod::CubicSpline ) );
226 combo->addItem( QObject::tr( "Lanczos (6x6 Kernel)" ), static_cast<int>( QgsRasterDataProvider::ResamplingMethod::Lanczos ) );
227 combo->addItem( QObject::tr( "Average" ), static_cast<int>( QgsRasterDataProvider::ResamplingMethod::Average ) );
228 combo->addItem( QObject::tr( "Mode" ), static_cast<int>( QgsRasterDataProvider::ResamplingMethod::Mode ) );
229 combo->addItem( QObject::tr( "Gauss" ), static_cast<int>( QgsRasterDataProvider::ResamplingMethod::Gauss ) );
230 }
231}
232
233void QgsResamplingUtils::removeExtraEarlyResamplingMethodsFromCombos()
234{
235 if ( mZoomedInResamplingComboBox->findData( static_cast<int>( QgsRasterDataProvider::ResamplingMethod::CubicSpline ) ) == -1 )
236 return; // already removed
237
238 for ( QComboBox *combo : {mZoomedInResamplingComboBox, mZoomedOutResamplingComboBox } )
239 {
240 for ( const QgsRasterDataProvider::ResamplingMethod method :
241 {
247 } )
248 {
249 combo->removeItem( combo->findData( static_cast< int >( method ) ) );
250 }
251 }
252}
253
@ Provider
Resampling occurs in Provider.
@ ResampleFilter
Resampling occurs in ResamplingFilter.
Base class for raster data providers.
ResamplingMethod zoomedOutResamplingMethod() const
Returns resampling method for zoomed-out operations.
virtual QgsRasterDataProvider::ProviderCapabilities providerCapabilities() const
Returns flags containing the supported capabilities of the data provider.
virtual bool setMaxOversampling(double factor)
Sets maximum oversampling factor for zoomed-out operations.
double maxOversampling() const
Returns maximum oversampling factor for zoomed-out operations.
@ ProviderHintCanPerformProviderResampling
Provider can perform resampling (to be opposed to post rendering resampling) (since QGIS 3....
virtual bool setZoomedInResamplingMethod(ResamplingMethod method)
Set resampling method to apply for zoomed-in operations.
ResamplingMethod zoomedInResamplingMethod() const
Returns resampling method for zoomed-in operations.
ResamplingMethod
Resampling method for provider-level resampling.
@ Lanczos
Lanczos windowed sinc interpolation (6x6 kernel)
@ Nearest
Nearest-neighbour resampling.
@ Mode
Mode (selects the value which appears most often of all the sampled points)
@ Bilinear
Bilinear (2x2 kernel) resampling.
@ CubicSpline
Cubic B-Spline Approximation (4x4 kernel)
@ Cubic
Cubic Convolution Approximation (4x4 kernel) resampling.
virtual bool setZoomedOutResamplingMethod(ResamplingMethod method)
Set resampling method to apply for zoomed-out operations.
Represents a raster layer.
Resample filter pipe for rasters.
void setZoomedOutResampler(QgsRasterResampler *r)
Sets resampler for zoomed out scales. Takes ownership of the object.
const QgsRasterResampler * zoomedInResampler() const
const QgsRasterResampler * zoomedOutResampler() const
void setZoomedInResampler(QgsRasterResampler *r)
Sets resampler for zoomed in scales. Takes ownership of the object.
Interface for resampling rasters (e.g.
virtual QString type() const =0
Gets a descriptive type identifier for this raster resampler.