QGIS API Documentation 3.27.0-Master (a46f227e17)
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"
24#include "qgsrasterrenderer.h"
27#include "qgsdoublespinbox.h"
28
29const int IDX_WHOLE_RASTER = 0;
30const int IDX_CURRENT_CANVAS = 1;
31const 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
69void 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
95void 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;
166 break;
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}
@ MaximumValue
Reset value to maximum()
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:90
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.
virtual int bandCount() const =0
Gets number of bands.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
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