QGIS API Documentation  2.99.0-Master (cb63e82)
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  , mCanvas( nullptr )
36  , mLastRectangleValid( false )
37  , mBandsChanged( false )
38 {
39  QgsDebugMsg( "Entered." );
40  setupUi( this );
41 
42  QgsRasterMinMaxOrigin defaultMinMaxOrigin;
43  setFromMinMaxOrigin( defaultMinMaxOrigin );
44 }
45 
47 {
48  mCanvas = canvas;
49 }
50 
52 {
53  return mCanvas;
54 }
55 
56 void QgsRasterMinMaxWidget::setBands( const QList<int> &bands )
57 {
58  mBandsChanged = bands != mBands;
59  mBands = bands;
60 }
61 
63 {
64  const int nExtentIdx = mStatisticsExtentCombo->currentIndex();
65  if ( nExtentIdx != IDX_CURRENT_CANVAS && nExtentIdx != IDX_UPDATED_CANVAS )
66  return QgsRectangle();
67 
68  if ( mLayer && mCanvas )
69  return mCanvas->mapSettings().outputExtentToLayerExtent( mLayer, mCanvas->extent() );
70  else if ( mCanvas )
71  return mCanvas->extent();
72  else
73  return QgsRectangle();
74 }
75 
77 {
78  mUserDefinedRadioButton->setChecked( true );
79  mStatisticsExtentCombo->setCurrentIndex( IDX_WHOLE_RASTER );
80 }
81 
82 void QgsRasterMinMaxWidget::on_mUserDefinedRadioButton_toggled( bool toggled )
83 {
84  mStatisticsExtentCombo->setEnabled( !toggled );
85  cboAccuracy->setEnabled( !toggled );
86  emit widgetChanged();
87 }
88 
90 {
91  switch ( minMaxOrigin.limits() )
92  {
94  default:
95  mUserDefinedRadioButton->setChecked( true );
96  break;
97 
99  mMinMaxRadioButton->setChecked( true );
100  break;
101 
103  mStdDevRadioButton->setChecked( true );
104  break;
105 
107  mCumulativeCutRadioButton->setChecked( true );
108  break;
109  }
110 
111  switch ( minMaxOrigin.extent() )
112  {
113  default:
115  mStatisticsExtentCombo->setCurrentIndex( IDX_WHOLE_RASTER );
116  break;
117 
119  mStatisticsExtentCombo->setCurrentIndex( IDX_CURRENT_CANVAS );
120  break;
121 
123  mStatisticsExtentCombo->setCurrentIndex( IDX_UPDATED_CANVAS );
124  break;
125  }
126 
127  mCumulativeCutLowerDoubleSpinBox->setValue( 100.0 * minMaxOrigin.cumulativeCutLower() );
128  mCumulativeCutUpperDoubleSpinBox->setValue( 100.0 * minMaxOrigin.cumulativeCutUpper() );
129  mStdDevSpinBox->setValue( minMaxOrigin.stdDevFactor() );
130 
131  cboAccuracy->setCurrentIndex( minMaxOrigin.statAccuracy() == QgsRasterMinMaxOrigin::Estimated ? 0 : 1 );
132 }
133 
135 {
137 
138  if ( mMinMaxRadioButton->isChecked() )
140  else if ( mStdDevRadioButton->isChecked() )
142  else if ( mCumulativeCutRadioButton->isChecked() )
144  else
145  minMaxOrigin.setLimits( QgsRasterMinMaxOrigin::None );
146 
147  switch ( mStatisticsExtentCombo->currentIndex() )
148  {
149  case IDX_WHOLE_RASTER:
150  default:
152  break;
153  case IDX_CURRENT_CANVAS:
155  break;
156  case IDX_UPDATED_CANVAS:
158  break;
159  }
160 
161  if ( cboAccuracy->currentIndex() == 0 )
163  else
165 
166  minMaxOrigin.setCumulativeCutLower(
167  mCumulativeCutLowerDoubleSpinBox->value() / 100.0 );
168  minMaxOrigin.setCumulativeCutUpper(
169  mCumulativeCutUpperDoubleSpinBox->value() / 100.0 );
170  minMaxOrigin.setStdDevFactor( mStdDevSpinBox->value() );
171 
172  return minMaxOrigin;
173 }
174 
176 {
177  QgsDebugMsg( "Entered." );
178 
179  QgsRectangle myExtent = extent(); // empty == full
180  int mySampleSize = sampleSize(); // 0 == exact
181 
182  QgsRasterMinMaxOrigin newMinMaxOrigin = minMaxOrigin();
183  if ( mLastRectangleValid && mLastRectangle == myExtent &&
184  mLastMinMaxOrigin == newMinMaxOrigin &&
185  !mBandsChanged )
186  {
187  QgsDebugMsg( "Does not need to redo statistics computations" );
188  return;
189  }
190 
191  mLastRectangleValid = true;
192  mLastRectangle = myExtent;
193  mLastMinMaxOrigin = newMinMaxOrigin;
194  mBandsChanged = false;
195 
196  Q_FOREACH ( int myBand, mBands )
197  {
198  QgsDebugMsg( QString( "myBand = %1" ).arg( myBand ) );
199  if ( myBand < 1 || myBand > mLayer->dataProvider()->bandCount() )
200  {
201  continue;
202  }
203  double myMin = std::numeric_limits<double>::quiet_NaN();
204  double myMax = std::numeric_limits<double>::quiet_NaN();
205 
206  bool updateMinMax = false;
207  if ( mCumulativeCutRadioButton->isChecked() )
208  {
209  updateMinMax = true;
210  double myLower = mCumulativeCutLowerDoubleSpinBox->value() / 100.0;
211  double myUpper = mCumulativeCutUpperDoubleSpinBox->value() / 100.0;
212  mLayer->dataProvider()->cumulativeCut( myBand, myLower, myUpper, myMin, myMax, myExtent, mySampleSize );
213  }
214  else if ( mMinMaxRadioButton->isChecked() )
215  {
216  updateMinMax = true;
217  // TODO: consider provider minimum/maximumValue() (has to be defined well in povider)
218  QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Min | QgsRasterBandStats::Max, myExtent, mySampleSize );
219  myMin = myRasterBandStats.minimumValue;
220  myMax = myRasterBandStats.maximumValue;
221  }
222  else if ( mStdDevRadioButton->isChecked() )
223  {
224  updateMinMax = true;
225  QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev, myExtent, mySampleSize );
226  double myStdDev = mStdDevSpinBox->value();
227  myMin = myRasterBandStats.mean - ( myStdDev * myRasterBandStats.stdDev );
228  myMax = myRasterBandStats.mean + ( myStdDev * myRasterBandStats.stdDev );
229  }
230 
231  if ( updateMinMax )
232  emit load( myBand, myMin, myMax );
233  }
234 }
235 
237 {
238  mStatisticsExtentCombo->removeItem( IDX_UPDATED_CANVAS );
239 }
virtual int bandCount() const =0
Get number of bands.
A rectangle specified with double values.
Definition: qgsrectangle.h:38
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
QgsRectangle outputExtentToLayerExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from output CRS to layer&#39;s CRS
double maximumValue
The maximum cell value in the raster band.
QgsRasterMinMaxOrigin minMaxOrigin()
Return a QgsRasterMinMaxOrigin object with the widget values.
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.
void setLimits(Limits limits)
Set limits.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:72
StatAccuracy statAccuracy() const
Return statistic accuracy.
Current extent of the canvas (at the time of computation) is used to compute statistics.
double cumulativeCutLower() const
Return lower bound of cumulative cut method (between 0 and 1).
void widgetChanged()
Emitted when something on the widget has changed.
double stdDev
The standard deviation of the cell values.
QgsRasterDataProvider * dataProvider() override
This class describes the origin of min/max values.
The RasterBandStats struct is a container for statistics about a single raster band.
double mean
The mean cell value for the band. NO_DATA values are excluded.
void setBands(const QList< int > &bands)
double cumulativeCutUpper() const
Return upper bound of cumulative cut method (between 0 and 1).
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
Constantly updated extent of the canvas is used to compute statistics.
Range is [ mean - stdDevFactor() * stddev, mean + stdDevFactor() * stddev ].
void hideUpdatedExtent()
Hide updated extent choice.
const int IDX_UPDATED_CANVAS
void setStdDevFactor(double val)
Set factor f so that the min/max range is [ mean - f * stddev , mean + f * stddev ]...
Range is [ min + cumulativeCutLower() * (max - min), min + cumulativeCutUpper() * (max - min) ]...
QgsRasterMinMaxWidget(QgsRasterLayer *layer, QWidget *parent=nullptr)
int sampleSize()
Return the selected sample size.
void setCumulativeCutLower(double val)
Set lower bound of cumulative cut method (between 0 and 1).
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Get band statistics.
void setExtent(Extent extent)
Set extent.
void userHasSetManualMinMaxValues()
Uncheck cumulative cut, min/max, std-dev radio buttons.
QgsRectangle extent()
Return the extent selected by the user.
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
Whole raster is used to compute statistics.
Extent extent() const
Return extent.
double minimumValue
The minimum cell value in the raster band.
void load(int bandNo, double min, double max)
signal emitted when new min/max values are computed from statistics.
const int IDX_CURRENT_CANVAS
void setStatAccuracy(StatAccuracy accuracy)
Set statistics accuracy.
QgsMapCanvas * mapCanvas()
Returns the map canvas associated with the widget.
void setCumulativeCutUpper(double val)
Set upper bound of cumulative cut method (between 0 and 1).
double stdDevFactor() const
Return factor f so that the min/max range is [ mean - f * stddev , mean + f * stddev ]...
Limits limits() const
Return limits.
void doComputations()
Load programmatically with current values.
const int IDX_WHOLE_RASTER
void setFromMinMaxOrigin(const QgsRasterMinMaxOrigin &)
Set the "source" of min/max values.