QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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"
23#include "qgsmapcanvas.h"
26#include "qgsdoublespinbox.h"
27
28const int IDX_WHOLE_RASTER = 0;
29const int IDX_CURRENT_CANVAS = 1;
30const 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
41 // use maximum value as a clear value for the upper border of the cumulative cut
42 mCumulativeCutUpperDoubleSpinBox->setClearValueMode( QgsDoubleSpinBox::MaximumValue );
43
44 connect( mUserDefinedRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mUserDefinedRadioButton_toggled );
45 connect( mMinMaxRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mMinMaxRadioButton_toggled );
46 connect( mStdDevRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mStdDevRadioButton_toggled );
47 connect( mCumulativeCutRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mCumulativeCutRadioButton_toggled );
48 connect( mStatisticsExtentCombo, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMinMaxWidget::mStatisticsExtentCombo_currentIndexChanged );
49 connect( mCumulativeCutLowerDoubleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMinMaxWidget::mCumulativeCutLowerDoubleSpinBox_valueChanged );
50 connect( mCumulativeCutUpperDoubleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMinMaxWidget::mCumulativeCutUpperDoubleSpinBox_valueChanged );
51 connect( mStdDevSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMinMaxWidget::mStdDevSpinBox_valueChanged );
52 connect( cboAccuracy, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMinMaxWidget::cboAccuracy_currentIndexChanged );
53
54 const QgsRasterMinMaxOrigin defaultMinMaxOrigin;
55 setFromMinMaxOrigin( defaultMinMaxOrigin );
56}
57
59{
60 mCanvas = canvas;
61}
62
64{
65 return mCanvas;
66}
67
68void QgsRasterMinMaxWidget::setBands( const QList<int> &bands )
69{
70 mBandsChanged = bands != mBands;
71 mBands = bands;
72}
73
75{
76 const int nExtentIdx = mStatisticsExtentCombo->currentIndex();
77 if ( nExtentIdx != IDX_CURRENT_CANVAS && nExtentIdx != IDX_UPDATED_CANVAS )
78 return QgsRectangle();
79
80 if ( mLayer && mCanvas )
81 return mCanvas->mapSettings().outputExtentToLayerExtent( mLayer, mCanvas->extent() );
82 else if ( mCanvas )
83 return mCanvas->extent();
84 else
85 return QgsRectangle();
86}
87
89{
90 mUserDefinedRadioButton->setChecked( true );
91 mStatisticsExtentCombo->setCurrentIndex( IDX_WHOLE_RASTER );
92}
93
94void QgsRasterMinMaxWidget::mUserDefinedRadioButton_toggled( bool toggled )
95{
96 mStatisticsExtentCombo->setEnabled( !toggled );
97 cboAccuracy->setEnabled( !toggled );
98 emit widgetChanged();
99}
100
102{
103 switch ( minMaxOrigin.limits() )
104 {
106 mUserDefinedRadioButton->setChecked( true );
107 break;
108
110 mMinMaxRadioButton->setChecked( true );
111 break;
112
114 mStdDevRadioButton->setChecked( true );
115 break;
116
118 mCumulativeCutRadioButton->setChecked( true );
119 break;
120 }
121
122 switch ( minMaxOrigin.extent() )
123 {
125 mStatisticsExtentCombo->setCurrentIndex( IDX_WHOLE_RASTER );
126 break;
127
129 mStatisticsExtentCombo->setCurrentIndex( IDX_CURRENT_CANVAS );
130 break;
131
133 mStatisticsExtentCombo->setCurrentIndex( IDX_UPDATED_CANVAS );
134 break;
135 }
136
137 mCumulativeCutLowerDoubleSpinBox->setValue( 100.0 * minMaxOrigin.cumulativeCutLower() );
138 mCumulativeCutUpperDoubleSpinBox->setValue( 100.0 * minMaxOrigin.cumulativeCutUpper() );
139 mStdDevSpinBox->setValue( minMaxOrigin.stdDevFactor() );
140
141 cboAccuracy->setCurrentIndex( minMaxOrigin.statAccuracy() == QgsRasterMinMaxOrigin::Estimated ? 0 : 1 );
142}
143
145{
147
148 if ( mMinMaxRadioButton->isChecked() )
150 else if ( mStdDevRadioButton->isChecked() )
152 else if ( mCumulativeCutRadioButton->isChecked() )
154 else
156
157 switch ( mStatisticsExtentCombo->currentIndex() )
158 {
159 case IDX_WHOLE_RASTER:
160 default:
162 break;
165 break;
168 break;
169 }
170
171 if ( cboAccuracy->currentIndex() == 0 )
173 else
175
177 mCumulativeCutLowerDoubleSpinBox->value() / 100.0 );
179 mCumulativeCutUpperDoubleSpinBox->value() / 100.0 );
180 minMaxOrigin.setStdDevFactor( mStdDevSpinBox->value() );
181
182 return minMaxOrigin;
183}
184
186{
187 QgsDebugMsgLevel( QStringLiteral( "Entered." ), 4 );
188 if ( !mLayer->dataProvider() )
189 return;
190
191 const QgsRectangle myExtent = extent(); // empty == full
192 const int mySampleSize = sampleSize(); // 0 == exact
193
194 const QgsRasterMinMaxOrigin newMinMaxOrigin = minMaxOrigin();
195 if ( mLastRectangleValid && mLastRectangle == myExtent &&
196 mLastMinMaxOrigin == newMinMaxOrigin &&
197 !mBandsChanged )
198 {
199 QgsDebugMsgLevel( QStringLiteral( "Does not need to redo statistics computations" ), 2 );
200 return;
201 }
202
203 mLastRectangleValid = true;
204 mLastRectangle = myExtent;
205 mLastMinMaxOrigin = newMinMaxOrigin;
206 mBandsChanged = false;
207
208 for ( const int myBand : std::as_const( mBands ) )
209 {
210 QgsDebugMsgLevel( QStringLiteral( "myBand = %1" ).arg( myBand ), 2 );
211 if ( myBand < 1 || myBand > mLayer->dataProvider()->bandCount() )
212 {
213 continue;
214 }
215 double myMin = std::numeric_limits<double>::quiet_NaN();
216 double myMax = std::numeric_limits<double>::quiet_NaN();
217
218 bool updateMinMax = false;
219 if ( mCumulativeCutRadioButton->isChecked() )
220 {
221 updateMinMax = true;
222 const double myLower = mCumulativeCutLowerDoubleSpinBox->value() / 100.0;
223 const double myUpper = mCumulativeCutUpperDoubleSpinBox->value() / 100.0;
224 mLayer->dataProvider()->cumulativeCut( myBand, myLower, myUpper, myMin, myMax, myExtent, mySampleSize );
225 }
226 else if ( mMinMaxRadioButton->isChecked() )
227 {
228 updateMinMax = true;
229 // TODO: consider provider minimum/maximumValue() (has to be defined well in povider)
230 const QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, Qgis::RasterBandStatistic::Min | Qgis::RasterBandStatistic::Max, myExtent, mySampleSize );
231 myMin = myRasterBandStats.minimumValue;
232 myMax = myRasterBandStats.maximumValue;
233 }
234 else if ( mStdDevRadioButton->isChecked() )
235 {
236 updateMinMax = true;
237 const QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, Qgis::RasterBandStatistic::Mean | Qgis::RasterBandStatistic::StdDev, myExtent, mySampleSize );
238 const double myStdDev = mStdDevSpinBox->value();
239 myMin = myRasterBandStats.mean - ( myStdDev * myRasterBandStats.stdDev );
240 myMax = myRasterBandStats.mean + ( myStdDev * myRasterBandStats.stdDev );
241 }
242
243 if ( updateMinMax )
244 emit load( myBand, myMin, myMax );
245 }
246}
247
249{
250 mStatisticsExtentCombo->removeItem( IDX_UPDATED_CANVAS );
251}
@ StdDev
Standard deviation.
@ MaximumValue
Reset value to maximum()
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:93
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
QgsRectangle outputExtentToLayerExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from output CRS to layer's CRS
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.
double stdDev
The standard deviation of the cell values.
double minimumValue
The minimum cell value in the raster band.
double maximumValue
The maximum cell value in the raster band.
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.
Q_DECL_DEPRECATED QgsRasterBandStats bandStatistics(int bandNo, int stats, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
virtual int bandCount() const =0
Gets number of bands.
Represents a raster layer.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
This class describes the origin of min/max values.
void setExtent(QgsRasterMinMaxOrigin::Extent extent)
Sets the extent.
QgsRasterMinMaxOrigin::StatAccuracy statAccuracy() const
Returns the raster statistic accuracy.
double cumulativeCutLower() const
Returns the lower bound of cumulative cut method (between 0 and 1).
@ Exact
Exact statistics.
@ Estimated
Approximated statistics.
QgsRasterMinMaxOrigin::Limits limits() const
Returns the raster limits.
double stdDevFactor() const
Returns the factor f so that the min/max range is [ mean - f * stddev , mean + f * stddev ].
void setLimits(QgsRasterMinMaxOrigin::Limits limits)
Sets the limits.
void setStatAccuracy(QgsRasterMinMaxOrigin::StatAccuracy accuracy)
Sets the statistics accuracy.
@ UpdatedCanvas
Constantly updated extent of the canvas is used to compute statistics.
@ CurrentCanvas
Current extent of the canvas (at the time of computation) is used to compute statistics.
@ WholeRaster
Whole raster is used to compute statistics.
void setCumulativeCutUpper(double val)
Sets the upper bound of cumulative cut method (between 0 and 1).
void setStdDevFactor(double val)
Sets the factor f so that the min/max range is [ mean - f * stddev , mean + f * stddev ].
double cumulativeCutUpper() const
Returns the upper bound of cumulative cut method (between 0 and 1).
void setCumulativeCutLower(double val)
Sets the lower bound of cumulative cut method (between 0 and 1).
@ StdDev
Range is [ mean - stdDevFactor() * stddev, mean + stdDevFactor() * stddev ].
@ MinMax
Real min-max values.
@ CumulativeCut
Range is [ min + cumulativeCutLower() * (max - min), min + cumulativeCutUpper() * (max - min) ].
QgsRasterMinMaxOrigin::Extent extent() const
Returns the raster extent.
QgsRectangle extent()
Returns the extent selected by the user.
QgsRasterMinMaxWidget(QgsRasterLayer *layer, QWidget *parent=nullptr)
Constructor for QgsRasterMinMaxWidget.
void doComputations()
Load programmatically with current values.
QgsMapCanvas * mapCanvas()
Returns the map canvas associated with the widget.
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
void load(int bandNo, double min, double max)
signal emitted when new min/max values are computed from statistics.
void setFromMinMaxOrigin(const QgsRasterMinMaxOrigin &)
Sets the "source" of min/max values.
int sampleSize()
Returns the selected sample size.
void setBands(const QList< int > &bands)
void hideUpdatedExtent()
Hide updated extent choice.
QgsRasterMinMaxOrigin minMaxOrigin()
Returns a QgsRasterMinMaxOrigin object with the widget values.
void widgetChanged()
Emitted when something on the widget has changed.
void userHasSetManualMinMaxValues()
Uncheck cumulative cut, min/max, std-dev radio buttons.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
const int IDX_CURRENT_CANVAS
const int IDX_WHOLE_RASTER
const int IDX_UPDATED_CANVAS