QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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
19
20#include "qgsdoublevalidator.h"
23#include "qgsrasterlayer.h"
25
26#include "moc_qgsmultibandcolorrendererwidget.cpp"
27
29 : QgsRasterRendererWidget( layer, extent )
30{
31 setupUi( this );
32 connect( mRedMinLineEdit, &QLineEdit::textChanged, this, &QgsMultiBandColorRendererWidget::mRedMinLineEdit_textChanged );
33 connect( mRedMaxLineEdit, &QLineEdit::textChanged, this, &QgsMultiBandColorRendererWidget::mRedMaxLineEdit_textChanged );
34 connect( mGreenMinLineEdit, &QLineEdit::textChanged, this, &QgsMultiBandColorRendererWidget::mGreenMinLineEdit_textChanged );
35 connect( mGreenMaxLineEdit, &QLineEdit::textChanged, this, &QgsMultiBandColorRendererWidget::mGreenMaxLineEdit_textChanged );
36 connect( mBlueMinLineEdit, &QLineEdit::textChanged, this, &QgsMultiBandColorRendererWidget::mBlueMinLineEdit_textChanged );
37 connect( mBlueMaxLineEdit, &QLineEdit::textChanged, this, &QgsMultiBandColorRendererWidget::mBlueMaxLineEdit_textChanged );
38 createValidators();
39
40 if ( mRasterLayer )
41 {
42 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
43 if ( !provider )
44 {
45 return;
46 }
47
48 mMinMaxWidget = new QgsRasterMinMaxWidget( layer, this );
49 mMinMaxWidget->setExtent( extent );
50 mMinMaxWidget->setMapCanvas( mCanvas );
51 QHBoxLayout *layout = new QHBoxLayout();
52 layout->setContentsMargins( 0, 0, 0, 0 );
53 mMinMaxContainerWidget->setLayout( layout );
54 layout->addWidget( mMinMaxWidget );
55
58
59 connect( mRedBandComboBox, &QgsRasterBandComboBox::bandChanged, this, &QgsMultiBandColorRendererWidget::onBandChanged );
60 connect( mGreenBandComboBox, &QgsRasterBandComboBox::bandChanged, this, &QgsMultiBandColorRendererWidget::onBandChanged );
61 connect( mBlueBandComboBox, &QgsRasterBandComboBox::bandChanged, this, &QgsMultiBandColorRendererWidget::onBandChanged );
62
63 mRedBandComboBox->setShowNotSetOption( true );
64 mGreenBandComboBox->setShowNotSetOption( true );
65 mBlueBandComboBox->setShowNotSetOption( true );
66 mRedBandComboBox->setLayer( mRasterLayer );
67 mGreenBandComboBox->setLayer( mRasterLayer );
68 mBlueBandComboBox->setLayer( mRasterLayer );
69
70 //contrast enhancement algorithms
71 mContrastEnhancementAlgorithmComboBox->addItem( tr( "No Enhancement" ), QgsContrastEnhancement::NoEnhancement );
72 mContrastEnhancementAlgorithmComboBox->addItem( tr( "Stretch to MinMax" ), QgsContrastEnhancement::StretchToMinimumMaximum );
73 mContrastEnhancementAlgorithmComboBox->addItem( tr( "Stretch and Clip to MinMax" ), QgsContrastEnhancement::StretchAndClipToMinimumMaximum );
74 mContrastEnhancementAlgorithmComboBox->addItem( tr( "Clip to MinMax" ), QgsContrastEnhancement::ClipToMinimumMaximum );
75
76 setFromRenderer( mRasterLayer->renderer() );
77 onBandChanged( 0 ); // reset mMinMaxWidget bands
78
79 connect( mContrastEnhancementAlgorithmComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterRendererWidget::widgetChanged );
80 }
81}
82
84{
85 if ( !mRasterLayer )
86 {
87 return nullptr;
88 }
89 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
90 if ( !provider )
91 {
92 return nullptr;
93 }
94
95 const int redBand = mRedBandComboBox->currentBand();
96 const int greenBand = mGreenBandComboBox->currentBand();
97 const int blueBand = mBlueBandComboBox->currentBand();
98
99 QgsMultiBandColorRenderer *r = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand );
100 setCustomMinMaxValues( r, provider, redBand, greenBand, blueBand );
101
102 r->setMinMaxOrigin( mMinMaxWidget->minMaxOrigin() );
103
104 return r;
105}
106
108{
109 mMinMaxWidget->doComputations();
110}
111
113{
115 mMinMaxWidget->setMapCanvas( canvas );
116}
117
118void QgsMultiBandColorRendererWidget::createValidators()
119{
120 mRedMinLineEdit->setValidator( new QgsDoubleValidator( mRedMinLineEdit ) );
121 mRedMaxLineEdit->setValidator( new QgsDoubleValidator( mRedMinLineEdit ) );
122 mGreenMinLineEdit->setValidator( new QgsDoubleValidator( mGreenMinLineEdit ) );
123 mGreenMaxLineEdit->setValidator( new QgsDoubleValidator( mGreenMinLineEdit ) );
124 mBlueMinLineEdit->setValidator( new QgsDoubleValidator( mBlueMinLineEdit ) );
125 mBlueMaxLineEdit->setValidator( new QgsDoubleValidator( mBlueMinLineEdit ) );
126}
127
128void QgsMultiBandColorRendererWidget::setCustomMinMaxValues( QgsMultiBandColorRenderer *r, const QgsRasterDataProvider *provider, int redBand, int greenBand, int blueBand )
129{
130 if ( !r || !provider )
131 {
132 return;
133 }
134
135 QgsContrastEnhancement *redEnhancement = nullptr;
136 QgsContrastEnhancement *greenEnhancement = nullptr;
137 QgsContrastEnhancement *blueEnhancement = nullptr;
138
139 bool redMinOk, redMaxOk;
140 const double redMin = QgsDoubleValidator::toDouble( mRedMinLineEdit->text(), &redMinOk );
141 const double redMax = QgsDoubleValidator::toDouble( mRedMaxLineEdit->text(), &redMaxOk );
142 if ( redMinOk && redMaxOk && redBand != -1 )
143 {
144 redEnhancement = new QgsContrastEnhancement( ( Qgis::DataType )(
145 provider->dataType( redBand )
146 ) );
147 redEnhancement->setMinimumValue( redMin );
148 redEnhancement->setMaximumValue( redMax );
149 }
150
151 bool greenMinOk, greenMaxOk;
152 const double greenMin = QgsDoubleValidator::toDouble( mGreenMinLineEdit->text(), &greenMinOk );
153 const double greenMax = QgsDoubleValidator::toDouble( mGreenMaxLineEdit->text(), &greenMaxOk );
154 if ( greenMinOk && greenMaxOk && greenBand != -1 )
155 {
156 greenEnhancement = new QgsContrastEnhancement( ( Qgis::DataType )(
157 provider->dataType( greenBand )
158 ) );
159 greenEnhancement->setMinimumValue( greenMin );
160 greenEnhancement->setMaximumValue( greenMax );
161 }
162
163 bool blueMinOk, blueMaxOk;
164 const double blueMin = QgsDoubleValidator::toDouble( mBlueMinLineEdit->text(), &blueMinOk );
165 const double blueMax = QgsDoubleValidator::toDouble( mBlueMaxLineEdit->text(), &blueMaxOk );
166 if ( blueMinOk && blueMaxOk && blueBand != -1 )
167 {
168 blueEnhancement = new QgsContrastEnhancement( ( Qgis::DataType )(
169 provider->dataType( blueBand )
170 ) );
171 blueEnhancement->setMinimumValue( blueMin );
172 blueEnhancement->setMaximumValue( blueMax );
173 }
174
175 if ( redEnhancement )
176 {
177 redEnhancement->setContrastEnhancementAlgorithm( ( QgsContrastEnhancement::ContrastEnhancementAlgorithm )( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) );
178 }
179 if ( greenEnhancement )
180 {
181 greenEnhancement->setContrastEnhancementAlgorithm( ( QgsContrastEnhancement::ContrastEnhancementAlgorithm )( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) );
182 }
183 if ( blueEnhancement )
184 {
185 blueEnhancement->setContrastEnhancementAlgorithm( ( QgsContrastEnhancement::ContrastEnhancementAlgorithm )( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) );
186 }
187 r->setRedContrastEnhancement( redEnhancement );
188 r->setGreenContrastEnhancement( greenEnhancement );
189 r->setBlueContrastEnhancement( blueEnhancement );
190}
191
192void QgsMultiBandColorRendererWidget::onBandChanged( int index )
193{
194 Q_UNUSED( index )
195
196 QList<int> myBands;
197 myBands.append( mRedBandComboBox->currentBand() );
198 myBands.append( mGreenBandComboBox->currentBand() );
199 myBands.append( mBlueBandComboBox->currentBand() );
200 mMinMaxWidget->setBands( myBands );
201 emit widgetChanged();
202}
203
204void QgsMultiBandColorRendererWidget::mRedMinLineEdit_textChanged( const QString & )
205{
206 minMaxModified();
207}
208
209void QgsMultiBandColorRendererWidget::mRedMaxLineEdit_textChanged( const QString & )
210{
211 minMaxModified();
212}
213
214void QgsMultiBandColorRendererWidget::mGreenMinLineEdit_textChanged( const QString & )
215{
216 minMaxModified();
217}
218
219void QgsMultiBandColorRendererWidget::mGreenMaxLineEdit_textChanged( const QString & )
220{
221 minMaxModified();
222}
223
224void QgsMultiBandColorRendererWidget::mBlueMinLineEdit_textChanged( const QString & )
225{
226 minMaxModified();
227}
228
229void QgsMultiBandColorRendererWidget::mBlueMaxLineEdit_textChanged( const QString & )
230{
231 minMaxModified();
232}
233
234void QgsMultiBandColorRendererWidget::minMaxModified()
235{
236 if ( !mDisableMinMaxWidgetRefresh )
237 {
238 if ( ( QgsContrastEnhancement::ContrastEnhancementAlgorithm )( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) == QgsContrastEnhancement::NoEnhancement )
239 {
240 mContrastEnhancementAlgorithmComboBox->setCurrentIndex(
241 mContrastEnhancementAlgorithmComboBox->findData( ( int ) QgsContrastEnhancement::StretchToMinimumMaximum )
242 );
243 }
244 mMinMaxWidget->userHasSetManualMinMaxValues();
245 emit widgetChanged();
246 }
247}
248
249void QgsMultiBandColorRendererWidget::loadMinMax( int bandNo, double min, double max )
250{
251 QgsDebugMsgLevel( QStringLiteral( "theBandNo = %1 min = %2 max = %3" ).arg( bandNo ).arg( min ).arg( max ), 2 );
252
253 QLineEdit *myMinLineEdit, *myMaxLineEdit;
254
255 if ( mRedBandComboBox->currentBand() == bandNo )
256 {
257 myMinLineEdit = mRedMinLineEdit;
258 myMaxLineEdit = mRedMaxLineEdit;
259 }
260 else if ( mGreenBandComboBox->currentBand() == bandNo )
261 {
262 myMinLineEdit = mGreenMinLineEdit;
263 myMaxLineEdit = mGreenMaxLineEdit;
264 }
265 else if ( mBlueBandComboBox->currentBand() == bandNo )
266 {
267 myMinLineEdit = mBlueMinLineEdit;
268 myMaxLineEdit = mBlueMaxLineEdit;
269 }
270 else // should not happen
271 {
272 QgsDebugError( QStringLiteral( "Band not found" ) );
273 return;
274 }
275
276 mDisableMinMaxWidgetRefresh = true;
277 if ( std::isnan( min ) )
278 {
279 myMinLineEdit->clear();
280 }
281 else
282 {
283 myMinLineEdit->setText( QLocale().toString( min ) );
284 }
285
286 if ( std::isnan( max ) )
287 {
288 myMaxLineEdit->clear();
289 }
290 else
291 {
292 myMaxLineEdit->setText( QLocale().toString( max ) );
293 }
294 mDisableMinMaxWidgetRefresh = false;
295}
296
297void QgsMultiBandColorRendererWidget::setMinMaxValue( const QgsContrastEnhancement *ce, QLineEdit *minEdit, QLineEdit *maxEdit )
298{
299 if ( !minEdit || !maxEdit )
300 {
301 return;
302 }
303
304 if ( !ce )
305 {
306 minEdit->clear();
307 maxEdit->clear();
308 return;
309 }
310
311 minEdit->setText( QLocale().toString( ce->minimumValue() ) );
312 maxEdit->setText( QLocale().toString( ce->maximumValue() ) );
313
314 // QgsMultiBandColorRenderer is using individual contrast enhancements for each
315 // band, but this widget GUI has one for all
316 mContrastEnhancementAlgorithmComboBox->setCurrentIndex( mContrastEnhancementAlgorithmComboBox->findData(
317 ( int ) ( ce->contrastEnhancementAlgorithm() )
318 ) );
319}
320
322{
323 const QgsMultiBandColorRenderer *mbcr = dynamic_cast<const QgsMultiBandColorRenderer *>( r );
324 if ( mbcr )
325 {
326 mRedBandComboBox->setBand( mbcr->redBand() );
327 mGreenBandComboBox->setBand( mbcr->greenBand() );
328 mBlueBandComboBox->setBand( mbcr->blueBand() );
329
330 mDisableMinMaxWidgetRefresh = true;
331 setMinMaxValue( mbcr->redContrastEnhancement(), mRedMinLineEdit, mRedMaxLineEdit );
332 setMinMaxValue( mbcr->greenContrastEnhancement(), mGreenMinLineEdit, mGreenMaxLineEdit );
333 setMinMaxValue( mbcr->blueContrastEnhancement(), mBlueMinLineEdit, mBlueMaxLineEdit );
334 mDisableMinMaxWidgetRefresh = false;
335
336 mMinMaxWidget->setFromMinMaxOrigin( mbcr->minMaxOrigin() );
337 }
338 else
339 {
340 if ( mRedBandComboBox->findText( tr( "Red" ) ) > -1 && mRedBandComboBox->findText( tr( "Green" ) ) > -1 && mRedBandComboBox->findText( tr( "Blue" ) ) > -1 )
341 {
342 mRedBandComboBox->setCurrentIndex( mRedBandComboBox->findText( tr( "Red" ) ) );
343 mGreenBandComboBox->setCurrentIndex( mGreenBandComboBox->findText( tr( "Green" ) ) );
344 mBlueBandComboBox->setCurrentIndex( mBlueBandComboBox->findText( tr( "Blue" ) ) );
345 }
346 else
347 {
348 mRedBandComboBox->setCurrentIndex( mRedBandComboBox->count() > 1 ? 1 : 0 );
349 mGreenBandComboBox->setCurrentIndex( mRedBandComboBox->count() > 2 ? 2 : 0 );
350 mBlueBandComboBox->setCurrentIndex( mRedBandComboBox->count() > 3 ? 3 : 0 );
351 }
352 }
353}
354
356{
357 switch ( index )
358 {
359 case 0:
360 return mRedMinLineEdit->text();
361 case 1:
362 return mGreenMinLineEdit->text();
363 case 2:
364 return mBlueMinLineEdit->text();
365 default:
366 break;
367 }
368 return QString();
369}
370
372{
373 switch ( index )
374 {
375 case 0:
376 return mRedMaxLineEdit->text();
377 case 1:
378 return mGreenMaxLineEdit->text();
379 case 2:
380 return mBlueMaxLineEdit->text();
381 default:
382 break;
383 }
384 return QString();
385}
386
387void QgsMultiBandColorRendererWidget::setMin( const QString &value, int index )
388{
389 mDisableMinMaxWidgetRefresh = true;
390 switch ( index )
391 {
392 case 0:
393 mRedMinLineEdit->setText( value );
394 break;
395 case 1:
396 mGreenMinLineEdit->setText( value );
397 break;
398 case 2:
399 mBlueMinLineEdit->setText( value );
400 break;
401 default:
402 break;
403 }
404 mDisableMinMaxWidgetRefresh = false;
405}
406
407void QgsMultiBandColorRendererWidget::setMax( const QString &value, int index )
408{
409 mDisableMinMaxWidgetRefresh = true;
410 switch ( index )
411 {
412 case 0:
413 mRedMaxLineEdit->setText( value );
414 break;
415 case 1:
416 mGreenMaxLineEdit->setText( value );
417 break;
418 case 2:
419 mBlueMaxLineEdit->setText( value );
420 break;
421 default:
422 break;
423 }
424 mDisableMinMaxWidgetRefresh = false;
425}
426
428{
429 switch ( index )
430 {
431 case 0:
432 return mRedBandComboBox->currentBand();
433 case 1:
434 return mGreenBandComboBox->currentBand();
435 case 2:
436 return mBlueBandComboBox->currentBand();
437 default:
438 break;
439 }
440 return -1;
441}
442
447
449{
450 mDisableMinMaxWidgetRefresh = true;
451 mContrastEnhancementAlgorithmComboBox->setCurrentIndex( mContrastEnhancementAlgorithmComboBox->findData( static_cast<int>( algorithm ) ) );
452 mDisableMinMaxWidgetRefresh = false;
453}
DataType
Raster data types.
Definition qgis.h:372
Handles contrast enhancement and clipping.
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.
A custom validator which allows entry of doubles in a locale-tolerant way.
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.
void loadMinMax(int bandNo, double min, double max)
called when new min/max values are loaded
QgsMultiBandColorRendererWidget(QgsRasterLayer *layer, const QgsRectangle &extent=QgsRectangle())
Constructor for QgsMultiBandColorRendererWidget.
void doComputations() override
Load programmatically with current values.
void setContrastEnhancementAlgorithm(QgsContrastEnhancement::ContrastEnhancementAlgorithm algorithm) override
Sets the contrast enhancement algorithm to be used by the raster renderer.
QgsContrastEnhancement::ContrastEnhancementAlgorithm contrastEnhancementAlgorithm() const override
Returns the contrast enhancement algorithm to be used by the raster renderer.
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 * greenContrastEnhancement() const
Returns the contrast enhancement to use for the green channel.
int blueBand() const
Returns the band number for the blue 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 * redContrastEnhancement() const
Returns the contrast enhancement to use for the red channel.
int redBand() const
Returns the band number for the red channel.
int greenBand() const
Returns the band number 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.
A widget for configuring how the minimum and maximum value of a raster layer is determined.
void load(int bandNo, double min, double max)
signal emitted when new min/max values are computed from statistics.
void widgetChanged()
Emitted when something on the widget has changed.
virtual void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
QgsMapCanvas * mCanvas
Associated map canvas.
QgsRasterRendererWidget(QgsRasterLayer *layer, const QgsRectangle &extent)
Constructor for QgsRasterRendererWidget.
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.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:61
#define QgsDebugError(str)
Definition qgslogger.h:57