QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 
23  : QgsRasterRendererWidget( layer, extent )
24  , mMinMaxWidget( nullptr )
25 {
26  setupUi( this );
27  createValidators();
28 
29  if ( mRasterLayer )
30  {
32  if ( !provider )
33  {
34  return;
35  }
36 
37  mMinMaxWidget = new QgsRasterMinMaxWidget( layer, this );
38  mMinMaxWidget->setExtent( extent );
39  mMinMaxWidget->setMapCanvas( mCanvas );
41  layout->setContentsMargins( 0, 0, 0, 0 );
42  mMinMaxContainerWidget->setLayout( layout );
43  layout->addWidget( mMinMaxWidget );
44  connect( mMinMaxWidget, SIGNAL( load( int, double, double, int ) ),
45  this, SLOT( loadMinMax( int, double, double, int ) ) );
46 
47  connect( mRedBandComboBox, SIGNAL( currentIndexChanged( int ) ),
48  this, SLOT( onBandChanged( int ) ) );
49  connect( mGreenBandComboBox, SIGNAL( currentIndexChanged( int ) ),
50  this, SLOT( onBandChanged( int ) ) );
51  connect( mBlueBandComboBox, SIGNAL( currentIndexChanged( int ) ),
52  this, SLOT( onBandChanged( int ) ) );
53 
54  //fill available bands into combo boxes
55  mRedBandComboBox->addItem( tr( "Not set" ), -1 );
56  mGreenBandComboBox->addItem( tr( "Not set" ), -1 );
57  mBlueBandComboBox->addItem( tr( "Not set" ), -1 );
58 
59  //contrast enhancement algorithms
60  mContrastEnhancementAlgorithmComboBox->addItem( tr( "No enhancement" ), 0 );
61  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Stretch to MinMax" ), 1 );
62  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Stretch and clip to MinMax" ), 2 );
63  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Clip to MinMax" ), 3 );
64 
65  int nBands = provider->bandCount();
66  for ( int i = 1; i <= nBands; ++i ) //band numbering seem to start at 1
67  {
68  QString bandName = displayBandName( i );
69  mRedBandComboBox->addItem( bandName, i );
70  mGreenBandComboBox->addItem( bandName, i );
71  mBlueBandComboBox->addItem( bandName, i );
72  }
73 
75  onBandChanged( 0 ); // reset mMinMaxWidget bands
76 
77  connect( mRedMinLineEdit, SIGNAL( textChanged( QString ) ), this, SIGNAL( widgetChanged() ) );
78  connect( mRedMaxLineEdit, SIGNAL( textChanged( QString ) ), this, SIGNAL( widgetChanged() ) );
79  connect( mGreenMaxLineEdit, SIGNAL( textChanged( QString ) ), this, SIGNAL( widgetChanged() ) );
80  connect( mGreenMinLineEdit, SIGNAL( textChanged( QString ) ), this, SIGNAL( widgetChanged() ) );
81  connect( mBlueMaxLineEdit, SIGNAL( textChanged( QString ) ), this, SIGNAL( widgetChanged() ) );
82  connect( mBlueMinLineEdit, SIGNAL( textChanged( QString ) ), this, SIGNAL( widgetChanged() ) );
83 
84  }
85 }
86 
88 {
89 }
90 
92 {
93  if ( !mRasterLayer )
94  {
95  return nullptr;
96  }
98  if ( !provider )
99  {
100  return nullptr;
101  }
102 
103  int redBand = mRedBandComboBox->itemData( mRedBandComboBox->currentIndex() ).toInt();
104  int greenBand = mGreenBandComboBox->itemData( mGreenBandComboBox->currentIndex() ).toInt();
105  int blueBand = mBlueBandComboBox->itemData( mBlueBandComboBox->currentIndex() ).toInt();
106 
107  QgsMultiBandColorRenderer* r = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand );
108  setCustomMinMaxValues( r, provider, redBand, greenBand, blueBand );
109  return r;
110 }
111 
113 {
115  mMinMaxWidget->setMapCanvas( canvas );
116 }
117 
118 void QgsMultiBandColorRendererWidget::createValidators()
119 {
120  mRedMinLineEdit->setValidator( new QDoubleValidator( mRedMinLineEdit ) );
121  mRedMaxLineEdit->setValidator( new QDoubleValidator( mRedMinLineEdit ) );
122  mGreenMinLineEdit->setValidator( new QDoubleValidator( mGreenMinLineEdit ) );
123  mGreenMaxLineEdit->setValidator( new QDoubleValidator( mGreenMinLineEdit ) );
124  mBlueMinLineEdit->setValidator( new QDoubleValidator( mBlueMinLineEdit ) );
125  mBlueMaxLineEdit->setValidator( new QDoubleValidator( mBlueMinLineEdit ) );
126 }
127 
128 void QgsMultiBandColorRendererWidget::setCustomMinMaxValues( QgsMultiBandColorRenderer* r,
129  const QgsRasterDataProvider* provider,
130  int redBand, int greenBand, int blueBand )
131 {
132  if ( !r || !provider )
133  {
134  return;
135  }
136 
137  if ( mContrastEnhancementAlgorithmComboBox->itemData( mContrastEnhancementAlgorithmComboBox->currentIndex() ).toInt() ==
139  {
140  r->setRedContrastEnhancement( nullptr );
141  r->setGreenContrastEnhancement( nullptr );
142  r->setBlueContrastEnhancement( nullptr );
143  return;
144  }
145 
146  QgsContrastEnhancement* redEnhancement = nullptr;
147  QgsContrastEnhancement* greenEnhancement = nullptr;
148  QgsContrastEnhancement* blueEnhancement = nullptr;
149 
150  bool redMinOk, redMaxOk;
151  double redMin = mRedMinLineEdit->text().toDouble( &redMinOk );
152  double redMax = mRedMaxLineEdit->text().toDouble( &redMaxOk );
153  if ( redMinOk && redMaxOk && redBand != -1 )
154  {
155  redEnhancement = new QgsContrastEnhancement(( QGis::DataType )(
156  provider->dataType( redBand ) ) );
157  redEnhancement->setMinimumValue( redMin );
158  redEnhancement->setMaximumValue( redMax );
159  }
160 
161  bool greenMinOk, greenMaxOk;
162  double greenMin = mGreenMinLineEdit->text().toDouble( &greenMinOk );
163  double greenMax = mGreenMaxLineEdit->text().toDouble( &greenMaxOk );
164  if ( greenMinOk && greenMaxOk && greenBand != -1 )
165  {
166  greenEnhancement = new QgsContrastEnhancement(( QGis::DataType )(
167  provider->dataType( greenBand ) ) );
168  greenEnhancement->setMinimumValue( greenMin );
169  greenEnhancement->setMaximumValue( greenMax );
170  }
171 
172  bool blueMinOk, blueMaxOk;
173  double blueMin = mBlueMinLineEdit->text().toDouble( &blueMinOk );
174  double blueMax = mBlueMaxLineEdit->text().toDouble( &blueMaxOk );
175  if ( blueMinOk && blueMaxOk && blueBand != -1 )
176  {
177  blueEnhancement = new QgsContrastEnhancement(( QGis::DataType )(
178  provider->dataType( blueBand ) ) );
179  blueEnhancement->setMinimumValue( blueMin );
180  blueEnhancement->setMaximumValue( blueMax );
181  }
182 
183  if ( redEnhancement )
184  {
186  ( mContrastEnhancementAlgorithmComboBox->itemData( mContrastEnhancementAlgorithmComboBox->currentIndex() ).toInt() ) );
187  }
188  if ( greenEnhancement )
189  {
191  ( mContrastEnhancementAlgorithmComboBox->itemData( mContrastEnhancementAlgorithmComboBox->currentIndex() ).toInt() ) );
192  }
193  if ( blueEnhancement )
194  {
196  ( mContrastEnhancementAlgorithmComboBox->itemData( mContrastEnhancementAlgorithmComboBox->currentIndex() ).toInt() ) );
197  }
198  r->setRedContrastEnhancement( redEnhancement );
199  r->setGreenContrastEnhancement( greenEnhancement );
200  r->setBlueContrastEnhancement( blueEnhancement );
201 }
202 
203 void QgsMultiBandColorRendererWidget::onBandChanged( int index )
204 {
205  Q_UNUSED( index );
206 
207  QList<int> myBands;
208  myBands.append( mRedBandComboBox->itemData( mRedBandComboBox->currentIndex() ).toInt() );
209  myBands.append( mGreenBandComboBox->itemData( mGreenBandComboBox->currentIndex() ).toInt() );
210  myBands.append( mBlueBandComboBox->itemData( mBlueBandComboBox->currentIndex() ).toInt() );
211  mMinMaxWidget->setBands( myBands );
212  emit widgetChanged();
213 }
214 
215 void QgsMultiBandColorRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin )
216 {
217  Q_UNUSED( theOrigin );
218  QgsDebugMsg( QString( "theBandNo = %1 theMin = %2 theMax = %3" ).arg( theBandNo ).arg( theMin ).arg( theMax ) );
219 
220  QLineEdit *myMinLineEdit, *myMaxLineEdit;
221 
222  if ( mRedBandComboBox->itemData( mRedBandComboBox->currentIndex() ).toInt() == theBandNo )
223  {
224  myMinLineEdit = mRedMinLineEdit;
225  myMaxLineEdit = mRedMaxLineEdit;
226  }
227  else if ( mGreenBandComboBox->itemData( mGreenBandComboBox->currentIndex() ).toInt() == theBandNo )
228  {
229  myMinLineEdit = mGreenMinLineEdit;
230  myMaxLineEdit = mGreenMaxLineEdit;
231  }
232  else if ( mBlueBandComboBox->itemData( mBlueBandComboBox->currentIndex() ).toInt() == theBandNo )
233  {
234  myMinLineEdit = mBlueMinLineEdit;
235  myMaxLineEdit = mBlueMaxLineEdit;
236  }
237  else // should not happen
238  {
239  QgsDebugMsg( "Band not found" );
240  return;
241  }
242 
243  if ( qIsNaN( theMin ) )
244  {
245  myMinLineEdit->clear();
246  }
247  else
248  {
249  myMinLineEdit->setText( QString::number( theMin ) );
250  }
251 
252  if ( qIsNaN( theMax ) )
253  {
254  myMaxLineEdit->clear();
255  }
256  else
257  {
258  myMaxLineEdit->setText( QString::number( theMax ) );
259  }
260 }
261 
262 void QgsMultiBandColorRendererWidget::setMinMaxValue( const QgsContrastEnhancement* ce, QLineEdit* minEdit, QLineEdit* maxEdit )
263 {
264  if ( !minEdit || !maxEdit )
265  {
266  return;
267  }
268 
269  if ( !ce )
270  {
271  minEdit->clear();
272  maxEdit->clear();
273  return;
274  }
275 
276  minEdit->setText( QString::number( ce->minimumValue() ) );
277  maxEdit->setText( QString::number( ce->maximumValue() ) );
278 
279  // QgsMultiBandColorRenderer is using individual contrast enhancements for each
280  // band, but this widget GUI has one for all
281  mContrastEnhancementAlgorithmComboBox->setCurrentIndex( mContrastEnhancementAlgorithmComboBox->findData(
282  ( int )( ce->contrastEnhancementAlgorithm() ) ) );
283 }
284 
286 {
287  const QgsMultiBandColorRenderer* mbcr = dynamic_cast<const QgsMultiBandColorRenderer*>( r );
288  if ( mbcr )
289  {
290  mRedBandComboBox->setCurrentIndex( mRedBandComboBox->findData( mbcr->redBand() ) );
291  mGreenBandComboBox->setCurrentIndex( mGreenBandComboBox->findData( mbcr->greenBand() ) );
292  mBlueBandComboBox->setCurrentIndex( mBlueBandComboBox->findData( mbcr->blueBand() ) );
293 
294  setMinMaxValue( mbcr->redContrastEnhancement(), mRedMinLineEdit, mRedMaxLineEdit );
295  setMinMaxValue( mbcr->greenContrastEnhancement(), mGreenMinLineEdit, mGreenMaxLineEdit );
296  setMinMaxValue( mbcr->blueContrastEnhancement(), mBlueMinLineEdit, mBlueMaxLineEdit );
297  }
298  else
299  {
300  mRedBandComboBox->setCurrentIndex( mRedBandComboBox->findText( tr( "Red" ) ) );
301  mGreenBandComboBox->setCurrentIndex( mGreenBandComboBox->findText( tr( "Green" ) ) );
302  mBlueBandComboBox->setCurrentIndex( mBlueBandComboBox->findText( tr( "Blue" ) ) );
303  }
304 }
305 
307 {
308  switch ( index )
309  {
310  case 0:
311  return mRedMinLineEdit->text();
312  case 1:
313  return mGreenMinLineEdit->text();
314  case 2:
315  return mBlueMinLineEdit->text();
316  default:
317  break;
318  }
319  return QString();
320 }
321 
323 {
324  switch ( index )
325  {
326  case 0:
327  return mRedMaxLineEdit->text();
328  case 1:
329  return mGreenMaxLineEdit->text();
330  case 2:
331  return mBlueMaxLineEdit->text();
332  default:
333  break;
334  }
335  return QString();
336 }
337 
339 {
340  switch ( index )
341  {
342  case 0:
343  mRedMinLineEdit->setText( value );
344  break;
345  case 1:
346  mGreenMinLineEdit->setText( value );
347  break;
348  case 2:
349  mBlueMinLineEdit->setText( value );
350  break;
351  default:
352  break;
353  }
354 }
355 
357 {
358  switch ( index )
359  {
360  case 0:
361  mRedMaxLineEdit->setText( value );
362  break;
363  case 1:
364  mGreenMaxLineEdit->setText( value );
365  break;
366  case 2:
367  mBlueMaxLineEdit->setText( value );
368  break;
369  default:
370  break;
371  }
372 }
373 
375 {
376  switch ( index )
377  {
378  case 0:
379  return mRedBandComboBox->currentIndex();
380  case 1:
381  return mGreenBandComboBox->currentIndex();
382  case 2:
383  return mBlueBandComboBox->currentIndex();
384  default:
385  break;
386  }
387  return -1;
388 }
QLayout * layout() const
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:35
void loadMinMax(int theBandNo, double theMin, double theMax, int theOrigin)
void setContentsMargins(int left, int top, int right, int bottom)
void setupUi(QWidget *widget)
void setMapCanvas(QgsMapCanvas *canvas) override
Sets the map canvas associated with the widget.
const QgsContrastEnhancement * blueContrastEnhancement() const
QgsMultiBandColorRendererWidget(QgsRasterLayer *layer, const QgsRectangle &extent=QgsRectangle())
void clear()
void setText(const QString &)
#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)
double minimumValue() const
Return the minimum value for the contrast enhancement range.
QgsRasterRenderer * renderer() const
QString tr(const char *sourceText, const char *disambiguation, int n)
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:109
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
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QString number(int n, int base)
void append(const T &value)
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.
virtual QGis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.
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.
DataType
Raster data types.
Definition: qgis.h:133
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.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
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.