QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
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 "moc_qgsrasterminmaxwidget.cpp"
24#include "qgsmapcanvas.h"
27#include "qgsdoublespinbox.h"
28
30 : QWidget( parent )
31 , mLayer( layer )
32 , mLastRectangleValid( false )
33 , mBandsChanged( false )
34{
35 QgsDebugMsgLevel( QStringLiteral( "Entered." ), 4 );
36 setupUi( this );
37
38 mStatisticsExtentCombo->addItem( tr( "Whole Raster" ), QVariant::fromValue( Qgis::RasterRangeExtent::WholeRaster ) );
39 mStatisticsExtentCombo->addItem( tr( "Current Canvas" ), QVariant::fromValue( Qgis::RasterRangeExtent::FixedCanvas ) );
40 mStatisticsExtentCombo->addItem( tr( "Updated Canvas" ), QVariant::fromValue( Qgis::RasterRangeExtent::UpdatedCanvas ) );
41
42 cboAccuracy->addItem( tr( "Estimate (faster)" ), QVariant::fromValue( Qgis::RasterRangeAccuracy::Estimated ) );
43 cboAccuracy->addItem( tr( "Actual (slower)" ), QVariant::fromValue( Qgis::RasterRangeAccuracy::Exact ) );
44
45 // use maximum value as a clear value for the upper border of the cumulative cut
46 mCumulativeCutUpperDoubleSpinBox->setClearValueMode( QgsDoubleSpinBox::MaximumValue );
47
48 connect( mUserDefinedRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mUserDefinedRadioButton_toggled );
49 connect( mMinMaxRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mMinMaxRadioButton_toggled );
50 connect( mStdDevRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mStdDevRadioButton_toggled );
51 connect( mCumulativeCutRadioButton, &QRadioButton::toggled, this, &QgsRasterMinMaxWidget::mCumulativeCutRadioButton_toggled );
52 connect( mStatisticsExtentCombo, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMinMaxWidget::mStatisticsExtentCombo_currentIndexChanged );
53 connect( mCumulativeCutLowerDoubleSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMinMaxWidget::mCumulativeCutLowerDoubleSpinBox_valueChanged );
54 connect( mCumulativeCutUpperDoubleSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMinMaxWidget::mCumulativeCutUpperDoubleSpinBox_valueChanged );
55 connect( mStdDevSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMinMaxWidget::mStdDevSpinBox_valueChanged );
56 connect( cboAccuracy, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMinMaxWidget::cboAccuracy_currentIndexChanged );
57
58 const QgsRasterMinMaxOrigin defaultMinMaxOrigin;
59 setFromMinMaxOrigin( defaultMinMaxOrigin );
60}
61
63{
64 mCanvas = canvas;
65}
66
68{
69 return mCanvas;
70}
71
72void QgsRasterMinMaxWidget::setBands( const QList<int> &bands )
73{
74 mBandsChanged = bands != mBands;
75 mBands = bands;
76}
77
79{
80 const Qgis::RasterRangeExtent extentType = mStatisticsExtentCombo->currentData().value<Qgis::RasterRangeExtent>();
81 switch ( extentType )
82 {
84 return QgsRectangle();
85
88 break;
89 }
90
91 if ( mLayer && mCanvas )
92 return mCanvas->mapSettings().outputExtentToLayerExtent( mLayer, mCanvas->extent() );
93 else if ( mCanvas )
94 return mCanvas->extent();
95 else
96 return QgsRectangle();
97}
98
100{
101 mUserDefinedRadioButton->setChecked( true );
102 mStatisticsExtentCombo->setCurrentIndex( mStatisticsExtentCombo->findData( QVariant::fromValue( Qgis::RasterRangeExtent::WholeRaster ) ) );
103}
104
105void QgsRasterMinMaxWidget::mUserDefinedRadioButton_toggled( bool toggled )
106{
107 mStatisticsExtentCombo->setEnabled( !toggled );
108 cboAccuracy->setEnabled( !toggled );
109 emit widgetChanged();
110}
111
113{
114 switch ( minMaxOrigin.limits() )
115 {
117 mUserDefinedRadioButton->setChecked( true );
118 break;
119
121 mMinMaxRadioButton->setChecked( true );
122 break;
123
125 mStdDevRadioButton->setChecked( true );
126 break;
127
129 mCumulativeCutRadioButton->setChecked( true );
130 break;
131 }
132
133 mStatisticsExtentCombo->setCurrentIndex( mStatisticsExtentCombo->findData( QVariant::fromValue( minMaxOrigin.extent() ) ) );
134
135 mCumulativeCutLowerDoubleSpinBox->setValue( 100.0 * minMaxOrigin.cumulativeCutLower() );
136 mCumulativeCutUpperDoubleSpinBox->setValue( 100.0 * minMaxOrigin.cumulativeCutUpper() );
137 mStdDevSpinBox->setValue( minMaxOrigin.stdDevFactor() );
138
139 cboAccuracy->setCurrentIndex( cboAccuracy->findData( QVariant::fromValue( minMaxOrigin.statAccuracy() ) ) );
140}
141
143{
145
146 if ( mMinMaxRadioButton->isChecked() )
148 else if ( mStdDevRadioButton->isChecked() )
150 else if ( mCumulativeCutRadioButton->isChecked() )
152 else
154
155 minMaxOrigin.setExtent( mStatisticsExtentCombo->currentData().value<Qgis::RasterRangeExtent>() );
156 minMaxOrigin.setStatAccuracy( cboAccuracy->currentData().value<Qgis::RasterRangeAccuracy>() );
157
159 mCumulativeCutLowerDoubleSpinBox->value() / 100.0
160 );
162 mCumulativeCutUpperDoubleSpinBox->value() / 100.0
163 );
164 minMaxOrigin.setStdDevFactor( mStdDevSpinBox->value() );
165
166 return minMaxOrigin;
167}
168
170{
171 QgsDebugMsgLevel( QStringLiteral( "Entered." ), 4 );
172 if ( !mLayer->dataProvider() )
173 return;
174
175 const QgsRectangle myExtent = extent(); // empty == full
176 const int mySampleSize = sampleSize(); // 0 == exact
177
178 const QgsRasterMinMaxOrigin newMinMaxOrigin = minMaxOrigin();
179 if ( mLastRectangleValid && mLastRectangle == myExtent && mLastMinMaxOrigin == newMinMaxOrigin && !mBandsChanged )
180 {
181 QgsDebugMsgLevel( QStringLiteral( "Does not need to redo statistics computations" ), 2 );
182 return;
183 }
184
185 mLastRectangleValid = true;
186 mLastRectangle = myExtent;
187 mLastMinMaxOrigin = newMinMaxOrigin;
188 mBandsChanged = false;
189
190 for ( const int myBand : std::as_const( mBands ) )
191 {
192 QgsDebugMsgLevel( QStringLiteral( "myBand = %1" ).arg( myBand ), 2 );
193 if ( myBand < 1 || myBand > mLayer->dataProvider()->bandCount() )
194 {
195 continue;
196 }
197 double myMin = std::numeric_limits<double>::quiet_NaN();
198 double myMax = std::numeric_limits<double>::quiet_NaN();
199
200 bool updateMinMax = false;
201 if ( mCumulativeCutRadioButton->isChecked() )
202 {
203 updateMinMax = true;
204 const double myLower = mCumulativeCutLowerDoubleSpinBox->value() / 100.0;
205 const double myUpper = mCumulativeCutUpperDoubleSpinBox->value() / 100.0;
206 mLayer->dataProvider()->cumulativeCut( myBand, myLower, myUpper, myMin, myMax, myExtent, mySampleSize );
207 }
208 else if ( mMinMaxRadioButton->isChecked() )
209 {
210 updateMinMax = true;
211 // TODO: consider provider minimum/maximumValue() (has to be defined well in povider)
212 const QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, Qgis::RasterBandStatistic::Min | Qgis::RasterBandStatistic::Max, myExtent, mySampleSize );
213 myMin = myRasterBandStats.minimumValue;
214 myMax = myRasterBandStats.maximumValue;
215 }
216 else if ( mStdDevRadioButton->isChecked() )
217 {
218 updateMinMax = true;
219 const QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, Qgis::RasterBandStatistic::Mean | Qgis::RasterBandStatistic::StdDev, myExtent, mySampleSize );
220 const double myStdDev = mStdDevSpinBox->value();
221 myMin = myRasterBandStats.mean - ( myStdDev * myRasterBandStats.stdDev );
222 myMax = myRasterBandStats.mean + ( myStdDev * myRasterBandStats.stdDev );
223 }
224
225 if ( updateMinMax )
226 emit load( myBand, myMin, myMax );
227 }
228}
229
231{
232 mStatisticsExtentCombo->removeItem( mStatisticsExtentCombo->findData( QVariant::fromValue( Qgis::RasterRangeExtent::UpdatedCanvas ) ) );
233}
@ CumulativeCut
Range is [ min + cumulativeCutLower() * (max - min), min + cumulativeCutUpper() * (max - min) ].
@ StdDev
Range is [ mean - stdDevFactor() * stddev, mean + stdDevFactor() * stddev ].
@ MinimumMaximum
Real min-max values.
@ NotSet
User defined.
RasterRangeAccuracy
Describes the accuracy used to compute raster ranges (min/max values).
Definition qgis.h:1485
@ Exact
Exact statistics.
@ Estimated
Approximated statistics.
@ StdDev
Standard deviation.
RasterRangeExtent
Describes the extent used to compute raster ranges (min/max values).
Definition qgis.h:1470
@ UpdatedCanvas
Constantly updated extent of the canvas is used to compute statistics.
@ WholeRaster
Whole raster is used to compute statistics.
@ FixedCanvas
Current extent of the canvas (at the time of computation) is used to compute statistics.
@ MaximumValue
Reset value to maximum()
Map canvas is a class for displaying all GIS data types on a canvas.
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 setLimits(Qgis::RasterRangeLimit limits)
Sets the limits.
void setExtent(Qgis::RasterRangeExtent extent)
Sets the extent.
double cumulativeCutLower() const
Returns the lower bound of cumulative cut method (between 0 and 1).
Qgis::RasterRangeExtent extent() const
Returns the raster extent.
double stdDevFactor() const
Returns the factor f so that the min/max range is [ mean - f * stddev , mean + f * stddev ].
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).
Qgis::RasterRangeAccuracy statAccuracy() const
Returns the raster statistic accuracy.
Qgis::RasterRangeLimit limits() const
Returns the raster limits.
void setStatAccuracy(Qgis::RasterRangeAccuracy accuracy)
Sets the statistics accuracy.
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.
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39