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