QGIS API Documentation  3.21.0-Master (5b68dc587e)
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"
19 #include "qgsrasterdataprovider.h"
20 #include "qgsrasterresampler.h"
22 #include "qgsresamplingutils.h"
25 
26 #include <QObject>
27 #include <QComboBox>
28 #include <QDoubleSpinBox>
29 #include <QCheckBox>
30 
32 
33 QgsResamplingUtils::QgsResamplingUtils() = default;
34 
35 void 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" ), static_cast<int>( QgsRasterDataProvider::ResamplingMethod::Bilinear ) );
51  combo->addItem( QObject::tr( "Cubic" ), 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 
68 void 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 
137 void 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 
218 void 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 Spline" ), static_cast<int>( QgsRasterDataProvider::ResamplingMethod::CubicSpline ) );
226  combo->addItem( QObject::tr( "Lanczos" ), 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 
233 void 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 * zoomedOutResampler() const
const QgsRasterResampler * zoomedInResampler() 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.