QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
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 "qgstreewidgetitem.h"
25 #include "qgssettings.h"
26 #include "qgsmapcanvas.h"
27 
28 // for color ramps - todo add rasterStyle and refactor raster vs. vector ramps
29 #include "qgsstyle.h"
30 #include "qgscolorramp.h"
31 #include "qgscolorrampbutton.h"
32 #include "qgscolordialog.h"
33 
34 #include <QCursor>
35 #include <QPushButton>
36 #include <QInputDialog>
37 #include <QFileDialog>
38 #include <QMenu>
39 #include <QMessageBox>
40 #include <QTextStream>
41 #include <QTreeView>
42 
44  : QgsRasterRendererWidget( layer, extent )
45  , mMinMaxOrigin( 0 )
46 {
47  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 
64  if ( !provider )
65  {
66  return;
67  }
68 
69  // Must be before adding items to mBandComboBox (signal)
70  mMinLineEdit->setValidator( new QDoubleValidator( mMinLineEdit ) );
71  mMaxLineEdit->setValidator( new QDoubleValidator( 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() == QgsRasterMinMaxOrigin::None )
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  int bandNumber = mBandComboBox->currentBand();
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 {
136  return mBandComboBox->currentBand();
137 }
138 
140 {
142  mMinMaxWidget->setMapCanvas( canvas );
143  mColorRampShaderWidget->setExtent( mMinMaxWidget->extent() );
144 }
145 
147 {
148  const QgsSingleBandPseudoColorRenderer *pr = dynamic_cast<const QgsSingleBandPseudoColorRenderer *>( r );
149  if ( pr )
150  {
151  mBandComboBox->setBand( pr->band() );
152  mMinMaxWidget->setBands( QList< int >() << pr->band() );
153  mColorRampShaderWidget->setRasterBand( pr->band() );
154 
155  const QgsRasterShader *rasterShader = pr->shader();
156  if ( rasterShader )
157  {
158  const QgsColorRampShader *colorRampShader = dynamic_cast<const QgsColorRampShader *>( rasterShader->rasterShaderFunction() );
159  if ( colorRampShader )
160  {
161  mColorRampShaderWidget->setFromShader( *colorRampShader );
162  }
163  }
164  setLineEditValue( mMinLineEdit, pr->classificationMin() );
165  setLineEditValue( mMaxLineEdit, pr->classificationMax() );
166 
167  mMinMaxWidget->setFromMinMaxOrigin( pr->minMaxOrigin() );
168  }
169  else
170  {
171  mMinMaxWidget->setBands( QList< int >() << mBandComboBox->currentBand() );
172  }
173 }
174 
175 void QgsSingleBandPseudoColorRendererWidget::bandChanged()
176 {
177  QList<int> bands;
178  bands.append( mBandComboBox->currentBand() );
179  mMinMaxWidget->setBands( bands );
180  mColorRampShaderWidget->setRasterBand( mBandComboBox->currentBand() );
181  mColorRampShaderWidget->classify();
182 }
183 
185 {
186  Q_UNUSED( bandNo )
187  QgsDebugMsg( QStringLiteral( "theBandNo = %1 min = %2 max = %3" ).arg( bandNo ).arg( min ).arg( max ) );
188 
189  double oldMin = lineEditValue( mMinLineEdit );
190  double oldMax = lineEditValue( mMaxLineEdit );
191 
192  if ( std::isnan( min ) )
193  {
194  whileBlocking( mMinLineEdit )->clear();
195  }
196  else
197  {
198  whileBlocking( mMinLineEdit )->setText( QString::number( min ) );
199  }
200 
201  if ( std::isnan( max ) )
202  {
203  whileBlocking( mMaxLineEdit )->clear();
204  }
205  else
206  {
207  whileBlocking( mMaxLineEdit )->setText( QString::number( max ) );
208  }
209 
210  if ( !qgsDoubleNear( oldMin, min ) || !qgsDoubleNear( oldMax, max ) )
211  {
212  whileBlocking( mColorRampShaderWidget )->setRasterBand( bandNo );
213  whileBlocking( mColorRampShaderWidget )->setMinimumMaximumAndClassify( min, max );
214  }
215 }
216 
217 
219 {
220  whileBlocking( mMinLineEdit )->setText( QString::number( min ) );
221  whileBlocking( mMaxLineEdit )->setText( QString::number( max ) );
222  minMaxModified();
223 }
224 
225 
226 void QgsSingleBandPseudoColorRendererWidget::setLineEditValue( QLineEdit *lineEdit, double value )
227 {
228  QString s;
229  if ( !std::isnan( value ) )
230  {
231  s = QString::number( value );
232  }
233  lineEdit->setText( s );
234 }
235 
236 double 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 lineEdit->text().toDouble();
244 }
245 
246 void QgsSingleBandPseudoColorRendererWidget::mMinLineEdit_textEdited( const QString & )
247 {
248  minMaxModified();
249  whileBlocking( mColorRampShaderWidget )->setMinimumMaximumAndClassify( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
250  emit widgetChanged();
251 }
252 
253 void QgsSingleBandPseudoColorRendererWidget::mMaxLineEdit_textEdited( const QString & )
254 {
255  minMaxModified();
256  whileBlocking( mColorRampShaderWidget )->setMinimumMaximumAndClassify( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
257  emit widgetChanged();
258 }
259 
260 void QgsSingleBandPseudoColorRendererWidget::mMinLineEdit_textChanged( const QString & )
261 {
262  whileBlocking( mColorRampShaderWidget )->setMinimumMaximum( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
263  emit widgetChanged();
264 }
265 
266 void QgsSingleBandPseudoColorRendererWidget::mMaxLineEdit_textChanged( const QString & )
267 {
268  whileBlocking( mColorRampShaderWidget )->setMinimumMaximum( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
269  emit widgetChanged();
270 }
271 
272 
273 void QgsSingleBandPseudoColorRendererWidget::minMaxModified()
274 {
275  mMinMaxWidget->userHasSetManualMinMaxValues();
276 }
void loadMinMaxFromTree(double min, double max)
called when the color ramp tree has changed
QgsRasterMinMaxOrigin::Limits limits() const
Returns the raster limits.
void setExtent(const QgsRectangle &extent)
Sets the extent to use for minimum and maximum value calculation.
A rectangle specified with double values.
Definition: qgsrectangle.h:41
Interface for all raster shaders.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
A ramp shader will color a raster pixel based on a list of values ranges in a ramp.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:280
void widgetChanged()
Widget changed.
QgsRasterMinMaxWidget * minMaxWidget() override
Returns min/max widget when it exists.
QgsRasterMinMaxOrigin minMaxOrigin()
Returns a QgsRasterMinMaxOrigin object with the widget values.
const QgsRasterMinMaxOrigin & minMaxOrigin() const
Returns const reference to origin of min/max values.
QgsRasterRenderer * renderer() const
Returns the raster&#39;s renderer.
QgsRasterShader * shader()
Returns the raster shader.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:75
virtual void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
void setMapCanvas(QgsMapCanvas *canvas) override
Sets the map canvas associated with the widget.
void widgetChanged()
Emitted when something on the widget has changed.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
This class describes the origin of min/max values.
virtual QString min(int index=0)
void bandChanged(int band)
Emitted when the currently selected band changes.
QgsRasterShaderFunction * rasterShaderFunction()
void setBands(const QList< int > &bands)
Raster renderer pipe for single band pseudocolor.
void setRasterShaderFunction(QgsRasterShaderFunction *function)
A public method that allows the user to set their own shader function.
void doComputations() override
Load programmatically with current values.
void setMinMaxOrigin(const QgsRasterMinMaxOrigin &origin)
Sets origin of min/max values.
void setLimits(QgsRasterMinMaxOrigin::Limits limits)
Sets the limits.
void userHasSetManualMinMaxValues()
Uncheck cumulative cut, min/max, std-dev radio buttons.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:227
QgsRectangle extent()
Returns the extent selected by the user.
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
QgsSingleBandPseudoColorRendererWidget(QgsRasterLayer *layer, const QgsRectangle &extent=QgsRectangle())
Creates new raster renderer widget.
void setBand(int bandNo)
Sets the band used by the renderer.
void load(int bandNo, double min, double max)
signal emitted when new min/max values are computed from statistics.
virtual QString max(int index=0)
int currentBand() const
Returns the current raster band number.
QgsMapCanvas * mCanvas
Associated map canvas.
void widgetChanged()
Emitted when something on the widget has changed.
void setFromRenderer(const QgsRasterRenderer *r)
Set state of the widget from renderer settings.
Raster renderer pipe that applies colors to a raster.
void doComputations()
Load programmatically with current values.
int band() const
Returns the band used by the renderer.
void loadMinMax(int bandNo, double min, double max)
called when new min/max values are loaded
void minimumMaximumChangedFromTree(double minimum, double maximum)
Color ramp tree has changed.
Base class for raster data providers.
void setFromMinMaxOrigin(const QgsRasterMinMaxOrigin &)
Sets the "source" of min/max values.