QGIS API Documentation 3.99.0-Master (357b655ed83)
Loading...
Searching...
No Matches
qgssinglebandpseudocolorrendererwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssinglebandpseudocolorrendererwidget.cpp
3 ------------------------------------------
4 begin : February 2012
5 copyright : (C) 2012 by Marco Hugentobler
6 email : marco at sourcepole dot ch
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 "qgsdoublevalidator.h"
21#include "qgsguiutils.h"
22#include "qgsmapcanvas.h"
24#include "qgsrasterlayer.h"
26#include "qgsrastershader.h"
27#include "qgssettings.h"
29
30#include <QCursor>
31#include <QFileDialog>
32#include <QInputDialog>
33#include <QMenu>
34#include <QMessageBox>
35#include <QPushButton>
36#include <QString>
37#include <QTextStream>
38#include <QTreeView>
39
40#include "moc_qgssinglebandpseudocolorrendererwidget.cpp"
41
42using namespace Qt::StringLiterals;
43
45 : QgsRasterRendererWidget( layer, extent )
46{
47 const QgsSettings settings;
48
49 setupUi( this );
50
51 mColorRampShaderWidget->initializeForUseWithRasterLayer();
52
53 connect( mMinLineEdit, &QLineEdit::textChanged, this, &QgsSingleBandPseudoColorRendererWidget::mMinLineEdit_textChanged );
54 connect( mMaxLineEdit, &QLineEdit::textChanged, this, &QgsSingleBandPseudoColorRendererWidget::mMaxLineEdit_textChanged );
55 connect( mMinLineEdit, &QLineEdit::textEdited, this, &QgsSingleBandPseudoColorRendererWidget::mMinLineEdit_textEdited );
56 connect( mMaxLineEdit, &QLineEdit::textEdited, this, &QgsSingleBandPseudoColorRendererWidget::mMaxLineEdit_textEdited );
57
58 if ( !mRasterLayer )
59 {
60 return;
61 }
62
63 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
64 if ( !provider )
65 {
66 return;
67 }
68
69 // Must be before adding items to mBandComboBox (signal)
70 mMinLineEdit->setValidator( new QgsDoubleValidator( mMinLineEdit ) );
71 mMaxLineEdit->setValidator( new QgsDoubleValidator( mMaxLineEdit ) );
72
73 mMinMaxWidget = new QgsRasterMinMaxWidget( layer, this );
74 mMinMaxWidget->setExtent( extent );
75 mMinMaxWidget->setMapCanvas( mCanvas );
76
77 QHBoxLayout *layout = new QHBoxLayout();
78 layout->setContentsMargins( 0, 0, 0, 0 );
79 mMinMaxContainerWidget->setLayout( layout );
80 layout->addWidget( mMinMaxWidget );
81
82 mColorRampShaderWidget->setRasterDataProvider( provider );
83 mBandComboBox->setLayer( mRasterLayer );
84
85 setFromRenderer( layer->renderer() );
86
89
90 // If there is currently no min/max, load default with user current default options
91 if ( mMinLineEdit->text().isEmpty() || mMaxLineEdit->text().isEmpty() )
92 {
93 QgsRasterMinMaxOrigin minMaxOrigin = mMinMaxWidget->minMaxOrigin();
94 if ( minMaxOrigin.limits() == Qgis::RasterRangeLimit::NotSet )
95 {
97 mMinMaxWidget->setFromMinMaxOrigin( minMaxOrigin );
98 }
99 mMinMaxWidget->doComputations();
100 }
101
102 whileBlocking( mColorRampShaderWidget )->setMinimumMaximum( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
103
104 connect( mBandComboBox, &QgsRasterBandComboBox::bandChanged, this, &QgsSingleBandPseudoColorRendererWidget::bandChanged );
107}
108
110{
111 QgsRasterShader *rasterShader = new QgsRasterShader();
112
113 mColorRampShaderWidget->setMinimumMaximum( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
114 mColorRampShaderWidget->setExtent( mMinMaxWidget->extent() );
115
116 QgsColorRampShader *fcn = new QgsColorRampShader( mColorRampShaderWidget->shader() );
117 rasterShader->setRasterShaderFunction( fcn );
118
119 const int bandNumber = mBandComboBox->currentBand();
120 QgsSingleBandPseudoColorRenderer *renderer = new QgsSingleBandPseudoColorRenderer( mRasterLayer->dataProvider(), bandNumber, rasterShader );
121 renderer->setClassificationMin( lineEditValue( mMinLineEdit ) );
122 renderer->setClassificationMax( lineEditValue( mMaxLineEdit ) );
123 renderer->setMinMaxOrigin( mMinMaxWidget->minMaxOrigin() );
124 return renderer;
125}
126
128{
129 mMinMaxWidget->doComputations();
130}
131
133
135{
137 mMinMaxWidget->setMapCanvas( canvas );
138 mColorRampShaderWidget->setExtent( mMinMaxWidget->extent() );
139}
140
142{
143 const QgsSingleBandPseudoColorRenderer *pr = dynamic_cast<const QgsSingleBandPseudoColorRenderer *>( r );
144 if ( pr )
145 {
146 mBandComboBox->setBand( pr->inputBand() );
147 mMinMaxWidget->setBands( QList<int>() << pr->inputBand() );
148 mColorRampShaderWidget->setRasterBand( pr->inputBand() );
149
150 // need to set min/max properties here because if we use the raster shader below,
151 // we may set a new color ramp which needs to have min/max values defined.
152 setLineEditValue( mMinLineEdit, pr->classificationMin() );
153 setLineEditValue( mMaxLineEdit, pr->classificationMax() );
154 mMinMaxWidget->setFromMinMaxOrigin( pr->minMaxOrigin() );
155
156 const QgsRasterShader *rasterShader = pr->shader();
157 if ( rasterShader )
158 {
159 const QgsColorRampShader *colorRampShader = dynamic_cast<const QgsColorRampShader *>( rasterShader->rasterShaderFunction() );
160 if ( colorRampShader )
161 {
162 mColorRampShaderWidget->setFromShader( *colorRampShader );
163 }
164 }
165 }
166 else
167 {
168 mMinMaxWidget->setBands( QList<int>() << mBandComboBox->currentBand() );
169 mColorRampShaderWidget->setRasterBand( mBandComboBox->currentBand() );
170 }
171}
172
173void QgsSingleBandPseudoColorRendererWidget::bandChanged()
174{
175 QList<int> bands;
176 bands.append( mBandComboBox->currentBand() );
177 mMinMaxWidget->setBands( bands );
178 mColorRampShaderWidget->setRasterBand( mBandComboBox->currentBand() );
179 mColorRampShaderWidget->classify();
180}
181
183{
184 QgsDebugMsgLevel( u"theBandNo = %1 min = %2 max = %3"_s.arg( bandNo ).arg( min ).arg( max ), 2 );
185
186 const QString oldMinTextvalue = mMinLineEdit->text();
187 const QString oldMaxTextvalue = mMaxLineEdit->text();
188
189 if ( std::isnan( min ) )
190 {
191 whileBlocking( mMinLineEdit )->clear();
192 }
193 else
194 {
195 whileBlocking( mMinLineEdit )->setText( displayValueWithMaxPrecision( min ) );
196 }
197
198 if ( std::isnan( max ) )
199 {
200 whileBlocking( mMaxLineEdit )->clear();
201 }
202 else
203 {
204 whileBlocking( mMaxLineEdit )->setText( displayValueWithMaxPrecision( max ) );
205 }
206
207 // We compare old min and new min as text because QString::number keeps a fixed number of significant
208 // digits (default 6) and so loaded min/max will always differ from current one, which triggers a
209 // classification, and wipe out every user modification (see https://github.com/qgis/QGIS/issues/36172)
210 if ( mMinLineEdit->text() != oldMinTextvalue || mMaxLineEdit->text() != oldMaxTextvalue )
211 {
212 whileBlocking( mColorRampShaderWidget )->setRasterBand( bandNo );
213 whileBlocking( mColorRampShaderWidget )->setMinimumMaximumAndClassify( min, max );
214 }
215}
216
217
219{
220 whileBlocking( mMinLineEdit )->setText( displayValueWithMaxPrecision( min ) );
221 whileBlocking( mMaxLineEdit )->setText( displayValueWithMaxPrecision( max ) );
222 minMaxModified();
223}
224
225
226void QgsSingleBandPseudoColorRendererWidget::setLineEditValue( QLineEdit *lineEdit, double value )
227{
228 QString s;
229 if ( !std::isnan( value ) )
230 {
231 s = displayValueWithMaxPrecision( value );
232 }
233 lineEdit->setText( s );
234}
235
236double QgsSingleBandPseudoColorRendererWidget::lineEditValue( const QLineEdit *lineEdit ) const
237{
238 if ( lineEdit->text().isEmpty() )
239 {
240 return std::numeric_limits<double>::quiet_NaN();
241 }
242
243 return QgsDoubleValidator::toDouble( lineEdit->text() );
244}
245
246void QgsSingleBandPseudoColorRendererWidget::mMinLineEdit_textEdited( const QString & )
247{
248 minMaxModified();
249 whileBlocking( mColorRampShaderWidget )->setMinimumMaximumAndClassify( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
250 emit widgetChanged();
251}
252
253void QgsSingleBandPseudoColorRendererWidget::mMaxLineEdit_textEdited( const QString & )
254{
255 minMaxModified();
256 whileBlocking( mColorRampShaderWidget )->setMinimumMaximumAndClassify( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
257 emit widgetChanged();
258}
259
260void QgsSingleBandPseudoColorRendererWidget::mMinLineEdit_textChanged( const QString & )
261{
262 whileBlocking( mColorRampShaderWidget )->setMinimumMaximum( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
263 emit widgetChanged();
264}
265
266void QgsSingleBandPseudoColorRendererWidget::mMaxLineEdit_textChanged( const QString & )
267{
268 whileBlocking( mColorRampShaderWidget )->setMinimumMaximum( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
269 emit widgetChanged();
270}
271
272
273void QgsSingleBandPseudoColorRendererWidget::minMaxModified()
274{
275 mMinMaxWidget->userHasSetManualMinMaxValues();
276}
277
278QString QgsSingleBandPseudoColorRendererWidget::displayValueWithMaxPrecision( const double value )
279{
280 if ( mRasterLayer->dataProvider() )
281 {
282 return QgsGuiUtils::displayValueWithMaximumDecimals( mRasterLayer->dataProvider()->dataType( mBandComboBox->currentBand() ), value );
283 }
284 else
285 {
286 // Use QLocale default
287 return QLocale().toString( value, 'g' );
288 }
289}
290
291void QgsSingleBandPseudoColorRendererWidget::setMin( const QString &value, int )
292{
293 mMinLineEdit->setText( value );
294 minMaxModified();
295 mColorRampShaderWidget->classify();
296}
297
298void QgsSingleBandPseudoColorRendererWidget::setMax( const QString &value, int )
299{
300 mMaxLineEdit->setText( value );
301 minMaxModified();
302 mColorRampShaderWidget->classify();
303}
@ MinimumMaximum
Real min-max values.
Definition qgis.h:1604
@ NotSet
User defined.
Definition qgis.h:1603
void minimumMaximumChangedFromTree(double minimum, double maximum)
Color ramp tree has changed.
void widgetChanged()
Widget changed.
A ramp shader will color a raster pixel based on a list of values ranges in a ramp.
A custom validator which allows entry of doubles in a locale-tolerant way.
static double toDouble(const QString &input, bool *ok)
Converts input string to double value.
Map canvas is a class for displaying all GIS data types on a canvas.
void bandChanged(int band)
Emitted when the currently selected band changes.
Base class for raster data providers.
Represents a raster layer.
QgsRasterRenderer * renderer() const
Returns the raster's renderer.
Describes the origin of minimum and maximum values in a raster.
void setLimits(Qgis::RasterRangeLimit limits)
Sets the limits.
Qgis::RasterRangeLimit limits() const
Returns the raster limits.
A widget for configuring how the minimum and maximum value of a raster layer is determined.
void load(int bandNo, double min, double max)
signal emitted when new min/max values are computed from statistics.
void setBands(const QList< int > &bands)
void widgetChanged()
Emitted when something on the widget has changed.
virtual void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
QgsMapCanvas * mCanvas
Associated map canvas.
QgsRasterRendererWidget(QgsRasterLayer *layer, const QgsRectangle &extent)
Constructor for QgsRasterRendererWidget.
void widgetChanged()
Emitted when something on the widget has changed.
Raster renderer pipe that applies colors to a raster.
const QgsRasterMinMaxOrigin & minMaxOrigin() const
Returns const reference to origin of min/max values.
Interface for all raster shaders.
void setRasterShaderFunction(QgsRasterShaderFunction *function)
A public method that allows the user to set their own shader function.
QgsRasterShaderFunction * rasterShaderFunction()
A rectangle specified with double values.
Stores settings for use within QGIS.
Definition qgssettings.h:68
void setMax(const QString &value, int index=0) override
QgsSingleBandPseudoColorRendererWidget(QgsRasterLayer *layer, const QgsRectangle &extent=QgsRectangle())
Constructor for QgsSingleBandPseudoColorRendererWidget.
void doComputations() override
Load programmatically with current values.
QgsRasterMinMaxWidget * minMaxWidget() override
Returns min/max widget when it exists.
void setMin(const QString &value, int index=0) override
void setMapCanvas(QgsMapCanvas *canvas) override
Sets the map canvas associated with the widget.
QgsRasterRenderer * renderer() override
Creates a new renderer, using the properties defined in the widget.
void setFromRenderer(const QgsRasterRenderer *r)
Sets the widget state from the specified renderer.
void loadMinMax(int bandNo, double min, double max)
called when new min/max values are loaded
void loadMinMaxFromTree(double min, double max)
called when the color ramp tree has changed
Raster renderer pipe for single band pseudocolor.
QgsRasterShader * shader()
Returns the raster shader.
int inputBand() const override
Returns the input band for the renderer, or -1 if no input band is available.
QString displayValueWithMaximumDecimals(const Qgis::DataType dataType, const double value, bool displayTrailingZeroes)
Returns a localized string representation of the value with the appropriate number of decimals suppor...
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6839
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:63