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