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