QGIS API Documentation  2.99.0-Master (7fe5405)
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, SIGNAL( currentIndexChanged( int ) ),
54  this, SLOT( onBandChanged( int ) ) );
55  connect( mGreenBandComboBox, SIGNAL( currentIndexChanged( int ) ),
56  this, SLOT( onBandChanged( int ) ) );
57  connect( mBlueBandComboBox, SIGNAL( currentIndexChanged( int ) ),
58  this, SLOT( onBandChanged( int ) ) );
59 
60  //fill available bands into combo boxes
61  mRedBandComboBox->addItem( tr( "Not set" ), -1 );
62  mGreenBandComboBox->addItem( tr( "Not set" ), -1 );
63  mBlueBandComboBox->addItem( tr( "Not set" ), -1 );
64 
65  //contrast enhancement algorithms
66  mContrastEnhancementAlgorithmComboBox->addItem( tr( "No enhancement" ), QgsContrastEnhancement::NoEnhancement );
67  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Stretch to MinMax" ), QgsContrastEnhancement::StretchToMinimumMaximum );
68  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Stretch and clip to MinMax" ), QgsContrastEnhancement::StretchAndClipToMinimumMaximum );
69  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Clip to MinMax" ), QgsContrastEnhancement::ClipToMinimumMaximum );
70 
71  int nBands = provider->bandCount();
72  for ( int i = 1; i <= nBands; ++i ) //band numbering seem to start at 1
73  {
74  QString bandName = displayBandName( i );
75  mRedBandComboBox->addItem( bandName, i );
76  mGreenBandComboBox->addItem( bandName, i );
77  mBlueBandComboBox->addItem( bandName, i );
78  }
79 
81  onBandChanged( 0 ); // reset mMinMaxWidget bands
82 
83  connect( mContrastEnhancementAlgorithmComboBox, SIGNAL( currentIndexChanged( int ) ), this, SIGNAL( widgetChanged() ) );
84  }
85 }
86 
88 {
89  if ( !mRasterLayer )
90  {
91  return nullptr;
92  }
94  if ( !provider )
95  {
96  return nullptr;
97  }
98 
99  int redBand = mRedBandComboBox->currentData().toInt();
100  int greenBand = mGreenBandComboBox->currentData().toInt();
101  int blueBand = mBlueBandComboBox->currentData().toInt();
102 
103  QgsMultiBandColorRenderer* r = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand );
104  setCustomMinMaxValues( r, provider, redBand, greenBand, blueBand );
105 
106  r->setMinMaxOrigin( mMinMaxWidget->minMaxOrigin() );
107 
108  return r;
109 }
110 
112 {
113  mMinMaxWidget->doComputations();
114 }
115 
117 {
119  mMinMaxWidget->setMapCanvas( canvas );
120 }
121 
122 void QgsMultiBandColorRendererWidget::createValidators()
123 {
124  mRedMinLineEdit->setValidator( new QDoubleValidator( mRedMinLineEdit ) );
125  mRedMaxLineEdit->setValidator( new QDoubleValidator( mRedMinLineEdit ) );
126  mGreenMinLineEdit->setValidator( new QDoubleValidator( mGreenMinLineEdit ) );
127  mGreenMaxLineEdit->setValidator( new QDoubleValidator( mGreenMinLineEdit ) );
128  mBlueMinLineEdit->setValidator( new QDoubleValidator( mBlueMinLineEdit ) );
129  mBlueMaxLineEdit->setValidator( new QDoubleValidator( mBlueMinLineEdit ) );
130 }
131 
132 void QgsMultiBandColorRendererWidget::setCustomMinMaxValues( QgsMultiBandColorRenderer* r,
133  const QgsRasterDataProvider* provider,
134  int redBand, int greenBand, int blueBand )
135 {
136  if ( !r || !provider )
137  {
138  return;
139  }
140 
141  if ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ==
143  {
144  r->setRedContrastEnhancement( nullptr );
145  r->setGreenContrastEnhancement( nullptr );
146  r->setBlueContrastEnhancement( nullptr );
147  return;
148  }
149 
150  QgsContrastEnhancement* redEnhancement = nullptr;
151  QgsContrastEnhancement* greenEnhancement = nullptr;
152  QgsContrastEnhancement* blueEnhancement = nullptr;
153 
154  bool redMinOk, redMaxOk;
155  double redMin = mRedMinLineEdit->text().toDouble( &redMinOk );
156  double redMax = mRedMaxLineEdit->text().toDouble( &redMaxOk );
157  if ( redMinOk && redMaxOk && redBand != -1 )
158  {
159  redEnhancement = new QgsContrastEnhancement(( Qgis::DataType )(
160  provider->dataType( redBand ) ) );
161  redEnhancement->setMinimumValue( redMin );
162  redEnhancement->setMaximumValue( redMax );
163  }
164 
165  bool greenMinOk, greenMaxOk;
166  double greenMin = mGreenMinLineEdit->text().toDouble( &greenMinOk );
167  double greenMax = mGreenMaxLineEdit->text().toDouble( &greenMaxOk );
168  if ( greenMinOk && greenMaxOk && greenBand != -1 )
169  {
170  greenEnhancement = new QgsContrastEnhancement(( Qgis::DataType )(
171  provider->dataType( greenBand ) ) );
172  greenEnhancement->setMinimumValue( greenMin );
173  greenEnhancement->setMaximumValue( greenMax );
174  }
175 
176  bool blueMinOk, blueMaxOk;
177  double blueMin = mBlueMinLineEdit->text().toDouble( &blueMinOk );
178  double blueMax = mBlueMaxLineEdit->text().toDouble( &blueMaxOk );
179  if ( blueMinOk && blueMaxOk && blueBand != -1 )
180  {
181  blueEnhancement = new QgsContrastEnhancement(( Qgis::DataType )(
182  provider->dataType( blueBand ) ) );
183  blueEnhancement->setMinimumValue( blueMin );
184  blueEnhancement->setMaximumValue( blueMax );
185  }
186 
187  if ( redEnhancement )
188  {
190  ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) );
191  }
192  if ( greenEnhancement )
193  {
195  ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) );
196  }
197  if ( blueEnhancement )
198  {
200  ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) );
201  }
202  r->setRedContrastEnhancement( redEnhancement );
203  r->setGreenContrastEnhancement( greenEnhancement );
204  r->setBlueContrastEnhancement( blueEnhancement );
205 }
206 
207 void QgsMultiBandColorRendererWidget::onBandChanged( int index )
208 {
209  Q_UNUSED( index );
210 
211  QList<int> myBands;
212  myBands.append( mRedBandComboBox->currentData().toInt() );
213  myBands.append( mGreenBandComboBox->currentData().toInt() );
214  myBands.append( mBlueBandComboBox->currentData().toInt() );
215  mMinMaxWidget->setBands( myBands );
216  emit widgetChanged();
217 }
218 
219 void QgsMultiBandColorRendererWidget::on_mRedMinLineEdit_textChanged( const QString & )
220 {
221  minMaxModified();
222 }
223 
224 void QgsMultiBandColorRendererWidget::on_mRedMaxLineEdit_textChanged( const QString & )
225 {
226  minMaxModified();
227 }
228 
229 void QgsMultiBandColorRendererWidget::on_mGreenMinLineEdit_textChanged( const QString & )
230 {
231  minMaxModified();
232 }
233 
234 void QgsMultiBandColorRendererWidget::on_mGreenMaxLineEdit_textChanged( const QString & )
235 {
236  minMaxModified();
237 }
238 
239 void QgsMultiBandColorRendererWidget::on_mBlueMinLineEdit_textChanged( const QString & )
240 {
241  minMaxModified();
242 }
243 
244 void QgsMultiBandColorRendererWidget::on_mBlueMaxLineEdit_textChanged( const QString & )
245 {
246  minMaxModified();
247 }
248 
249 void QgsMultiBandColorRendererWidget::minMaxModified()
250 {
251  if ( !mDisableMinMaxWidgetRefresh )
252  {
253  if (( QgsContrastEnhancement::ContrastEnhancementAlgorithm )( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) == QgsContrastEnhancement::NoEnhancement )
254  {
255  mContrastEnhancementAlgorithmComboBox->setCurrentIndex(
256  mContrastEnhancementAlgorithmComboBox->findData(( int ) QgsContrastEnhancement::StretchToMinimumMaximum ) );
257  }
258  mMinMaxWidget->userHasSetManualMinMaxValues();
259  emit widgetChanged();
260  }
261 }
262 
263 void QgsMultiBandColorRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax )
264 {
265  QgsDebugMsg( QString( "theBandNo = %1 theMin = %2 theMax = %3" ).arg( theBandNo ).arg( theMin ).arg( theMax ) );
266 
267  QLineEdit *myMinLineEdit, *myMaxLineEdit;
268 
269  if ( mRedBandComboBox->currentData().toInt() == theBandNo )
270  {
271  myMinLineEdit = mRedMinLineEdit;
272  myMaxLineEdit = mRedMaxLineEdit;
273  }
274  else if ( mGreenBandComboBox->currentData().toInt() == theBandNo )
275  {
276  myMinLineEdit = mGreenMinLineEdit;
277  myMaxLineEdit = mGreenMaxLineEdit;
278  }
279  else if ( mBlueBandComboBox->currentData().toInt() == theBandNo )
280  {
281  myMinLineEdit = mBlueMinLineEdit;
282  myMaxLineEdit = mBlueMaxLineEdit;
283  }
284  else // should not happen
285  {
286  QgsDebugMsg( "Band not found" );
287  return;
288  }
289 
290  mDisableMinMaxWidgetRefresh = true;
291  if ( qIsNaN( theMin ) )
292  {
293  myMinLineEdit->clear();
294  }
295  else
296  {
297  myMinLineEdit->setText( QString::number( theMin ) );
298  }
299 
300  if ( qIsNaN( theMax ) )
301  {
302  myMaxLineEdit->clear();
303  }
304  else
305  {
306  myMaxLineEdit->setText( QString::number( theMax ) );
307  }
308  mDisableMinMaxWidgetRefresh = false;
309 }
310 
311 void QgsMultiBandColorRendererWidget::setMinMaxValue( const QgsContrastEnhancement* ce, QLineEdit* minEdit, QLineEdit* maxEdit )
312 {
313  if ( !minEdit || !maxEdit )
314  {
315  return;
316  }
317 
318  if ( !ce )
319  {
320  minEdit->clear();
321  maxEdit->clear();
322  return;
323  }
324 
325  minEdit->setText( QString::number( ce->minimumValue() ) );
326  maxEdit->setText( QString::number( ce->maximumValue() ) );
327 
328  // QgsMultiBandColorRenderer is using individual contrast enhancements for each
329  // band, but this widget GUI has one for all
330  mContrastEnhancementAlgorithmComboBox->setCurrentIndex( mContrastEnhancementAlgorithmComboBox->findData(
331  ( int )( ce->contrastEnhancementAlgorithm() ) ) );
332 }
333 
335 {
336  const QgsMultiBandColorRenderer* mbcr = dynamic_cast<const QgsMultiBandColorRenderer*>( r );
337  if ( mbcr )
338  {
339  mRedBandComboBox->setCurrentIndex( mRedBandComboBox->findData( mbcr->redBand() ) );
340  mGreenBandComboBox->setCurrentIndex( mGreenBandComboBox->findData( mbcr->greenBand() ) );
341  mBlueBandComboBox->setCurrentIndex( mBlueBandComboBox->findData( mbcr->blueBand() ) );
342 
343  mDisableMinMaxWidgetRefresh = true;
344  setMinMaxValue( mbcr->redContrastEnhancement(), mRedMinLineEdit, mRedMaxLineEdit );
345  setMinMaxValue( mbcr->greenContrastEnhancement(), mGreenMinLineEdit, mGreenMaxLineEdit );
346  setMinMaxValue( mbcr->blueContrastEnhancement(), mBlueMinLineEdit, mBlueMaxLineEdit );
347  mDisableMinMaxWidgetRefresh = false;
348 
349  mMinMaxWidget->setFromMinMaxOrigin( mbcr->minMaxOrigin() );
350  }
351  else
352  {
353  if ( mRedBandComboBox->findText( tr( "Red" ) ) > -1 && mRedBandComboBox->findText( tr( "Green" ) ) > -1 &&
354  mRedBandComboBox->findText( tr( "Blue" ) ) > -1 )
355  {
356  mRedBandComboBox->setCurrentIndex( mRedBandComboBox->findText( tr( "Red" ) ) );
357  mGreenBandComboBox->setCurrentIndex( mGreenBandComboBox->findText( tr( "Green" ) ) );
358  mBlueBandComboBox->setCurrentIndex( mBlueBandComboBox->findText( tr( "Blue" ) ) );
359  }
360  else
361  {
362  mRedBandComboBox->setCurrentIndex( mRedBandComboBox->count() > 1 ? 1 : 0 );
363  mGreenBandComboBox->setCurrentIndex( mRedBandComboBox->count() > 2 ? 2 : 0 );
364  mBlueBandComboBox->setCurrentIndex( mRedBandComboBox->count() > 3 ? 3 : 0 );
365  }
366  }
367 }
368 
370 {
371  switch ( index )
372  {
373  case 0:
374  return mRedMinLineEdit->text();
375  case 1:
376  return mGreenMinLineEdit->text();
377  case 2:
378  return mBlueMinLineEdit->text();
379  default:
380  break;
381  }
382  return QString();
383 }
384 
386 {
387  switch ( index )
388  {
389  case 0:
390  return mRedMaxLineEdit->text();
391  case 1:
392  return mGreenMaxLineEdit->text();
393  case 2:
394  return mBlueMaxLineEdit->text();
395  default:
396  break;
397  }
398  return QString();
399 }
400 
401 void QgsMultiBandColorRendererWidget::setMin( const QString& value, int index )
402 {
403  mDisableMinMaxWidgetRefresh = true;
404  switch ( index )
405  {
406  case 0:
407  mRedMinLineEdit->setText( value );
408  break;
409  case 1:
410  mGreenMinLineEdit->setText( value );
411  break;
412  case 2:
413  mBlueMinLineEdit->setText( value );
414  break;
415  default:
416  break;
417  }
418  mDisableMinMaxWidgetRefresh = false;
419 }
420 
421 void QgsMultiBandColorRendererWidget::setMax( const QString& value, int index )
422 {
423  mDisableMinMaxWidgetRefresh = true;
424  switch ( index )
425  {
426  case 0:
427  mRedMaxLineEdit->setText( value );
428  break;
429  case 1:
430  mGreenMaxLineEdit->setText( value );
431  break;
432  case 2:
433  mBlueMaxLineEdit->setText( value );
434  break;
435  default:
436  break;
437  }
438  mDisableMinMaxWidgetRefresh = false;
439 }
440 
442 {
443  switch ( index )
444  {
445  case 0:
446  return mRedBandComboBox->currentIndex();
447  case 1:
448  return mGreenBandComboBox->currentIndex();
449  case 2:
450  return mBlueBandComboBox->currentIndex();
451  default:
452  break;
453  }
454  return -1;
455 }
virtual int bandCount() const =0
Get number of bands.
void setContrastEnhancementAlgorithm(ContrastEnhancementAlgorithm, bool generateTable=true)
Set the contrast enhancement algorithm.
static unsigned index
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:36
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:36
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
void setBands(const QList< int > &theBands)
DataType
Raster data types.
Definition: qgis.h:61
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
void setMinMaxOrigin(const QgsRasterMinMaxOrigin &theOrigin)
Sets origin of min/max values.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:74
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
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 setExtent(const QgsRectangle &theExtent)
Sets the extent to use for minimum and maximum value calculation.
void setMinimumValue(double, bool generateTable=true)
Return the minimum value for the contrast enhancement range.
QString displayBandName(int band) const
Returns a band name for display. First choice is color name, otherwise band number.
void load(int theBandNo, double theMin, double theMax)
signal emitted when new min/max values are computed from statistics.
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...
QgsRasterDataProvider * dataProvider()
Returns the data provider.
void loadMinMax(int theBandNo, double theMin, double theMax)
called when new min/max values are loaded
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.