QGIS API Documentation 4.3.0-Master (3b7b3208a79)
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
136
138{
140 mMinMaxWidget->setMapCanvas( canvas );
141 mColorRampShaderWidget->setExtent( mMinMaxWidget->extent() );
142}
143
145{
146 bool hasSetColorRampShader = false;
147 if ( const QgsSingleBandPseudoColorRenderer *pr = dynamic_cast<const QgsSingleBandPseudoColorRenderer *>( r ) )
148 {
149 mBandComboBox->setBand( pr->inputBand() );
150 mMinMaxWidget->setBands( QList<int>() << pr->inputBand() );
151 mColorRampShaderWidget->setRasterBand( pr->inputBand() );
152
153 // need to set min/max properties here because if we use the raster shader below,
154 // we may set a new color ramp which needs to have min/max values defined.
155 setLineEditValue( mMinLineEdit, pr->classificationMin() );
156 setLineEditValue( mMaxLineEdit, pr->classificationMax() );
157 mMinMaxWidget->setFromMinMaxOrigin( pr->minMaxOrigin() );
158
159 if ( const QgsRasterShader *rasterShader = pr->shader() )
160 {
161 if ( const auto *colorRampShader = dynamic_cast<const QgsColorRampShader *>( rasterShader->rasterShaderFunction() ) )
162 {
163 mColorRampShaderWidget->setFromShader( *colorRampShader );
164 hasSetColorRampShader = true;
165 }
166 }
167 }
168 else
169 {
170 mMinMaxWidget->setBands( QList<int>() << mBandComboBox->currentBand() );
171 mColorRampShaderWidget->setRasterBand( mBandComboBox->currentBand() );
172 }
173
174 if ( !hasSetColorRampShader )
175 {
176 // set a default color ramp shader for the widget, so that the widget is nicely populated with a
177 // usable state to begin with
178 mColorRampShaderWidget->setFromShader( QgsColorRampShader() );
179 }
180}
181
182void QgsSingleBandPseudoColorRendererWidget::bandChanged()
183{
184 QList<int> bands;
185 bands.append( mBandComboBox->currentBand() );
186 mMinMaxWidget->setBands( bands );
187 mColorRampShaderWidget->setRasterBand( mBandComboBox->currentBand() );
188 mColorRampShaderWidget->classify();
189}
190
192{
193 QgsDebugMsgLevel( u"theBandNo = %1 min = %2 max = %3"_s.arg( bandNo ).arg( min ).arg( max ), 2 );
194
195 const QString oldMinTextvalue = mMinLineEdit->text();
196 const QString oldMaxTextvalue = mMaxLineEdit->text();
197
198 if ( std::isnan( min ) )
199 {
200 whileBlocking( mMinLineEdit )->clear();
201 }
202 else
203 {
204 whileBlocking( mMinLineEdit )->setText( displayValueWithMaxPrecision( min ) );
205 }
206
207 if ( std::isnan( max ) )
208 {
209 whileBlocking( mMaxLineEdit )->clear();
210 }
211 else
212 {
213 whileBlocking( mMaxLineEdit )->setText( displayValueWithMaxPrecision( max ) );
214 }
215
216 // We compare old min and new min as text because QString::number keeps a fixed number of significant
217 // digits (default 6) and so loaded min/max will always differ from current one, which triggers a
218 // classification, and wipe out every user modification (see https://github.com/qgis/QGIS/issues/36172)
219 if ( mMinLineEdit->text() != oldMinTextvalue || mMaxLineEdit->text() != oldMaxTextvalue )
220 {
221 whileBlocking( mColorRampShaderWidget )->setRasterBand( bandNo );
222 whileBlocking( mColorRampShaderWidget )->setMinimumMaximumAndClassify( min, max );
223 }
224}
225
226
228{
229 whileBlocking( mMinLineEdit )->setText( displayValueWithMaxPrecision( min ) );
230 whileBlocking( mMaxLineEdit )->setText( displayValueWithMaxPrecision( max ) );
231 minMaxModified();
232}
233
234
235void QgsSingleBandPseudoColorRendererWidget::setLineEditValue( QLineEdit *lineEdit, double value )
236{
237 QString s;
238 if ( !std::isnan( value ) )
239 {
240 s = displayValueWithMaxPrecision( value );
241 }
242 lineEdit->setText( s );
243}
244
245double QgsSingleBandPseudoColorRendererWidget::lineEditValue( const QLineEdit *lineEdit ) const
246{
247 if ( lineEdit->text().isEmpty() )
248 {
249 return std::numeric_limits<double>::quiet_NaN();
250 }
251
252 return QgsDoubleValidator::toDouble( lineEdit->text() );
253}
254
255void QgsSingleBandPseudoColorRendererWidget::mMinLineEdit_textEdited( const QString & )
256{
257 minMaxModified();
258 whileBlocking( mColorRampShaderWidget )->setMinimumMaximumAndClassify( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
259 emit widgetChanged();
260}
261
262void QgsSingleBandPseudoColorRendererWidget::mMaxLineEdit_textEdited( const QString & )
263{
264 minMaxModified();
265 whileBlocking( mColorRampShaderWidget )->setMinimumMaximumAndClassify( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
266 emit widgetChanged();
267}
268
269void QgsSingleBandPseudoColorRendererWidget::mMinLineEdit_textChanged( const QString & )
270{
271 whileBlocking( mColorRampShaderWidget )->setMinimumMaximum( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
272 emit widgetChanged();
273}
274
275void QgsSingleBandPseudoColorRendererWidget::mMaxLineEdit_textChanged( const QString & )
276{
277 whileBlocking( mColorRampShaderWidget )->setMinimumMaximum( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
278 emit widgetChanged();
279}
280
281
282void QgsSingleBandPseudoColorRendererWidget::minMaxModified()
283{
284 mMinMaxWidget->userHasSetManualMinMaxValues();
285}
286
287QString QgsSingleBandPseudoColorRendererWidget::displayValueWithMaxPrecision( const double value )
288{
289 if ( mRasterLayer->dataProvider() )
290 {
291 return QgsGuiUtils::displayValueWithMaximumDecimals( mRasterLayer->dataProvider()->dataType( mBandComboBox->currentBand() ), value );
292 }
293 else
294 {
295 // Use QLocale default
296 return QLocale().toString( value, 'g' );
297 }
298}
299
300void QgsSingleBandPseudoColorRendererWidget::setMin( const QString &value, int )
301{
302 mMinLineEdit->setText( value );
303 minMaxModified();
304 mColorRampShaderWidget->classify();
305}
306
307void QgsSingleBandPseudoColorRendererWidget::setMax( const QString &value, int )
308{
309 mMaxLineEdit->setText( value );
310 minMaxModified();
311 mColorRampShaderWidget->classify();
312}
@ MinimumMaximum
Real min-max values.
Definition qgis.h:1716
@ NotSet
User defined.
Definition qgis.h:1715
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.
Interface for all raster shaders.
void setRasterShaderFunction(QgsRasterShaderFunction *function)
A public method that allows the user to set their own shader function.
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.
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:7619
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:80