QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
qgsmultibandcolorrendererwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmultibandcolorrendererwidget.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 "qgsrasterminmaxwidget.h"
23 #include "qgsdoublevalidator.h"
24 
26  : QgsRasterRendererWidget( layer, extent )
27  , mDisableMinMaxWidgetRefresh( false )
28 {
29  setupUi( this );
30  connect( mRedMinLineEdit, &QLineEdit::textChanged, this, &QgsMultiBandColorRendererWidget::mRedMinLineEdit_textChanged );
31  connect( mRedMaxLineEdit, &QLineEdit::textChanged, this, &QgsMultiBandColorRendererWidget::mRedMaxLineEdit_textChanged );
32  connect( mGreenMinLineEdit, &QLineEdit::textChanged, this, &QgsMultiBandColorRendererWidget::mGreenMinLineEdit_textChanged );
33  connect( mGreenMaxLineEdit, &QLineEdit::textChanged, this, &QgsMultiBandColorRendererWidget::mGreenMaxLineEdit_textChanged );
34  connect( mBlueMinLineEdit, &QLineEdit::textChanged, this, &QgsMultiBandColorRendererWidget::mBlueMinLineEdit_textChanged );
35  connect( mBlueMaxLineEdit, &QLineEdit::textChanged, this, &QgsMultiBandColorRendererWidget::mBlueMaxLineEdit_textChanged );
36  createValidators();
37 
38  if ( mRasterLayer )
39  {
41  if ( !provider )
42  {
43  return;
44  }
45 
46  mMinMaxWidget = new QgsRasterMinMaxWidget( layer, this );
47  mMinMaxWidget->setExtent( extent );
48  mMinMaxWidget->setMapCanvas( mCanvas );
49  QHBoxLayout *layout = new QHBoxLayout();
50  layout->setContentsMargins( 0, 0, 0, 0 );
51  mMinMaxContainerWidget->setLayout( layout );
52  layout->addWidget( mMinMaxWidget );
53 
54  connect( mMinMaxWidget, &QgsRasterMinMaxWidget::widgetChanged,
56  connect( mMinMaxWidget, &QgsRasterMinMaxWidget::load,
58 
59  connect( mRedBandComboBox, &QgsRasterBandComboBox::bandChanged,
60  this, &QgsMultiBandColorRendererWidget::onBandChanged );
61  connect( mGreenBandComboBox, &QgsRasterBandComboBox::bandChanged,
62  this, &QgsMultiBandColorRendererWidget::onBandChanged );
63  connect( mBlueBandComboBox, &QgsRasterBandComboBox::bandChanged,
64  this, &QgsMultiBandColorRendererWidget::onBandChanged );
65 
66  mRedBandComboBox->setShowNotSetOption( true );
67  mGreenBandComboBox->setShowNotSetOption( true );
68  mBlueBandComboBox->setShowNotSetOption( true );
69  mRedBandComboBox->setLayer( mRasterLayer );
70  mGreenBandComboBox->setLayer( mRasterLayer );
71  mBlueBandComboBox->setLayer( mRasterLayer );
72 
73  //contrast enhancement algorithms
74  mContrastEnhancementAlgorithmComboBox->addItem( tr( "No Enhancement" ), QgsContrastEnhancement::NoEnhancement );
75  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Stretch to MinMax" ), QgsContrastEnhancement::StretchToMinimumMaximum );
76  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Stretch and Clip to MinMax" ), QgsContrastEnhancement::StretchAndClipToMinimumMaximum );
77  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Clip to MinMax" ), QgsContrastEnhancement::ClipToMinimumMaximum );
78 
80  onBandChanged( 0 ); // reset mMinMaxWidget bands
81 
82  connect( mContrastEnhancementAlgorithmComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterRendererWidget::widgetChanged );
83  }
84 }
85 
87 {
88  if ( !mRasterLayer )
89  {
90  return nullptr;
91  }
93  if ( !provider )
94  {
95  return nullptr;
96  }
97 
98  const int redBand = mRedBandComboBox->currentBand();
99  const int greenBand = mGreenBandComboBox->currentBand();
100  const int blueBand = mBlueBandComboBox->currentBand();
101 
102  QgsMultiBandColorRenderer *r = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand );
103  setCustomMinMaxValues( r, provider, redBand, greenBand, blueBand );
104 
105  r->setMinMaxOrigin( mMinMaxWidget->minMaxOrigin() );
106 
107  return r;
108 }
109 
111 {
112  mMinMaxWidget->doComputations();
113 }
114 
116 {
118  mMinMaxWidget->setMapCanvas( canvas );
119 }
120 
121 void QgsMultiBandColorRendererWidget::createValidators()
122 {
123  mRedMinLineEdit->setValidator( new QgsDoubleValidator( mRedMinLineEdit ) );
124  mRedMaxLineEdit->setValidator( new QgsDoubleValidator( mRedMinLineEdit ) );
125  mGreenMinLineEdit->setValidator( new QgsDoubleValidator( mGreenMinLineEdit ) );
126  mGreenMaxLineEdit->setValidator( new QgsDoubleValidator( mGreenMinLineEdit ) );
127  mBlueMinLineEdit->setValidator( new QgsDoubleValidator( mBlueMinLineEdit ) );
128  mBlueMaxLineEdit->setValidator( new QgsDoubleValidator( mBlueMinLineEdit ) );
129 }
130 
131 void QgsMultiBandColorRendererWidget::setCustomMinMaxValues( QgsMultiBandColorRenderer *r,
132  const QgsRasterDataProvider *provider,
133  int redBand, int greenBand, int blueBand )
134 {
135  if ( !r || !provider )
136  {
137  return;
138  }
139 
140  if ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ==
142  {
143  r->setRedContrastEnhancement( nullptr );
144  r->setGreenContrastEnhancement( nullptr );
145  r->setBlueContrastEnhancement( nullptr );
146  return;
147  }
148 
149  QgsContrastEnhancement *redEnhancement = nullptr;
150  QgsContrastEnhancement *greenEnhancement = nullptr;
151  QgsContrastEnhancement *blueEnhancement = nullptr;
152 
153  bool redMinOk, redMaxOk;
154  const double redMin = QgsDoubleValidator::toDouble( mRedMinLineEdit->text(), &redMinOk );
155  const double redMax = QgsDoubleValidator::toDouble( mRedMaxLineEdit->text(), &redMaxOk );
156  if ( redMinOk && redMaxOk && redBand != -1 )
157  {
158  redEnhancement = new QgsContrastEnhancement( ( Qgis::DataType )(
159  provider->dataType( redBand ) ) );
160  redEnhancement->setMinimumValue( redMin );
161  redEnhancement->setMaximumValue( redMax );
162  }
163 
164  bool greenMinOk, greenMaxOk;
165  const double greenMin = QgsDoubleValidator::toDouble( mGreenMinLineEdit->text(), &greenMinOk );
166  const double greenMax = QgsDoubleValidator::toDouble( mGreenMaxLineEdit->text(), &greenMaxOk );
167  if ( greenMinOk && greenMaxOk && greenBand != -1 )
168  {
169  greenEnhancement = new QgsContrastEnhancement( ( Qgis::DataType )(
170  provider->dataType( greenBand ) ) );
171  greenEnhancement->setMinimumValue( greenMin );
172  greenEnhancement->setMaximumValue( greenMax );
173  }
174 
175  bool blueMinOk, blueMaxOk;
176  const double blueMin = QgsDoubleValidator::toDouble( mBlueMinLineEdit->text(), &blueMinOk );
177  const double blueMax = QgsDoubleValidator::toDouble( mBlueMaxLineEdit->text(), &blueMaxOk );
178  if ( blueMinOk && blueMaxOk && blueBand != -1 )
179  {
180  blueEnhancement = new QgsContrastEnhancement( ( Qgis::DataType )(
181  provider->dataType( blueBand ) ) );
182  blueEnhancement->setMinimumValue( blueMin );
183  blueEnhancement->setMaximumValue( blueMax );
184  }
185 
186  if ( redEnhancement )
187  {
189  ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) );
190  }
191  if ( greenEnhancement )
192  {
194  ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) );
195  }
196  if ( blueEnhancement )
197  {
199  ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) );
200  }
201  r->setRedContrastEnhancement( redEnhancement );
202  r->setGreenContrastEnhancement( greenEnhancement );
203  r->setBlueContrastEnhancement( blueEnhancement );
204 }
205 
206 void QgsMultiBandColorRendererWidget::onBandChanged( int index )
207 {
208  Q_UNUSED( index )
209 
210  QList<int> myBands;
211  myBands.append( mRedBandComboBox->currentBand() );
212  myBands.append( mGreenBandComboBox->currentBand() );
213  myBands.append( mBlueBandComboBox->currentBand() );
214  mMinMaxWidget->setBands( myBands );
215  emit widgetChanged();
216 }
217 
218 void QgsMultiBandColorRendererWidget::mRedMinLineEdit_textChanged( const QString & )
219 {
220  minMaxModified();
221 }
222 
223 void QgsMultiBandColorRendererWidget::mRedMaxLineEdit_textChanged( const QString & )
224 {
225  minMaxModified();
226 }
227 
228 void QgsMultiBandColorRendererWidget::mGreenMinLineEdit_textChanged( const QString & )
229 {
230  minMaxModified();
231 }
232 
233 void QgsMultiBandColorRendererWidget::mGreenMaxLineEdit_textChanged( const QString & )
234 {
235  minMaxModified();
236 }
237 
238 void QgsMultiBandColorRendererWidget::mBlueMinLineEdit_textChanged( const QString & )
239 {
240  minMaxModified();
241 }
242 
243 void QgsMultiBandColorRendererWidget::mBlueMaxLineEdit_textChanged( const QString & )
244 {
245  minMaxModified();
246 }
247 
248 void QgsMultiBandColorRendererWidget::minMaxModified()
249 {
250  if ( !mDisableMinMaxWidgetRefresh )
251  {
252  if ( ( QgsContrastEnhancement::ContrastEnhancementAlgorithm )( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) == QgsContrastEnhancement::NoEnhancement )
253  {
254  mContrastEnhancementAlgorithmComboBox->setCurrentIndex(
255  mContrastEnhancementAlgorithmComboBox->findData( ( int ) QgsContrastEnhancement::StretchToMinimumMaximum ) );
256  }
257  mMinMaxWidget->userHasSetManualMinMaxValues();
258  emit widgetChanged();
259  }
260 }
261 
262 void QgsMultiBandColorRendererWidget::loadMinMax( int bandNo, double min, double max )
263 {
264  QgsDebugMsg( QStringLiteral( "theBandNo = %1 min = %2 max = %3" ).arg( bandNo ).arg( min ).arg( max ) );
265 
266  QLineEdit *myMinLineEdit, *myMaxLineEdit;
267 
268  if ( mRedBandComboBox->currentBand() == bandNo )
269  {
270  myMinLineEdit = mRedMinLineEdit;
271  myMaxLineEdit = mRedMaxLineEdit;
272  }
273  else if ( mGreenBandComboBox->currentBand() == bandNo )
274  {
275  myMinLineEdit = mGreenMinLineEdit;
276  myMaxLineEdit = mGreenMaxLineEdit;
277  }
278  else if ( mBlueBandComboBox->currentBand() == bandNo )
279  {
280  myMinLineEdit = mBlueMinLineEdit;
281  myMaxLineEdit = mBlueMaxLineEdit;
282  }
283  else // should not happen
284  {
285  QgsDebugMsg( QStringLiteral( "Band not found" ) );
286  return;
287  }
288 
289  mDisableMinMaxWidgetRefresh = true;
290  if ( std::isnan( min ) )
291  {
292  myMinLineEdit->clear();
293  }
294  else
295  {
296  myMinLineEdit->setText( QLocale().toString( min ) );
297  }
298 
299  if ( std::isnan( max ) )
300  {
301  myMaxLineEdit->clear();
302  }
303  else
304  {
305  myMaxLineEdit->setText( QLocale().toString( max ) );
306  }
307  mDisableMinMaxWidgetRefresh = false;
308 }
309 
310 void QgsMultiBandColorRendererWidget::setMinMaxValue( const QgsContrastEnhancement *ce, QLineEdit *minEdit, QLineEdit *maxEdit )
311 {
312  if ( !minEdit || !maxEdit )
313  {
314  return;
315  }
316 
317  if ( !ce )
318  {
319  minEdit->clear();
320  maxEdit->clear();
321  return;
322  }
323 
324  minEdit->setText( QLocale().toString( ce->minimumValue() ) );
325  maxEdit->setText( QLocale().toString( ce->maximumValue() ) );
326 
327  // QgsMultiBandColorRenderer is using individual contrast enhancements for each
328  // band, but this widget GUI has one for all
329  mContrastEnhancementAlgorithmComboBox->setCurrentIndex( mContrastEnhancementAlgorithmComboBox->findData(
330  ( int )( ce->contrastEnhancementAlgorithm() ) ) );
331 }
332 
334 {
335  const QgsMultiBandColorRenderer *mbcr = dynamic_cast<const QgsMultiBandColorRenderer *>( r );
336  if ( mbcr )
337  {
338  mRedBandComboBox->setBand( mbcr->redBand() );
339  mGreenBandComboBox->setBand( mbcr->greenBand() );
340  mBlueBandComboBox->setBand( mbcr->blueBand() );
341 
342  mDisableMinMaxWidgetRefresh = true;
343  setMinMaxValue( mbcr->redContrastEnhancement(), mRedMinLineEdit, mRedMaxLineEdit );
344  setMinMaxValue( mbcr->greenContrastEnhancement(), mGreenMinLineEdit, mGreenMaxLineEdit );
345  setMinMaxValue( mbcr->blueContrastEnhancement(), mBlueMinLineEdit, mBlueMaxLineEdit );
346  mDisableMinMaxWidgetRefresh = false;
347 
348  mMinMaxWidget->setFromMinMaxOrigin( mbcr->minMaxOrigin() );
349  }
350  else
351  {
352  if ( mRedBandComboBox->findText( tr( "Red" ) ) > -1 && mRedBandComboBox->findText( tr( "Green" ) ) > -1 &&
353  mRedBandComboBox->findText( tr( "Blue" ) ) > -1 )
354  {
355  mRedBandComboBox->setCurrentIndex( mRedBandComboBox->findText( tr( "Red" ) ) );
356  mGreenBandComboBox->setCurrentIndex( mGreenBandComboBox->findText( tr( "Green" ) ) );
357  mBlueBandComboBox->setCurrentIndex( mBlueBandComboBox->findText( tr( "Blue" ) ) );
358  }
359  else
360  {
361  mRedBandComboBox->setCurrentIndex( mRedBandComboBox->count() > 1 ? 1 : 0 );
362  mGreenBandComboBox->setCurrentIndex( mRedBandComboBox->count() > 2 ? 2 : 0 );
363  mBlueBandComboBox->setCurrentIndex( mRedBandComboBox->count() > 3 ? 3 : 0 );
364  }
365  }
366 }
367 
369 {
370  switch ( index )
371  {
372  case 0:
373  return mRedMinLineEdit->text();
374  case 1:
375  return mGreenMinLineEdit->text();
376  case 2:
377  return mBlueMinLineEdit->text();
378  default:
379  break;
380  }
381  return QString();
382 }
383 
385 {
386  switch ( index )
387  {
388  case 0:
389  return mRedMaxLineEdit->text();
390  case 1:
391  return mGreenMaxLineEdit->text();
392  case 2:
393  return mBlueMaxLineEdit->text();
394  default:
395  break;
396  }
397  return QString();
398 }
399 
400 void QgsMultiBandColorRendererWidget::setMin( const QString &value, int index )
401 {
402  mDisableMinMaxWidgetRefresh = true;
403  switch ( index )
404  {
405  case 0:
406  mRedMinLineEdit->setText( value );
407  break;
408  case 1:
409  mGreenMinLineEdit->setText( value );
410  break;
411  case 2:
412  mBlueMinLineEdit->setText( value );
413  break;
414  default:
415  break;
416  }
417  mDisableMinMaxWidgetRefresh = false;
418 }
419 
420 void QgsMultiBandColorRendererWidget::setMax( const QString &value, int index )
421 {
422  mDisableMinMaxWidgetRefresh = true;
423  switch ( index )
424  {
425  case 0:
426  mRedMaxLineEdit->setText( value );
427  break;
428  case 1:
429  mGreenMaxLineEdit->setText( value );
430  break;
431  case 2:
432  mBlueMaxLineEdit->setText( value );
433  break;
434  default:
435  break;
436  }
437  mDisableMinMaxWidgetRefresh = false;
438 }
439 
441 {
442  switch ( index )
443  {
444  case 0:
445  return mRedBandComboBox->currentBand();
446  case 1:
447  return mGreenBandComboBox->currentBand();
448  case 2:
449  return mBlueBandComboBox->currentBand();
450  default:
451  break;
452  }
453  return -1;
454 }
DataType
Raster data types.
Definition: qgis.h:120
Manipulates raster or point cloud pixel values so that they enhanceContrast or clip into a specified ...
ContrastEnhancementAlgorithm
This enumerator describes the types of contrast enhancement algorithms that can be used.
@ StretchToMinimumMaximum
Linear histogram.
@ NoEnhancement
Default color scaling algorithm, no scaling is applied.
void setMinimumValue(double value, bool generateTable=true)
Sets the minimum value for the contrast enhancement range.
void setContrastEnhancementAlgorithm(ContrastEnhancementAlgorithm algorithm, bool generateTable=true)
Sets the contrast enhancement algorithm.
double minimumValue() const
Returns the minimum value for the contrast enhancement range.
ContrastEnhancementAlgorithm contrastEnhancementAlgorithm() const
void setMaximumValue(double value, bool generateTable=true)
Sets the maximum value for the contrast enhancement range.
double maximumValue() const
Returns the maximum value for the contrast enhancement range.
QgsDoubleValidator is a QLineEdit Validator that combines QDoubleValidator and QRegularExpressionVali...
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.
Definition: qgsmapcanvas.h:89
void loadMinMax(int bandNo, double min, double max)
called when new min/max values are loaded
QgsMultiBandColorRendererWidget(QgsRasterLayer *layer, const QgsRectangle &extent=QgsRectangle())
void doComputations() override
Load programmatically with current values.
QgsRasterRenderer * renderer() override
Creates a new renderer, using the properties defined in the widget.
void setMin(const QString &value, int index=0) override
void setMax(const QString &value, int index=0) override
void setMapCanvas(QgsMapCanvas *canvas) override
Sets the map canvas associated with the widget.
void setFromRenderer(const QgsRasterRenderer *r)
Sets the widget state from the specified renderer.
Renderer for multiband images with the color components.
const QgsContrastEnhancement * redContrastEnhancement() const
Returns the contrast enhancement to use for the red channel.
const QgsContrastEnhancement * blueContrastEnhancement() const
Returns the contrast enhancement to use for the blue channel.
void setGreenContrastEnhancement(QgsContrastEnhancement *ce)
Sets the contrast enhancement to use for the green channel.
void setBlueContrastEnhancement(QgsContrastEnhancement *ce)
Sets the contrast enhancement to use for the blue channel.
void setRedContrastEnhancement(QgsContrastEnhancement *ce)
Sets the contrast enhancement to use for the red channel.
const QgsContrastEnhancement * greenContrastEnhancement() const
Returns the contrast enhancement to use for the green channel.
void bandChanged(int band)
Emitted when the currently selected band changes.
Base class for raster data providers.
Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.
Represents a raster layer.
QgsRasterRenderer * renderer() const
Returns the raster's renderer.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
void setExtent(const QgsRectangle &extent)
Sets the extent to use for minimum and maximum value calculation.
void doComputations()
Load programmatically with current values.
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.
void setBands(const QList< int > &bands)
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.
Abstract base class for widgets which configure a QgsRasterRenderer.
virtual void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
QgsMapCanvas * mCanvas
Associated map canvas.
void widgetChanged()
Emitted when something on the widget has changed.
Raster renderer pipe that applies colors to a raster.
void setMinMaxOrigin(const QgsRasterMinMaxOrigin &origin)
Sets origin of min/max values.
const QgsRasterMinMaxOrigin & minMaxOrigin() const
Returns const reference to origin of min/max values.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
#define QgsDebugMsg(str)
Definition: qgslogger.h:38