QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 
28 const int IDX_WHOLE_RASTER = 0;
29 const int IDX_CURRENT_CANVAS = 1;
30 const int IDX_UPDATED_CANVAS = 2;
31 
33  : QWidget( parent )
34  , mLayer( layer )
35  , mLastRectangleValid( false )
36  , mBandsChanged( false )
37 {
38  QgsDebugMsgLevel( QStringLiteral( "Entered." ), 4 );
39  setupUi( this );
40  connect( mUserDefinedRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mUserDefinedRadioButton_toggled );
41  connect( mMinMaxRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mMinMaxRadioButton_toggled );
42  connect( mStdDevRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mStdDevRadioButton_toggled );
43  connect( mCumulativeCutRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mCumulativeCutRadioButton_toggled );
44  connect( mStatisticsExtentCombo, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMinMaxWidget::mStatisticsExtentCombo_currentIndexChanged );
45  connect( mCumulativeCutLowerDoubleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMinMaxWidget::mCumulativeCutLowerDoubleSpinBox_valueChanged );
46  connect( mCumulativeCutUpperDoubleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMinMaxWidget::mCumulativeCutUpperDoubleSpinBox_valueChanged );
47  connect( mStdDevSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMinMaxWidget::mStdDevSpinBox_valueChanged );
48  connect( cboAccuracy, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMinMaxWidget::cboAccuracy_currentIndexChanged );
49 
50  QgsRasterMinMaxOrigin defaultMinMaxOrigin;
51  setFromMinMaxOrigin( defaultMinMaxOrigin );
52 }
53 
55 {
56  mCanvas = canvas;
57 }
58 
60 {
61  return mCanvas;
62 }
63 
64 void QgsRasterMinMaxWidget::setBands( const QList<int> &bands )
65 {
66  mBandsChanged = bands != mBands;
67  mBands = bands;
68 }
69 
71 {
72  const int nExtentIdx = mStatisticsExtentCombo->currentIndex();
73  if ( nExtentIdx != IDX_CURRENT_CANVAS && nExtentIdx != IDX_UPDATED_CANVAS )
74  return QgsRectangle();
75 
76  if ( mLayer && mCanvas )
77  return mCanvas->mapSettings().outputExtentToLayerExtent( mLayer, mCanvas->extent() );
78  else if ( mCanvas )
79  return mCanvas->extent();
80  else
81  return QgsRectangle();
82 }
83 
85 {
86  mUserDefinedRadioButton->setChecked( true );
87  mStatisticsExtentCombo->setCurrentIndex( IDX_WHOLE_RASTER );
88 }
89 
90 void QgsRasterMinMaxWidget::mUserDefinedRadioButton_toggled( bool toggled )
91 {
92  mStatisticsExtentCombo->setEnabled( !toggled );
93  cboAccuracy->setEnabled( !toggled );
94  emit widgetChanged();
95 }
96 
98 {
99  switch ( minMaxOrigin.limits() )
100  {
102  mUserDefinedRadioButton->setChecked( true );
103  break;
104 
106  mMinMaxRadioButton->setChecked( true );
107  break;
108 
110  mStdDevRadioButton->setChecked( true );
111  break;
112 
114  mCumulativeCutRadioButton->setChecked( true );
115  break;
116  }
117 
118  switch ( minMaxOrigin.extent() )
119  {
121  mStatisticsExtentCombo->setCurrentIndex( IDX_WHOLE_RASTER );
122  break;
123 
125  mStatisticsExtentCombo->setCurrentIndex( IDX_CURRENT_CANVAS );
126  break;
127 
129  mStatisticsExtentCombo->setCurrentIndex( IDX_UPDATED_CANVAS );
130  break;
131  }
132 
133  mCumulativeCutLowerDoubleSpinBox->setValue( 100.0 * minMaxOrigin.cumulativeCutLower() );
134  mCumulativeCutUpperDoubleSpinBox->setValue( 100.0 * minMaxOrigin.cumulativeCutUpper() );
135  mStdDevSpinBox->setValue( minMaxOrigin.stdDevFactor() );
136 
137  cboAccuracy->setCurrentIndex( minMaxOrigin.statAccuracy() == QgsRasterMinMaxOrigin::Estimated ? 0 : 1 );
138 }
139 
141 {
143 
144  if ( mMinMaxRadioButton->isChecked() )
146  else if ( mStdDevRadioButton->isChecked() )
148  else if ( mCumulativeCutRadioButton->isChecked() )
150  else
152 
153  switch ( mStatisticsExtentCombo->currentIndex() )
154  {
155  case IDX_WHOLE_RASTER:
156  default:
158  break;
159  case IDX_CURRENT_CANVAS:
161  break;
162  case IDX_UPDATED_CANVAS:
164  break;
165  }
166 
167  if ( cboAccuracy->currentIndex() == 0 )
169  else
171 
173  mCumulativeCutLowerDoubleSpinBox->value() / 100.0 );
175  mCumulativeCutUpperDoubleSpinBox->value() / 100.0 );
176  minMaxOrigin.setStdDevFactor( mStdDevSpinBox->value() );
177 
178  return minMaxOrigin;
179 }
180 
182 {
183  QgsDebugMsgLevel( QStringLiteral( "Entered." ), 4 );
184  if ( !mLayer->dataProvider() )
185  return;
186 
187  QgsRectangle myExtent = extent(); // empty == full
188  int mySampleSize = sampleSize(); // 0 == exact
189 
190  QgsRasterMinMaxOrigin newMinMaxOrigin = minMaxOrigin();
191  if ( mLastRectangleValid && mLastRectangle == myExtent &&
192  mLastMinMaxOrigin == newMinMaxOrigin &&
193  !mBandsChanged )
194  {
195  QgsDebugMsg( QStringLiteral( "Does not need to redo statistics computations" ) );
196  return;
197  }
198 
199  mLastRectangleValid = true;
200  mLastRectangle = myExtent;
201  mLastMinMaxOrigin = newMinMaxOrigin;
202  mBandsChanged = false;
203 
204  const auto constMBands = mBands;
205  for ( int myBand : constMBands )
206  {
207  QgsDebugMsg( QStringLiteral( "myBand = %1" ).arg( myBand ) );
208  if ( myBand < 1 || myBand > mLayer->dataProvider()->bandCount() )
209  {
210  continue;
211  }
212  double myMin = std::numeric_limits<double>::quiet_NaN();
213  double myMax = std::numeric_limits<double>::quiet_NaN();
214 
215  bool updateMinMax = false;
216  if ( mCumulativeCutRadioButton->isChecked() )
217  {
218  updateMinMax = true;
219  double myLower = mCumulativeCutLowerDoubleSpinBox->value() / 100.0;
220  double myUpper = mCumulativeCutUpperDoubleSpinBox->value() / 100.0;
221  mLayer->dataProvider()->cumulativeCut( myBand, myLower, myUpper, myMin, myMax, myExtent, mySampleSize );
222  }
223  else if ( mMinMaxRadioButton->isChecked() )
224  {
225  updateMinMax = true;
226  // TODO: consider provider minimum/maximumValue() (has to be defined well in povider)
227  QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Min | QgsRasterBandStats::Max, myExtent, mySampleSize );
228  myMin = myRasterBandStats.minimumValue;
229  myMax = myRasterBandStats.maximumValue;
230  }
231  else if ( mStdDevRadioButton->isChecked() )
232  {
233  updateMinMax = true;
234  QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev, myExtent, mySampleSize );
235  double myStdDev = mStdDevSpinBox->value();
236  myMin = myRasterBandStats.mean - ( myStdDev * myRasterBandStats.stdDev );
237  myMax = myRasterBandStats.mean + ( myStdDev * myRasterBandStats.stdDev );
238  }
239 
240  if ( updateMinMax )
241  emit load( myBand, myMin, myMax );
242  }
243 }
244 
246 {
247  mStatisticsExtentCombo->removeItem( IDX_UPDATED_CANVAS );
248 }
QgsRasterMinMaxWidget::userHasSetManualMinMaxValues
void userHasSetManualMinMaxValues()
Uncheck cumulative cut, min/max, std-dev radio buttons.
Definition: qgsrasterminmaxwidget.cpp:84
qgsrasterminmaxorigin.h
QgsRasterMinMaxWidget::hideUpdatedExtent
void hideUpdatedExtent()
Hide updated extent choice.
Definition: qgsrasterminmaxwidget.cpp:245
QgsMapCanvas::extent
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
Definition: qgsmapcanvas.cpp:1049
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
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:522
QgsRasterBandStats
Definition: qgsrasterbandstats.h:34
QgsMapCanvas::mapSettings
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
Definition: qgsmapcanvas.cpp:390
QgsMapSettings::outputExtentToLayerExtent
QgsRectangle outputExtentToLayerExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from output CRS to layer's CRS
Definition: qgsmapsettings.cpp:457
QgsMapCanvas
Definition: qgsmapcanvas.h:83
QgsRasterBandStats::mean
double mean
The mean cell value for the band. NO_DATA values are excluded.
Definition: qgsrasterbandstats.h:107
IDX_CURRENT_CANVAS
const int IDX_CURRENT_CANVAS
Definition: qgsrasterminmaxwidget.cpp:29
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:59
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
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsRectangle
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:30
QgsRasterMinMaxWidget::setFromMinMaxOrigin
void setFromMinMaxOrigin(const QgsRasterMinMaxOrigin &)
Sets the "source" of min/max values.
Definition: qgsrasterminmaxwidget.cpp:97
QgsRasterMinMaxOrigin
Definition: qgsrasterminmaxorigin.h:33
QgsRasterMinMaxWidget::minMaxOrigin
QgsRasterMinMaxOrigin minMaxOrigin()
Returns a QgsRasterMinMaxOrigin object with the widget values.
Definition: qgsrasterminmaxwidget.cpp:140
QgsRasterBandStats::maximumValue
double maximumValue
The maximum cell value in the raster band.
Definition: qgsrasterbandstats.h:99
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:181
QgsRasterBandStats::StdDev
@ StdDev
Definition: qgsrasterbandstats.h:71
QgsRasterMinMaxWidget::setMapCanvas
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
Definition: qgsrasterminmaxwidget.cpp:54
QgsRasterBandStats::Min
@ Min
Definition: qgsrasterbandstats.h:66
QgsRasterLayer
Definition: qgsrasterlayer.h:72
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:104
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:70
QgsRasterMinMaxWidget::setBands
void setBands(const QList< int > &bands)
Definition: qgsrasterminmaxwidget.cpp:64
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:113
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:28
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:32
QgsRasterMinMaxOrigin::limits
QgsRasterMinMaxOrigin::Limits limits() const
Returns the raster limits.
Definition: qgsrasterminmaxorigin.h:109
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:233
QgsRasterMinMaxOrigin::cumulativeCutUpper
double cumulativeCutUpper() const
Returns the upper bound of cumulative cut method (between 0 and 1).
Definition: qgsrasterminmaxorigin.h:121
qgsrasterdataprovider.h