QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsrasterminmaxwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasterminmaxwidget.h
3  ---------------------------------
4  begin : July 2012
5  copyright : (C) 2012 by Radim Blazek
6  email : radim dot blazek at gmail dot 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 <QSettings>
19 #include <QMessageBox>
20 
21 #include "qgsrasterlayer.h"
22 #include "qgsrasterminmaxwidget.h"
23 #include "qgsmapcanvas.h"
24 #include "qgsrasterrenderer.h"
25 #include "qgsrasterdataprovider.h"
26 #include "qgsrasterminmaxorigin.h"
27 #include "qgsdoublespinbox.h"
28 
29 const int IDX_WHOLE_RASTER = 0;
30 const int IDX_CURRENT_CANVAS = 1;
31 const int IDX_UPDATED_CANVAS = 2;
32 
34  : QWidget( parent )
35  , mLayer( layer )
36  , mLastRectangleValid( false )
37  , mBandsChanged( false )
38 {
39  QgsDebugMsgLevel( QStringLiteral( "Entered." ), 4 );
40  setupUi( this );
41 
42  // use maximum value as a clear value for the upper border of the cumulative cut
43  mCumulativeCutUpperDoubleSpinBox->setClearValueMode( QgsDoubleSpinBox::MaximumValue );
44 
45  connect( mUserDefinedRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mUserDefinedRadioButton_toggled );
46  connect( mMinMaxRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mMinMaxRadioButton_toggled );
47  connect( mStdDevRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mStdDevRadioButton_toggled );
48  connect( mCumulativeCutRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mCumulativeCutRadioButton_toggled );
49  connect( mStatisticsExtentCombo, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMinMaxWidget::mStatisticsExtentCombo_currentIndexChanged );
50  connect( mCumulativeCutLowerDoubleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMinMaxWidget::mCumulativeCutLowerDoubleSpinBox_valueChanged );
51  connect( mCumulativeCutUpperDoubleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMinMaxWidget::mCumulativeCutUpperDoubleSpinBox_valueChanged );
52  connect( mStdDevSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMinMaxWidget::mStdDevSpinBox_valueChanged );
53  connect( cboAccuracy, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMinMaxWidget::cboAccuracy_currentIndexChanged );
54 
55  const QgsRasterMinMaxOrigin defaultMinMaxOrigin;
56  setFromMinMaxOrigin( defaultMinMaxOrigin );
57 }
58 
60 {
61  mCanvas = canvas;
62 }
63 
65 {
66  return mCanvas;
67 }
68 
69 void QgsRasterMinMaxWidget::setBands( const QList<int> &bands )
70 {
71  mBandsChanged = bands != mBands;
72  mBands = bands;
73 }
74 
76 {
77  const int nExtentIdx = mStatisticsExtentCombo->currentIndex();
78  if ( nExtentIdx != IDX_CURRENT_CANVAS && nExtentIdx != IDX_UPDATED_CANVAS )
79  return QgsRectangle();
80 
81  if ( mLayer && mCanvas )
82  return mCanvas->mapSettings().outputExtentToLayerExtent( mLayer, mCanvas->extent() );
83  else if ( mCanvas )
84  return mCanvas->extent();
85  else
86  return QgsRectangle();
87 }
88 
90 {
91  mUserDefinedRadioButton->setChecked( true );
92  mStatisticsExtentCombo->setCurrentIndex( IDX_WHOLE_RASTER );
93 }
94 
95 void QgsRasterMinMaxWidget::mUserDefinedRadioButton_toggled( bool toggled )
96 {
97  mStatisticsExtentCombo->setEnabled( !toggled );
98  cboAccuracy->setEnabled( !toggled );
99  emit widgetChanged();
100 }
101 
103 {
104  switch ( minMaxOrigin.limits() )
105  {
107  mUserDefinedRadioButton->setChecked( true );
108  break;
109 
111  mMinMaxRadioButton->setChecked( true );
112  break;
113 
115  mStdDevRadioButton->setChecked( true );
116  break;
117 
119  mCumulativeCutRadioButton->setChecked( true );
120  break;
121  }
122 
123  switch ( minMaxOrigin.extent() )
124  {
126  mStatisticsExtentCombo->setCurrentIndex( IDX_WHOLE_RASTER );
127  break;
128 
130  mStatisticsExtentCombo->setCurrentIndex( IDX_CURRENT_CANVAS );
131  break;
132 
134  mStatisticsExtentCombo->setCurrentIndex( IDX_UPDATED_CANVAS );
135  break;
136  }
137 
138  mCumulativeCutLowerDoubleSpinBox->setValue( 100.0 * minMaxOrigin.cumulativeCutLower() );
139  mCumulativeCutUpperDoubleSpinBox->setValue( 100.0 * minMaxOrigin.cumulativeCutUpper() );
140  mStdDevSpinBox->setValue( minMaxOrigin.stdDevFactor() );
141 
142  cboAccuracy->setCurrentIndex( minMaxOrigin.statAccuracy() == QgsRasterMinMaxOrigin::Estimated ? 0 : 1 );
143 }
144 
146 {
148 
149  if ( mMinMaxRadioButton->isChecked() )
151  else if ( mStdDevRadioButton->isChecked() )
153  else if ( mCumulativeCutRadioButton->isChecked() )
155  else
157 
158  switch ( mStatisticsExtentCombo->currentIndex() )
159  {
160  case IDX_WHOLE_RASTER:
161  default:
163  break;
164  case IDX_CURRENT_CANVAS:
166  break;
167  case IDX_UPDATED_CANVAS:
169  break;
170  }
171 
172  if ( cboAccuracy->currentIndex() == 0 )
174  else
176 
178  mCumulativeCutLowerDoubleSpinBox->value() / 100.0 );
180  mCumulativeCutUpperDoubleSpinBox->value() / 100.0 );
181  minMaxOrigin.setStdDevFactor( mStdDevSpinBox->value() );
182 
183  return minMaxOrigin;
184 }
185 
187 {
188  QgsDebugMsgLevel( QStringLiteral( "Entered." ), 4 );
189  if ( !mLayer->dataProvider() )
190  return;
191 
192  const QgsRectangle myExtent = extent(); // empty == full
193  const int mySampleSize = sampleSize(); // 0 == exact
194 
195  const QgsRasterMinMaxOrigin newMinMaxOrigin = minMaxOrigin();
196  if ( mLastRectangleValid && mLastRectangle == myExtent &&
197  mLastMinMaxOrigin == newMinMaxOrigin &&
198  !mBandsChanged )
199  {
200  QgsDebugMsgLevel( QStringLiteral( "Does not need to redo statistics computations" ), 2 );
201  return;
202  }
203 
204  mLastRectangleValid = true;
205  mLastRectangle = myExtent;
206  mLastMinMaxOrigin = newMinMaxOrigin;
207  mBandsChanged = false;
208 
209  for ( const int myBand : std::as_const( mBands ) )
210  {
211  QgsDebugMsgLevel( QStringLiteral( "myBand = %1" ).arg( myBand ), 2 );
212  if ( myBand < 1 || myBand > mLayer->dataProvider()->bandCount() )
213  {
214  continue;
215  }
216  double myMin = std::numeric_limits<double>::quiet_NaN();
217  double myMax = std::numeric_limits<double>::quiet_NaN();
218 
219  bool updateMinMax = false;
220  if ( mCumulativeCutRadioButton->isChecked() )
221  {
222  updateMinMax = true;
223  const double myLower = mCumulativeCutLowerDoubleSpinBox->value() / 100.0;
224  const double myUpper = mCumulativeCutUpperDoubleSpinBox->value() / 100.0;
225  mLayer->dataProvider()->cumulativeCut( myBand, myLower, myUpper, myMin, myMax, myExtent, mySampleSize );
226  }
227  else if ( mMinMaxRadioButton->isChecked() )
228  {
229  updateMinMax = true;
230  // TODO: consider provider minimum/maximumValue() (has to be defined well in povider)
231  const QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Min | QgsRasterBandStats::Max, myExtent, mySampleSize );
232  myMin = myRasterBandStats.minimumValue;
233  myMax = myRasterBandStats.maximumValue;
234  }
235  else if ( mStdDevRadioButton->isChecked() )
236  {
237  updateMinMax = true;
238  const QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev, myExtent, mySampleSize );
239  const double myStdDev = mStdDevSpinBox->value();
240  myMin = myRasterBandStats.mean - ( myStdDev * myRasterBandStats.stdDev );
241  myMax = myRasterBandStats.mean + ( myStdDev * myRasterBandStats.stdDev );
242  }
243 
244  if ( updateMinMax )
245  emit load( myBand, myMin, myMax );
246  }
247 }
248 
250 {
251  mStatisticsExtentCombo->removeItem( IDX_UPDATED_CANVAS );
252 }
QgsRasterMinMaxWidget::userHasSetManualMinMaxValues
void userHasSetManualMinMaxValues()
Uncheck cumulative cut, min/max, std-dev radio buttons.
Definition: qgsrasterminmaxwidget.cpp:89
qgsrasterminmaxorigin.h
QgsRasterMinMaxWidget::hideUpdatedExtent
void hideUpdatedExtent()
Hide updated extent choice.
Definition: qgsrasterminmaxwidget.cpp:249
QgsMapCanvas::extent
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
Definition: qgsmapcanvas.cpp:1331
qgsrasterlayer.h
QgsRasterMinMaxOrigin::setStdDevFactor
void setStdDevFactor(double val)
Sets the factor f so that the min/max range is [ mean - f * stddev , mean + f * stddev ].
Definition: qgsrasterminmaxorigin.h:144
qgsdoublespinbox.h
QgsRasterMinMaxWidget::widgetChanged
void widgetChanged()
Emitted when something on the widget has changed.
QgsRasterInterface::bandStatistics
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
Definition: qgsrasterinterface.cpp:116
qgsmapcanvas.h
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsRasterInterface::cumulativeCut
virtual void cumulativeCut(int bandNo, double lowerCount, double upperCount, double &lowerValue, double &upperValue, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0)
Find values for cumulative pixel count cut.
Definition: qgsrasterinterface.cpp:523
QgsRasterBandStats
The RasterBandStats struct is a container for statistics about a single raster band.
Definition: qgsrasterbandstats.h:34
QgsMapCanvas::mapSettings
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
Definition: qgsmapcanvas.cpp:437
QgsMapSettings::outputExtentToLayerExtent
QgsRectangle outputExtentToLayerExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from output CRS to layer's CRS
Definition: qgsmapsettings.cpp:553
QgsMapCanvas
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:89
QgsRasterBandStats::mean
double mean
The mean cell value for the band. NO_DATA values are excluded.
Definition: qgsrasterbandstats.h:110
IDX_CURRENT_CANVAS
const int IDX_CURRENT_CANVAS
Definition: qgsrasterminmaxwidget.cpp:30
qgsrasterrenderer.h
QgsRasterMinMaxOrigin::setStatAccuracy
void setStatAccuracy(QgsRasterMinMaxOrigin::StatAccuracy accuracy)
Sets the statistics accuracy.
Definition: qgsrasterminmaxorigin.h:135
QgsRasterMinMaxWidget::mapCanvas
QgsMapCanvas * mapCanvas()
Returns the map canvas associated with the widget.
Definition: qgsrasterminmaxwidget.cpp:64
QgsRasterMinMaxOrigin::stdDevFactor
double stdDevFactor() const
Returns the factor f so that the min/max range is [ mean - f * stddev , mean + f * stddev ].
Definition: qgsrasterminmaxorigin.h:124
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsRasterMinMaxOrigin::WholeRaster
@ WholeRaster
Whole raster is used to compute statistics.
Definition: qgsrasterminmaxorigin.h:84
IDX_UPDATED_CANVAS
const int IDX_UPDATED_CANVAS
Definition: qgsrasterminmaxwidget.cpp:31
QgsRasterMinMaxWidget::setFromMinMaxOrigin
void setFromMinMaxOrigin(const QgsRasterMinMaxOrigin &)
Sets the "source" of min/max values.
Definition: qgsrasterminmaxwidget.cpp:102
QgsRasterMinMaxOrigin
This class describes the origin of min/max values. It does not store by itself the min/max values.
Definition: qgsrasterminmaxorigin.h:33
QgsRasterMinMaxWidget::minMaxOrigin
QgsRasterMinMaxOrigin minMaxOrigin()
Returns a QgsRasterMinMaxOrigin object with the widget values.
Definition: qgsrasterminmaxwidget.cpp:145
QgsRasterBandStats::maximumValue
double maximumValue
The maximum cell value in the raster band.
Definition: qgsrasterbandstats.h:101
QgsRasterMinMaxOrigin::CumulativeCut
@ CumulativeCut
Range is [ min + cumulativeCutLower() * (max - min), min + cumulativeCutUpper() * (max - min) ].
Definition: qgsrasterminmaxorigin.h:76
QgsRasterMinMaxOrigin::MinMax
@ MinMax
Real min-max values.
Definition: qgsrasterminmaxorigin.h:74
QgsRasterMinMaxWidget::load
void load(int bandNo, double min, double max)
signal emitted when new min/max values are computed from statistics.
QgsRasterMinMaxOrigin::Exact
@ Exact
Exact statistics.
Definition: qgsrasterminmaxorigin.h:95
QgsRasterMinMaxOrigin::cumulativeCutLower
double cumulativeCutLower() const
Returns the lower bound of cumulative cut method (between 0 and 1).
Definition: qgsrasterminmaxorigin.h:118
QgsRasterMinMaxWidget::doComputations
void doComputations()
Load programmatically with current values.
Definition: qgsrasterminmaxwidget.cpp:186
QgsRasterBandStats::StdDev
@ StdDev
Definition: qgsrasterbandstats.h:71
QgsRasterMinMaxWidget::setMapCanvas
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
Definition: qgsrasterminmaxwidget.cpp:59
QgsRasterBandStats::Min
@ Min
Definition: qgsrasterbandstats.h:66
QgsRasterLayer
Represents a raster layer.
Definition: qgsrasterlayer.h:76
QgsRasterBandStats::Mean
@ Mean
Definition: qgsrasterbandstats.h:70
QgsRasterMinMaxOrigin::UpdatedCanvas
@ UpdatedCanvas
Constantly updated extent of the canvas is used to compute statistics.
Definition: qgsrasterminmaxorigin.h:88
QgsRasterMinMaxOrigin::Estimated
@ Estimated
Approximated statistics.
Definition: qgsrasterminmaxorigin.h:97
QgsRasterBandStats::minimumValue
double minimumValue
The minimum cell value in the raster band.
Definition: qgsrasterbandstats.h:107
QgsRasterBandStats::Max
@ Max
Definition: qgsrasterbandstats.h:67
QgsRasterMinMaxWidget::sampleSize
int sampleSize()
Returns the selected sample size.
Definition: qgsrasterminmaxwidget.h:79
QgsRasterMinMaxOrigin::StdDev
@ StdDev
Range is [ mean - stdDevFactor() * stddev, mean + stdDevFactor() * stddev ].
Definition: qgsrasterminmaxorigin.h:75
qgsrasterminmaxwidget.h
QgsRasterMinMaxOrigin::setLimits
void setLimits(QgsRasterMinMaxOrigin::Limits limits)
Sets the limits.
Definition: qgsrasterminmaxorigin.h:129
QgsRasterMinMaxOrigin::statAccuracy
QgsRasterMinMaxOrigin::StatAccuracy statAccuracy() const
Returns the raster statistic accuracy.
Definition: qgsrasterminmaxorigin.h:115
QgsRasterMinMaxWidget::extent
QgsRectangle extent()
Returns the extent selected by the user.
Definition: qgsrasterminmaxwidget.cpp:75
QgsRasterMinMaxWidget::setBands
void setBands(const QList< int > &bands)
Definition: qgsrasterminmaxwidget.cpp:69
QgsRasterMinMaxOrigin::setCumulativeCutUpper
void setCumulativeCutUpper(double val)
Sets the upper bound of cumulative cut method (between 0 and 1).
Definition: qgsrasterminmaxorigin.h:141
QgsRasterBandStats::stdDev
double stdDev
The standard deviation of the cell values.
Definition: qgsrasterbandstats.h:116
QgsRasterMinMaxOrigin::setExtent
void setExtent(QgsRasterMinMaxOrigin::Extent extent)
Sets the extent.
Definition: qgsrasterminmaxorigin.h:132
IDX_WHOLE_RASTER
const int IDX_WHOLE_RASTER
Definition: qgsrasterminmaxwidget.cpp:29
QgsRasterInterface::bandCount
virtual int bandCount() const =0
Gets number of bands.
QgsRasterMinMaxOrigin::None
@ None
User defined.
Definition: qgsrasterminmaxorigin.h:73
QgsRasterMinMaxOrigin::CurrentCanvas
@ CurrentCanvas
Current extent of the canvas (at the time of computation) is used to compute statistics.
Definition: qgsrasterminmaxorigin.h:86
QgsRasterMinMaxOrigin::extent
QgsRasterMinMaxOrigin::Extent extent() const
Returns the raster extent.
Definition: qgsrasterminmaxorigin.h:112
QgsRasterMinMaxWidget::QgsRasterMinMaxWidget
QgsRasterMinMaxWidget(QgsRasterLayer *layer, QWidget *parent=nullptr)
Constructor for QgsRasterMinMaxWidget.
Definition: qgsrasterminmaxwidget.cpp:33
QgsRasterMinMaxOrigin::limits
QgsRasterMinMaxOrigin::Limits limits() const
Returns the raster limits.
Definition: qgsrasterminmaxorigin.h:109
QgsDoubleSpinBox::MaximumValue
@ MaximumValue
Reset value to maximum()
Definition: qgsdoublespinbox.h:65
QgsRasterMinMaxOrigin::setCumulativeCutLower
void setCumulativeCutLower(double val)
Sets the lower bound of cumulative cut method (between 0 and 1).
Definition: qgsrasterminmaxorigin.h:138
QgsRasterLayer::dataProvider
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
Definition: qgsrasterlayer.cpp:257
QgsRasterMinMaxOrigin::cumulativeCutUpper
double cumulativeCutUpper() const
Returns the upper bound of cumulative cut method (between 0 and 1).
Definition: qgsrasterminmaxorigin.h:121
qgsrasterdataprovider.h