QGIS API Documentation  2.99.0-Master (c558d51)
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 {
28  setupUi( this );
29  createValidators();
30 
31  if ( mRasterLayer )
32  {
34  if ( !provider )
35  {
36  return;
37  }
38 
39  mMinMaxWidget = new QgsRasterMinMaxWidget( layer, this );
40  mMinMaxWidget->setExtent( extent );
41  mMinMaxWidget->setMapCanvas( mCanvas );
42  QHBoxLayout *layout = new QHBoxLayout();
43  layout->setContentsMargins( 0, 0, 0, 0 );
44  mMinMaxContainerWidget->setLayout( layout );
45  layout->addWidget( mMinMaxWidget );
46  connect( mMinMaxWidget, SIGNAL( load( int, double, double, int ) ),
47  this, SLOT( loadMinMax( int, double, double, int ) ) );
48 
49  connect( mRedBandComboBox, SIGNAL( currentIndexChanged( int ) ),
50  this, SLOT( onBandChanged( int ) ) );
51  connect( mGreenBandComboBox, SIGNAL( currentIndexChanged( int ) ),
52  this, SLOT( onBandChanged( int ) ) );
53  connect( mBlueBandComboBox, SIGNAL( currentIndexChanged( int ) ),
54  this, SLOT( onBandChanged( int ) ) );
55 
56  //fill available bands into combo boxes
57  mRedBandComboBox->addItem( tr( "Not set" ), -1 );
58  mGreenBandComboBox->addItem( tr( "Not set" ), -1 );
59  mBlueBandComboBox->addItem( tr( "Not set" ), -1 );
60 
61  //contrast enhancement algorithms
62  mContrastEnhancementAlgorithmComboBox->addItem( tr( "No enhancement" ), QgsContrastEnhancement::NoEnhancement );
63  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Stretch to MinMax" ), QgsContrastEnhancement::StretchToMinimumMaximum );
64  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Stretch and clip to MinMax" ), QgsContrastEnhancement::StretchAndClipToMinimumMaximum );
65  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Clip to MinMax" ), QgsContrastEnhancement::ClipToMinimumMaximum );
66 
67  int nBands = provider->bandCount();
68  for ( int i = 1; i <= nBands; ++i ) //band numbering seem to start at 1
69  {
70  QString bandName = displayBandName( i );
71  mRedBandComboBox->addItem( bandName, i );
72  mGreenBandComboBox->addItem( bandName, i );
73  mBlueBandComboBox->addItem( bandName, i );
74  }
75 
77  onBandChanged( 0 ); // reset mMinMaxWidget bands
78 
79  connect( mRedMinLineEdit, SIGNAL( textChanged( QString ) ), this, SIGNAL( widgetChanged() ) );
80  connect( mRedMaxLineEdit, SIGNAL( textChanged( QString ) ), this, SIGNAL( widgetChanged() ) );
81  connect( mGreenMaxLineEdit, SIGNAL( textChanged( QString ) ), this, SIGNAL( widgetChanged() ) );
82  connect( mGreenMinLineEdit, SIGNAL( textChanged( QString ) ), this, SIGNAL( widgetChanged() ) );
83  connect( mBlueMaxLineEdit, SIGNAL( textChanged( QString ) ), this, SIGNAL( widgetChanged() ) );
84  connect( mBlueMinLineEdit, SIGNAL( textChanged( QString ) ), this, SIGNAL( widgetChanged() ) );
85 
86  }
87 }
88 
90 {
91 }
92 
94 {
95  if ( !mRasterLayer )
96  {
97  return nullptr;
98  }
100  if ( !provider )
101  {
102  return nullptr;
103  }
104 
105  int redBand = mRedBandComboBox->currentData().toInt();
106  int greenBand = mGreenBandComboBox->currentData().toInt();
107  int blueBand = mBlueBandComboBox->currentData().toInt();
108 
109  QgsMultiBandColorRenderer* r = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand );
110  setCustomMinMaxValues( r, provider, redBand, greenBand, blueBand );
111  return r;
112 }
113 
115 {
117  mMinMaxWidget->setMapCanvas( canvas );
118 }
119 
120 void QgsMultiBandColorRendererWidget::createValidators()
121 {
122  mRedMinLineEdit->setValidator( new QDoubleValidator( mRedMinLineEdit ) );
123  mRedMaxLineEdit->setValidator( new QDoubleValidator( mRedMinLineEdit ) );
124  mGreenMinLineEdit->setValidator( new QDoubleValidator( mGreenMinLineEdit ) );
125  mGreenMaxLineEdit->setValidator( new QDoubleValidator( mGreenMinLineEdit ) );
126  mBlueMinLineEdit->setValidator( new QDoubleValidator( mBlueMinLineEdit ) );
127  mBlueMaxLineEdit->setValidator( new QDoubleValidator( mBlueMinLineEdit ) );
128 }
129 
130 void QgsMultiBandColorRendererWidget::setCustomMinMaxValues( QgsMultiBandColorRenderer* r,
131  const QgsRasterDataProvider* provider,
132  int redBand, int greenBand, int blueBand )
133 {
134  if ( !r || !provider )
135  {
136  return;
137  }
138 
139  if ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ==
141  {
142  r->setRedContrastEnhancement( nullptr );
143  r->setGreenContrastEnhancement( nullptr );
144  r->setBlueContrastEnhancement( nullptr );
145  return;
146  }
147 
148  QgsContrastEnhancement* redEnhancement = nullptr;
149  QgsContrastEnhancement* greenEnhancement = nullptr;
150  QgsContrastEnhancement* blueEnhancement = nullptr;
151 
152  bool redMinOk, redMaxOk;
153  double redMin = mRedMinLineEdit->text().toDouble( &redMinOk );
154  double redMax = mRedMaxLineEdit->text().toDouble( &redMaxOk );
155  if ( redMinOk && redMaxOk && redBand != -1 )
156  {
157  redEnhancement = new QgsContrastEnhancement(( Qgis::DataType )(
158  provider->dataType( redBand ) ) );
159  redEnhancement->setMinimumValue( redMin );
160  redEnhancement->setMaximumValue( redMax );
161  }
162 
163  bool greenMinOk, greenMaxOk;
164  double greenMin = mGreenMinLineEdit->text().toDouble( &greenMinOk );
165  double greenMax = mGreenMaxLineEdit->text().toDouble( &greenMaxOk );
166  if ( greenMinOk && greenMaxOk && greenBand != -1 )
167  {
168  greenEnhancement = new QgsContrastEnhancement(( Qgis::DataType )(
169  provider->dataType( greenBand ) ) );
170  greenEnhancement->setMinimumValue( greenMin );
171  greenEnhancement->setMaximumValue( greenMax );
172  }
173 
174  bool blueMinOk, blueMaxOk;
175  double blueMin = mBlueMinLineEdit->text().toDouble( &blueMinOk );
176  double blueMax = mBlueMaxLineEdit->text().toDouble( &blueMaxOk );
177  if ( blueMinOk && blueMaxOk && blueBand != -1 )
178  {
179  blueEnhancement = new QgsContrastEnhancement(( Qgis::DataType )(
180  provider->dataType( blueBand ) ) );
181  blueEnhancement->setMinimumValue( blueMin );
182  blueEnhancement->setMaximumValue( blueMax );
183  }
184 
185  if ( redEnhancement )
186  {
188  ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) );
189  }
190  if ( greenEnhancement )
191  {
193  ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) );
194  }
195  if ( blueEnhancement )
196  {
198  ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) );
199  }
200  r->setRedContrastEnhancement( redEnhancement );
201  r->setGreenContrastEnhancement( greenEnhancement );
202  r->setBlueContrastEnhancement( blueEnhancement );
203 }
204 
205 void QgsMultiBandColorRendererWidget::onBandChanged( int index )
206 {
207  Q_UNUSED( index );
208 
209  QList<int> myBands;
210  myBands.append( mRedBandComboBox->currentData().toInt() );
211  myBands.append( mGreenBandComboBox->currentData().toInt() );
212  myBands.append( mBlueBandComboBox->currentData().toInt() );
213  mMinMaxWidget->setBands( myBands );
214  emit widgetChanged();
215 }
216 
217 void QgsMultiBandColorRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin )
218 {
219  Q_UNUSED( theOrigin );
220  QgsDebugMsg( QString( "theBandNo = %1 theMin = %2 theMax = %3" ).arg( theBandNo ).arg( theMin ).arg( theMax ) );
221 
222  QLineEdit *myMinLineEdit, *myMaxLineEdit;
223 
224  if ( mRedBandComboBox->currentData().toInt() == theBandNo )
225  {
226  myMinLineEdit = mRedMinLineEdit;
227  myMaxLineEdit = mRedMaxLineEdit;
228  }
229  else if ( mGreenBandComboBox->currentData().toInt() == theBandNo )
230  {
231  myMinLineEdit = mGreenMinLineEdit;
232  myMaxLineEdit = mGreenMaxLineEdit;
233  }
234  else if ( mBlueBandComboBox->currentData().toInt() == theBandNo )
235  {
236  myMinLineEdit = mBlueMinLineEdit;
237  myMaxLineEdit = mBlueMaxLineEdit;
238  }
239  else // should not happen
240  {
241  QgsDebugMsg( "Band not found" );
242  return;
243  }
244 
245  if ( qIsNaN( theMin ) )
246  {
247  myMinLineEdit->clear();
248  }
249  else
250  {
251  myMinLineEdit->setText( QString::number( theMin ) );
252  }
253 
254  if ( qIsNaN( theMax ) )
255  {
256  myMaxLineEdit->clear();
257  }
258  else
259  {
260  myMaxLineEdit->setText( QString::number( theMax ) );
261  }
262 
263  //automaticlly activate contrast enhancement algorithm if set to none
264  if ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() == QgsContrastEnhancement::NoEnhancement )
265  {
266  mContrastEnhancementAlgorithmComboBox->setCurrentIndex(
267  mContrastEnhancementAlgorithmComboBox->findData( QgsContrastEnhancement::StretchToMinimumMaximum ) );
268  }
269 }
270 
271 void QgsMultiBandColorRendererWidget::setMinMaxValue( const QgsContrastEnhancement* ce, QLineEdit* minEdit, QLineEdit* maxEdit )
272 {
273  if ( !minEdit || !maxEdit )
274  {
275  return;
276  }
277 
278  if ( !ce )
279  {
280  minEdit->clear();
281  maxEdit->clear();
282  return;
283  }
284 
285  minEdit->setText( QString::number( ce->minimumValue() ) );
286  maxEdit->setText( QString::number( ce->maximumValue() ) );
287 
288  // QgsMultiBandColorRenderer is using individual contrast enhancements for each
289  // band, but this widget GUI has one for all
290  mContrastEnhancementAlgorithmComboBox->setCurrentIndex( mContrastEnhancementAlgorithmComboBox->findData(
291  ( int )( ce->contrastEnhancementAlgorithm() ) ) );
292 }
293 
295 {
296  const QgsMultiBandColorRenderer* mbcr = dynamic_cast<const QgsMultiBandColorRenderer*>( r );
297  if ( mbcr )
298  {
299  mRedBandComboBox->setCurrentIndex( mRedBandComboBox->findData( mbcr->redBand() ) );
300  mGreenBandComboBox->setCurrentIndex( mGreenBandComboBox->findData( mbcr->greenBand() ) );
301  mBlueBandComboBox->setCurrentIndex( mBlueBandComboBox->findData( mbcr->blueBand() ) );
302 
303  setMinMaxValue( mbcr->redContrastEnhancement(), mRedMinLineEdit, mRedMaxLineEdit );
304  setMinMaxValue( mbcr->greenContrastEnhancement(), mGreenMinLineEdit, mGreenMaxLineEdit );
305  setMinMaxValue( mbcr->blueContrastEnhancement(), mBlueMinLineEdit, mBlueMaxLineEdit );
306  }
307  else
308  {
309  if ( mRedBandComboBox->findText( tr( "Red" ) ) > -1 && mRedBandComboBox->findText( tr( "Green" ) ) > -1 &&
310  mRedBandComboBox->findText( tr( "Blue" ) ) > -1 )
311  {
312  mRedBandComboBox->setCurrentIndex( mRedBandComboBox->findText( tr( "Red" ) ) );
313  mGreenBandComboBox->setCurrentIndex( mGreenBandComboBox->findText( tr( "Green" ) ) );
314  mBlueBandComboBox->setCurrentIndex( mBlueBandComboBox->findText( tr( "Blue" ) ) );
315  }
316  else
317  {
318  mRedBandComboBox->setCurrentIndex( mRedBandComboBox->count() > 1 ? 1 : 0 );
319  mGreenBandComboBox->setCurrentIndex( mRedBandComboBox->count() > 2 ? 2 : 0 );
320  mBlueBandComboBox->setCurrentIndex( mRedBandComboBox->count() > 3 ? 3 : 0 );
321  }
322  }
323 }
324 
326 {
327  switch ( index )
328  {
329  case 0:
330  return mRedMinLineEdit->text();
331  case 1:
332  return mGreenMinLineEdit->text();
333  case 2:
334  return mBlueMinLineEdit->text();
335  default:
336  break;
337  }
338  return QString();
339 }
340 
342 {
343  switch ( index )
344  {
345  case 0:
346  return mRedMaxLineEdit->text();
347  case 1:
348  return mGreenMaxLineEdit->text();
349  case 2:
350  return mBlueMaxLineEdit->text();
351  default:
352  break;
353  }
354  return QString();
355 }
356 
357 void QgsMultiBandColorRendererWidget::setMin( const QString& value, int index )
358 {
359  switch ( index )
360  {
361  case 0:
362  mRedMinLineEdit->setText( value );
363  break;
364  case 1:
365  mGreenMinLineEdit->setText( value );
366  break;
367  case 2:
368  mBlueMinLineEdit->setText( value );
369  break;
370  default:
371  break;
372  }
373 }
374 
375 void QgsMultiBandColorRendererWidget::setMax( const QString& value, int index )
376 {
377  switch ( index )
378  {
379  case 0:
380  mRedMaxLineEdit->setText( value );
381  break;
382  case 1:
383  mGreenMaxLineEdit->setText( value );
384  break;
385  case 2:
386  mBlueMaxLineEdit->setText( value );
387  break;
388  default:
389  break;
390  }
391 }
392 
394 {
395  switch ( index )
396  {
397  case 0:
398  return mRedBandComboBox->currentIndex();
399  case 1:
400  return mGreenBandComboBox->currentIndex();
401  case 2:
402  return mBlueBandComboBox->currentIndex();
403  default:
404  break;
405  }
406  return -1;
407 }
virtual int bandCount() const =0
Get number of bands.
void setContrastEnhancementAlgorithm(ContrastEnhancementAlgorithm, bool generateTable=true)
Set the contrast enhancement algorithm.
static unsigned index
void setFromRenderer(const QgsRasterRenderer *r)
A rectangle specified with double values.
Definition: qgsrectangle.h:35
void loadMinMax(int theBandNo, double theMin, double theMax, int theOrigin)
void setMapCanvas(QgsMapCanvas *canvas) override
Sets the map canvas associated with the widget.
const QgsContrastEnhancement * greenContrastEnhancement() const
ContrastEnhancementAlgorithm contrastEnhancementAlgorithm() const
QgsMultiBandColorRendererWidget(QgsRasterLayer *layer, const QgsRectangle &extent=QgsRectangle())
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
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:60
const QgsContrastEnhancement * redContrastEnhancement() const
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:106
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 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.
QgsRasterRenderer * renderer() const
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.
double minimumValue() const
Return the minimum value for the contrast enhancement range.
const QgsContrastEnhancement * blueContrastEnhancement() const
ContrastEnhancementAlgorithm
This enumerator describes the types of contrast enhancement algorithms that can be used...
QString displayBandName(int band) const
Returns a band name for display. First choice is color name, otherwise band number.
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
double maximumValue() const
Return the maximum value for the contrast enhancement range.
void setBlueContrastEnhancement(QgsContrastEnhancement *ce)
Takes ownership.
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.
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 setMaximumValue(double, bool generateTable=true)
Set the maximum value for the contrast enhancement range.
Base class for raster data providers.