QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
qgspointcloudrgbrendererwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspointcloudrgbrendererwidget.cpp
3 ---------------------
4 begin : November 2020
5 copyright : (C) 2020 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
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
21#include "qgsdoublevalidator.h"
22#include "qgspointcloudlayer.h"
24
25#include "moc_qgspointcloudrgbrendererwidget.cpp"
26
28
29QgsPointCloudRgbRendererWidget::QgsPointCloudRgbRendererWidget( QgsPointCloudLayer *layer, QgsStyle *style )
30 : QgsPointCloudRendererWidget( layer, style )
31{
32 setupUi( this );
33 connect( mRedMinLineEdit, &QLineEdit::textChanged, this, &QgsPointCloudRgbRendererWidget::mRedMinLineEdit_textChanged );
34 connect( mRedMaxLineEdit, &QLineEdit::textChanged, this, &QgsPointCloudRgbRendererWidget::mRedMaxLineEdit_textChanged );
35 connect( mGreenMinLineEdit, &QLineEdit::textChanged, this, &QgsPointCloudRgbRendererWidget::mGreenMinLineEdit_textChanged );
36 connect( mGreenMaxLineEdit, &QLineEdit::textChanged, this, &QgsPointCloudRgbRendererWidget::mGreenMaxLineEdit_textChanged );
37 connect( mBlueMinLineEdit, &QLineEdit::textChanged, this, &QgsPointCloudRgbRendererWidget::mBlueMinLineEdit_textChanged );
38 connect( mBlueMaxLineEdit, &QLineEdit::textChanged, this, &QgsPointCloudRgbRendererWidget::mBlueMaxLineEdit_textChanged );
39 createValidators();
40
41 mRedAttributeComboBox->setAllowEmptyAttributeName( true );
42 mGreenAttributeComboBox->setAllowEmptyAttributeName( true );
43 mBlueAttributeComboBox->setAllowEmptyAttributeName( true );
44
45 //contrast enhancement algorithms
46 mContrastEnhancementAlgorithmComboBox->addItem( tr( "No Enhancement" ), QgsContrastEnhancement::NoEnhancement );
47 mContrastEnhancementAlgorithmComboBox->addItem( tr( "Stretch to MinMax" ), QgsContrastEnhancement::StretchToMinimumMaximum );
48 mContrastEnhancementAlgorithmComboBox->addItem( tr( "Stretch and Clip to MinMax" ), QgsContrastEnhancement::StretchAndClipToMinimumMaximum );
49 mContrastEnhancementAlgorithmComboBox->addItem( tr( "Clip to MinMax" ), QgsContrastEnhancement::ClipToMinimumMaximum );
50
51 if ( layer )
52 {
53 mRedAttributeComboBox->setLayer( layer );
54 mGreenAttributeComboBox->setLayer( layer );
55 mBlueAttributeComboBox->setLayer( layer );
56
57 setFromRenderer( layer->renderer() );
58 }
59
60 connect( mRedAttributeComboBox, &QgsPointCloudAttributeComboBox::attributeChanged, this, &QgsPointCloudRgbRendererWidget::redAttributeChanged );
61 connect( mGreenAttributeComboBox, &QgsPointCloudAttributeComboBox::attributeChanged, this, &QgsPointCloudRgbRendererWidget::greenAttributeChanged );
62 connect( mBlueAttributeComboBox, &QgsPointCloudAttributeComboBox::attributeChanged, this, &QgsPointCloudRgbRendererWidget::blueAttributeChanged );
63 connect( mContrastEnhancementAlgorithmComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointCloudRgbRendererWidget::emitWidgetChanged );
64
65 if ( layer )
66 {
67 // set nice initial values
68 mBlockChangedSignal = true;
69 redAttributeChanged();
70 greenAttributeChanged();
71 blueAttributeChanged();
72 mBlockChangedSignal = false;
73 minMaxModified();
74 }
75}
76
77QgsPointCloudRendererWidget *QgsPointCloudRgbRendererWidget::create( QgsPointCloudLayer *layer, QgsStyle *style, QgsPointCloudRenderer * )
78{
79 return new QgsPointCloudRgbRendererWidget( layer, style );
80}
81
82QgsPointCloudRenderer *QgsPointCloudRgbRendererWidget::renderer()
83{
84 if ( !mLayer )
85 {
86 return nullptr;
87 }
88
89 auto renderer = std::make_unique<QgsPointCloudRgbRenderer>();
90 renderer->setRedAttribute( mRedAttributeComboBox->currentAttribute() );
91 renderer->setGreenAttribute( mGreenAttributeComboBox->currentAttribute() );
92 renderer->setBlueAttribute( mBlueAttributeComboBox->currentAttribute() );
93
94 setCustomMinMaxValues( renderer.get() );
95 return renderer.release();
96}
97
98void QgsPointCloudRgbRendererWidget::createValidators()
99{
100 mRedMinLineEdit->setValidator( new QgsDoubleValidator( mRedMinLineEdit ) );
101 mRedMaxLineEdit->setValidator( new QgsDoubleValidator( mRedMinLineEdit ) );
102 mGreenMinLineEdit->setValidator( new QgsDoubleValidator( mGreenMinLineEdit ) );
103 mGreenMaxLineEdit->setValidator( new QgsDoubleValidator( mGreenMinLineEdit ) );
104 mBlueMinLineEdit->setValidator( new QgsDoubleValidator( mBlueMinLineEdit ) );
105 mBlueMaxLineEdit->setValidator( new QgsDoubleValidator( mBlueMinLineEdit ) );
106}
107
108void QgsPointCloudRgbRendererWidget::setCustomMinMaxValues( QgsPointCloudRgbRenderer *r )
109{
110 if ( !r )
111 {
112 return;
113 }
114
115 if ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() == QgsContrastEnhancement::NoEnhancement )
116 {
117 r->setRedContrastEnhancement( nullptr );
118 r->setGreenContrastEnhancement( nullptr );
119 r->setBlueContrastEnhancement( nullptr );
120 return;
121 }
122
123 QgsContrastEnhancement *redEnhancement = nullptr;
124 QgsContrastEnhancement *greenEnhancement = nullptr;
125 QgsContrastEnhancement *blueEnhancement = nullptr;
126
127 bool redMinOk, redMaxOk;
128 const double redMin = QgsDoubleValidator::toDouble( mRedMinLineEdit->text(), &redMinOk );
129 const double redMax = QgsDoubleValidator::toDouble( mRedMaxLineEdit->text(), &redMaxOk );
130 if ( redMinOk && redMaxOk && !mRedAttributeComboBox->currentAttribute().isEmpty() )
131 {
133 redEnhancement->setMinimumValue( redMin );
134 redEnhancement->setMaximumValue( redMax );
135 }
136
137 bool greenMinOk, greenMaxOk;
138 const double greenMin = QgsDoubleValidator::toDouble( mGreenMinLineEdit->text(), &greenMinOk );
139 const double greenMax = QgsDoubleValidator::toDouble( mGreenMaxLineEdit->text(), &greenMaxOk );
140 if ( greenMinOk && greenMaxOk && !mGreenAttributeComboBox->currentAttribute().isEmpty() )
141 {
143 greenEnhancement->setMinimumValue( greenMin );
144 greenEnhancement->setMaximumValue( greenMax );
145 }
146
147 bool blueMinOk, blueMaxOk;
148 const double blueMin = QgsDoubleValidator::toDouble( mBlueMinLineEdit->text(), &blueMinOk );
149 const double blueMax = QgsDoubleValidator::toDouble( mBlueMaxLineEdit->text(), &blueMaxOk );
150 if ( blueMinOk && blueMaxOk && !mBlueAttributeComboBox->currentAttribute().isEmpty() )
151 {
153 blueEnhancement->setMinimumValue( blueMin );
154 blueEnhancement->setMaximumValue( blueMax );
155 }
156
157 if ( redEnhancement )
158 {
160 ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() )
161 ) );
162 }
163 if ( greenEnhancement )
164 {
166 ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() )
167 ) );
168 }
169 if ( blueEnhancement )
170 {
172 ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() )
173 ) );
174 }
175 r->setRedContrastEnhancement( redEnhancement );
176 r->setGreenContrastEnhancement( greenEnhancement );
177 r->setBlueContrastEnhancement( blueEnhancement );
178}
179
180void QgsPointCloudRgbRendererWidget::mRedMinLineEdit_textChanged( const QString & )
181{
182 minMaxModified();
183}
184
185void QgsPointCloudRgbRendererWidget::mRedMaxLineEdit_textChanged( const QString & )
186{
187 minMaxModified();
188}
189
190void QgsPointCloudRgbRendererWidget::mGreenMinLineEdit_textChanged( const QString & )
191{
192 minMaxModified();
193}
194
195void QgsPointCloudRgbRendererWidget::mGreenMaxLineEdit_textChanged( const QString & )
196{
197 minMaxModified();
198}
199
200void QgsPointCloudRgbRendererWidget::mBlueMinLineEdit_textChanged( const QString & )
201{
202 minMaxModified();
203}
204
205void QgsPointCloudRgbRendererWidget::mBlueMaxLineEdit_textChanged( const QString & )
206{
207 minMaxModified();
208}
209
210void QgsPointCloudRgbRendererWidget::emitWidgetChanged()
211{
212 if ( !mBlockChangedSignal )
213 emit widgetChanged();
214}
215
216void QgsPointCloudRgbRendererWidget::redAttributeChanged()
217{
218 if ( mLayer && mLayer->dataProvider() )
219 {
220 const QgsPointCloudStatistics stats = mLayer->statistics();
221 const double max = stats.maximum( mRedAttributeComboBox->currentAttribute() );
222 if ( !std::isnan( max ) )
223 {
224 mDisableMinMaxWidgetRefresh++;
225 mRedMinLineEdit->setText( QLocale().toString( 0 ) );
226
227 // try and guess suitable range from input max values -- we don't just take the provider max value directly here, but rather see if it's
228 // likely to be 8 bit or 16 bit color values
229 mRedMaxLineEdit->setText( QLocale().toString( max > 255 ? 65535 : 255 ) );
230 mDisableMinMaxWidgetRefresh--;
231 emitWidgetChanged();
232 }
233 }
234}
235
236void QgsPointCloudRgbRendererWidget::greenAttributeChanged()
237{
238 if ( mLayer && mLayer->dataProvider() )
239 {
240 const QgsPointCloudStatistics stats = mLayer->statistics();
241 const double max = stats.maximum( mGreenAttributeComboBox->currentAttribute() );
242 if ( !std::isnan( max ) )
243 {
244 mDisableMinMaxWidgetRefresh++;
245 mGreenMinLineEdit->setText( QLocale().toString( 0 ) );
246
247 // try and guess suitable range from input max values -- we don't just take the provider max value directly here, but rather see if it's
248 // likely to be 8 bit or 16 bit color values
249 mGreenMaxLineEdit->setText( QLocale().toString( max > 255 ? 65535 : 255 ) );
250 mDisableMinMaxWidgetRefresh--;
251 emitWidgetChanged();
252 }
253 }
254}
255
256void QgsPointCloudRgbRendererWidget::blueAttributeChanged()
257{
258 if ( mLayer && mLayer->dataProvider() )
259 {
260 const QgsPointCloudStatistics stats = mLayer->statistics();
261 const double max = stats.maximum( mBlueAttributeComboBox->currentAttribute() );
262 if ( !std::isnan( max ) )
263 {
264 mDisableMinMaxWidgetRefresh++;
265 mBlueMinLineEdit->setText( QLocale().toString( 0 ) );
266
267 // try and guess suitable range from input max values -- we don't just take the provider max value directly here, but rather see if it's
268 // likely to be 8 bit or 16 bit color values
269 mBlueMaxLineEdit->setText( QLocale().toString( max > 255 ? 65535 : 255 ) );
270 mDisableMinMaxWidgetRefresh--;
271 emitWidgetChanged();
272 }
273 }
274}
275
276void QgsPointCloudRgbRendererWidget::minMaxModified()
277{
278 if ( !mDisableMinMaxWidgetRefresh )
279 {
280 if ( ( QgsContrastEnhancement::ContrastEnhancementAlgorithm )( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) == QgsContrastEnhancement::NoEnhancement )
281 {
282 mContrastEnhancementAlgorithmComboBox->setCurrentIndex(
283 mContrastEnhancementAlgorithmComboBox->findData( ( int ) QgsContrastEnhancement::StretchToMinimumMaximum )
284 );
285 }
286 emitWidgetChanged();
287 }
288}
289
290void QgsPointCloudRgbRendererWidget::setMinMaxValue( const QgsContrastEnhancement *ce, QLineEdit *minEdit, QLineEdit *maxEdit )
291{
292 if ( !minEdit || !maxEdit )
293 {
294 return;
295 }
296
297 if ( !ce )
298 {
299 minEdit->clear();
300 maxEdit->clear();
301 return;
302 }
303
304 minEdit->setText( QLocale().toString( ce->minimumValue() ) );
305 maxEdit->setText( QLocale().toString( ce->maximumValue() ) );
306
307 // QgsMultiBandColorRenderer is using individual contrast enhancements for each
308 // band, but this widget GUI has one for all
309 mContrastEnhancementAlgorithmComboBox->setCurrentIndex( mContrastEnhancementAlgorithmComboBox->findData(
310 static_cast<int>( ce->contrastEnhancementAlgorithm() )
311 ) );
312}
313
314void QgsPointCloudRgbRendererWidget::setFromRenderer( const QgsPointCloudRenderer *r )
315{
316 mBlockChangedSignal = true;
317 const QgsPointCloudRgbRenderer *mbcr = dynamic_cast<const QgsPointCloudRgbRenderer *>( r );
318 if ( mbcr )
319 {
320 mRedAttributeComboBox->setAttribute( mbcr->redAttribute() );
321 mGreenAttributeComboBox->setAttribute( mbcr->greenAttribute() );
322 mBlueAttributeComboBox->setAttribute( mbcr->blueAttribute() );
323
324 mDisableMinMaxWidgetRefresh++;
325 setMinMaxValue( mbcr->redContrastEnhancement(), mRedMinLineEdit, mRedMaxLineEdit );
326 setMinMaxValue( mbcr->greenContrastEnhancement(), mGreenMinLineEdit, mGreenMaxLineEdit );
327 setMinMaxValue( mbcr->blueContrastEnhancement(), mBlueMinLineEdit, mBlueMaxLineEdit );
328 mDisableMinMaxWidgetRefresh--;
329 }
330 else
331 {
332 if ( mRedAttributeComboBox->findText( QStringLiteral( "Red" ) ) > -1 && mRedAttributeComboBox->findText( QStringLiteral( "Green" ) ) > -1 && mRedAttributeComboBox->findText( QStringLiteral( "Blue" ) ) > -1 )
333 {
334 mRedAttributeComboBox->setAttribute( QStringLiteral( "Red" ) );
335 mGreenAttributeComboBox->setAttribute( QStringLiteral( "Green" ) );
336 mBlueAttributeComboBox->setAttribute( QStringLiteral( "Blue" ) );
337 }
338 else
339 {
340 mRedAttributeComboBox->setCurrentIndex( mRedAttributeComboBox->count() > 1 ? 1 : 0 );
341 mGreenAttributeComboBox->setCurrentIndex( mGreenAttributeComboBox->count() > 2 ? 2 : 0 );
342 mBlueAttributeComboBox->setCurrentIndex( mBlueAttributeComboBox->count() > 3 ? 3 : 0 );
343 }
344 }
345 mBlockChangedSignal = false;
346}
347
@ UnknownDataType
Unknown or unspecified type.
Definition qgis.h:373
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.
void attributeChanged(const QString &name)
Emitted when the currently selected attribute changes.
Represents a map layer supporting display of point clouds.
QgsPointCloudRenderer * renderer()
Returns the 2D renderer for the point cloud.
Base class for point cloud 2D renderer settings widgets.
Abstract base class for 2d point cloud renderers.
An RGB renderer for 2d visualisation of point clouds using embedded red, green and blue attributes.
void setRedContrastEnhancement(QgsContrastEnhancement *enhancement)
Sets the contrast enhancement to use for the red channel.
QString redAttribute() const
Returns the attribute to use for the red channel.
QString greenAttribute() const
Returns the attribute to use for the green channel.
void setBlueContrastEnhancement(QgsContrastEnhancement *enhancement)
Sets the contrast enhancement to use for the blue channel.
const QgsContrastEnhancement * greenContrastEnhancement() const
Returns the contrast enhancement to use for the green channel.
QString blueAttribute() const
Returns the attribute to use for the blue channel.
void setGreenContrastEnhancement(QgsContrastEnhancement *enhancement)
Sets the contrast enhancement to use for the green channel.
const QgsContrastEnhancement * blueContrastEnhancement() const
Returns the contrast enhancement to use for the blue channel.
const QgsContrastEnhancement * redContrastEnhancement() const
Returns the contrast enhancement to use for the red channel.
Used to store statistics of a point cloud dataset.
double maximum(const QString &attribute) const
Returns the maximum value for the attribute attribute If no matching statistic is available then NaN ...
A database of saved style entities, including symbols, color ramps, text formats and others.
Definition qgsstyle.h:88