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