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