QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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 #include "qgscontrastenhancement.h"
20 #include "qgspointcloudlayer.h"
22 #include "qgsdoublevalidator.h"
23 
25 
26 QgsPointCloudRgbRendererWidget::QgsPointCloudRgbRendererWidget( QgsPointCloudLayer *layer, QgsStyle *style )
27  : QgsPointCloudRendererWidget( layer, style )
28 {
29  setupUi( this );
30  connect( mRedMinLineEdit, &QLineEdit::textChanged, this, &QgsPointCloudRgbRendererWidget::mRedMinLineEdit_textChanged );
31  connect( mRedMaxLineEdit, &QLineEdit::textChanged, this, &QgsPointCloudRgbRendererWidget::mRedMaxLineEdit_textChanged );
32  connect( mGreenMinLineEdit, &QLineEdit::textChanged, this, &QgsPointCloudRgbRendererWidget::mGreenMinLineEdit_textChanged );
33  connect( mGreenMaxLineEdit, &QLineEdit::textChanged, this, &QgsPointCloudRgbRendererWidget::mGreenMaxLineEdit_textChanged );
34  connect( mBlueMinLineEdit, &QLineEdit::textChanged, this, &QgsPointCloudRgbRendererWidget::mBlueMinLineEdit_textChanged );
35  connect( mBlueMaxLineEdit, &QLineEdit::textChanged, this, &QgsPointCloudRgbRendererWidget::mBlueMaxLineEdit_textChanged );
36  createValidators();
37 
38  mRedAttributeComboBox->setAllowEmptyAttributeName( true );
39  mGreenAttributeComboBox->setAllowEmptyAttributeName( true );
40  mBlueAttributeComboBox->setAllowEmptyAttributeName( true );
41 
42  //contrast enhancement algorithms
43  mContrastEnhancementAlgorithmComboBox->addItem( tr( "No Enhancement" ), QgsContrastEnhancement::NoEnhancement );
44  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Stretch to MinMax" ), QgsContrastEnhancement::StretchToMinimumMaximum );
45  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Stretch and Clip to MinMax" ), QgsContrastEnhancement::StretchAndClipToMinimumMaximum );
46  mContrastEnhancementAlgorithmComboBox->addItem( tr( "Clip to MinMax" ), QgsContrastEnhancement::ClipToMinimumMaximum );
47 
48  if ( layer )
49  {
50  mRedAttributeComboBox->setLayer( layer );
51  mGreenAttributeComboBox->setLayer( layer );
52  mBlueAttributeComboBox->setLayer( layer );
53 
54  setFromRenderer( layer->renderer() );
55  }
56 
57  connect( mRedAttributeComboBox, &QgsPointCloudAttributeComboBox::attributeChanged,
58  this, &QgsPointCloudRgbRendererWidget::redAttributeChanged );
59  connect( mGreenAttributeComboBox, &QgsPointCloudAttributeComboBox::attributeChanged,
60  this, &QgsPointCloudRgbRendererWidget::greenAttributeChanged );
61  connect( mBlueAttributeComboBox, &QgsPointCloudAttributeComboBox::attributeChanged,
62  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 
77 QgsPointCloudRendererWidget *QgsPointCloudRgbRendererWidget::create( QgsPointCloudLayer *layer, QgsStyle *style, QgsPointCloudRenderer * )
78 {
79  return new QgsPointCloudRgbRendererWidget( layer, style );
80 }
81 
82 QgsPointCloudRenderer *QgsPointCloudRgbRendererWidget::renderer()
83 {
84  if ( !mLayer )
85  {
86  return nullptr;
87  }
88 
89  std::unique_ptr< QgsPointCloudRgbRenderer > 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 
98 void 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 
108 void QgsPointCloudRgbRendererWidget::setCustomMinMaxValues( QgsPointCloudRgbRenderer *r )
109 {
110  if ( !r )
111  {
112  return;
113  }
114 
115  if ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ==
117  {
118  r->setRedContrastEnhancement( nullptr );
119  r->setGreenContrastEnhancement( nullptr );
120  r->setBlueContrastEnhancement( nullptr );
121  return;
122  }
123 
124  QgsContrastEnhancement *redEnhancement = nullptr;
125  QgsContrastEnhancement *greenEnhancement = nullptr;
126  QgsContrastEnhancement *blueEnhancement = nullptr;
127 
128  bool redMinOk, redMaxOk;
129  const double redMin = QgsDoubleValidator::toDouble( mRedMinLineEdit->text(), &redMinOk );
130  const double redMax = QgsDoubleValidator::toDouble( mRedMaxLineEdit->text(), &redMaxOk );
131  if ( redMinOk && redMaxOk && !mRedAttributeComboBox->currentAttribute().isEmpty() )
132  {
134  redEnhancement->setMinimumValue( redMin );
135  redEnhancement->setMaximumValue( redMax );
136  }
137 
138  bool greenMinOk, greenMaxOk;
139  const double greenMin = QgsDoubleValidator::toDouble( mGreenMinLineEdit->text(), &greenMinOk );
140  const double greenMax = QgsDoubleValidator::toDouble( mGreenMaxLineEdit->text(), &greenMaxOk );
141  if ( greenMinOk && greenMaxOk && !mGreenAttributeComboBox->currentAttribute().isEmpty() )
142  {
144  greenEnhancement->setMinimumValue( greenMin );
145  greenEnhancement->setMaximumValue( greenMax );
146  }
147 
148  bool blueMinOk, blueMaxOk;
149  const double blueMin = QgsDoubleValidator::toDouble( mBlueMinLineEdit->text(), &blueMinOk );
150  const double blueMax = QgsDoubleValidator::toDouble( mBlueMaxLineEdit->text(), &blueMaxOk );
151  if ( blueMinOk && blueMaxOk && !mBlueAttributeComboBox->currentAttribute().isEmpty() )
152  {
154  blueEnhancement->setMinimumValue( blueMin );
155  blueEnhancement->setMaximumValue( blueMax );
156  }
157 
158  if ( redEnhancement )
159  {
161  ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) ) );
162  }
163  if ( greenEnhancement )
164  {
166  ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) ) );
167  }
168  if ( blueEnhancement )
169  {
171  ( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) ) );
172  }
173  r->setRedContrastEnhancement( redEnhancement );
174  r->setGreenContrastEnhancement( greenEnhancement );
175  r->setBlueContrastEnhancement( blueEnhancement );
176 }
177 
178 void QgsPointCloudRgbRendererWidget::mRedMinLineEdit_textChanged( const QString & )
179 {
180  minMaxModified();
181 }
182 
183 void QgsPointCloudRgbRendererWidget::mRedMaxLineEdit_textChanged( const QString & )
184 {
185  minMaxModified();
186 }
187 
188 void QgsPointCloudRgbRendererWidget::mGreenMinLineEdit_textChanged( const QString & )
189 {
190  minMaxModified();
191 }
192 
193 void QgsPointCloudRgbRendererWidget::mGreenMaxLineEdit_textChanged( const QString & )
194 {
195  minMaxModified();
196 }
197 
198 void QgsPointCloudRgbRendererWidget::mBlueMinLineEdit_textChanged( const QString & )
199 {
200  minMaxModified();
201 }
202 
203 void QgsPointCloudRgbRendererWidget::mBlueMaxLineEdit_textChanged( const QString & )
204 {
205  minMaxModified();
206 }
207 
208 void QgsPointCloudRgbRendererWidget::emitWidgetChanged()
209 {
210  if ( !mBlockChangedSignal )
211  emit widgetChanged();
212 }
213 
214 void QgsPointCloudRgbRendererWidget::redAttributeChanged()
215 {
216  if ( mLayer && mLayer->dataProvider() )
217  {
218  const QgsPointCloudStatistics stats = mLayer->statistics();
219  const double max = stats.maximum( mRedAttributeComboBox->currentAttribute() );
220  if ( !std::isnan( max ) )
221  {
222  mDisableMinMaxWidgetRefresh++;
223  mRedMinLineEdit->setText( QLocale().toString( 0 ) );
224 
225  // 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
226  // likely to be 8 bit or 16 bit color values
227  mRedMaxLineEdit->setText( QLocale().toString( max > 255 ? 65535 : 255 ) );
228  mDisableMinMaxWidgetRefresh--;
229  emitWidgetChanged();
230  }
231  }
232 }
233 
234 void QgsPointCloudRgbRendererWidget::greenAttributeChanged()
235 {
236  if ( mLayer && mLayer->dataProvider() )
237  {
238  const QgsPointCloudStatistics stats = mLayer->statistics();
239  const double max = stats.maximum( mGreenAttributeComboBox->currentAttribute() );
240  if ( !std::isnan( max ) )
241  {
242  mDisableMinMaxWidgetRefresh++;
243  mGreenMinLineEdit->setText( QLocale().toString( 0 ) );
244 
245  // 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
246  // likely to be 8 bit or 16 bit color values
247  mGreenMaxLineEdit->setText( QLocale().toString( max > 255 ? 65535 : 255 ) );
248  mDisableMinMaxWidgetRefresh--;
249  emitWidgetChanged();
250  }
251  }
252 }
253 
254 void QgsPointCloudRgbRendererWidget::blueAttributeChanged()
255 {
256  if ( mLayer && mLayer->dataProvider() )
257  {
258  const QgsPointCloudStatistics stats = mLayer->statistics();
259  const double max = stats.maximum( mBlueAttributeComboBox->currentAttribute() );
260  if ( !std::isnan( max ) )
261  {
262  mDisableMinMaxWidgetRefresh++;
263  mBlueMinLineEdit->setText( QLocale().toString( 0 ) );
264 
265  // 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
266  // likely to be 8 bit or 16 bit color values
267  mBlueMaxLineEdit->setText( QLocale().toString( max > 255 ? 65535 : 255 ) );
268  mDisableMinMaxWidgetRefresh--;
269  emitWidgetChanged();
270  }
271  }
272 }
273 
274 void QgsPointCloudRgbRendererWidget::minMaxModified()
275 {
276  if ( !mDisableMinMaxWidgetRefresh )
277  {
278  if ( ( QgsContrastEnhancement::ContrastEnhancementAlgorithm )( mContrastEnhancementAlgorithmComboBox->currentData().toInt() ) == QgsContrastEnhancement::NoEnhancement )
279  {
280  mContrastEnhancementAlgorithmComboBox->setCurrentIndex(
281  mContrastEnhancementAlgorithmComboBox->findData( ( int ) QgsContrastEnhancement::StretchToMinimumMaximum ) );
282  }
283  emitWidgetChanged();
284  }
285 }
286 
287 void QgsPointCloudRgbRendererWidget::setMinMaxValue( const QgsContrastEnhancement *ce, QLineEdit *minEdit, QLineEdit *maxEdit )
288 {
289  if ( !minEdit || !maxEdit )
290  {
291  return;
292  }
293 
294  if ( !ce )
295  {
296  minEdit->clear();
297  maxEdit->clear();
298  return;
299  }
300 
301  minEdit->setText( QLocale().toString( ce->minimumValue() ) );
302  maxEdit->setText( QLocale().toString( ce->maximumValue() ) );
303 
304  // QgsMultiBandColorRenderer is using individual contrast enhancements for each
305  // band, but this widget GUI has one for all
306  mContrastEnhancementAlgorithmComboBox->setCurrentIndex( mContrastEnhancementAlgorithmComboBox->findData(
307  static_cast< int >( ce->contrastEnhancementAlgorithm() ) ) );
308 }
309 
310 void QgsPointCloudRgbRendererWidget::setFromRenderer( const QgsPointCloudRenderer *r )
311 {
312  mBlockChangedSignal = true;
313  const QgsPointCloudRgbRenderer *mbcr = dynamic_cast<const QgsPointCloudRgbRenderer *>( r );
314  if ( mbcr )
315  {
316  mRedAttributeComboBox->setAttribute( mbcr->redAttribute() );
317  mGreenAttributeComboBox->setAttribute( mbcr->greenAttribute() );
318  mBlueAttributeComboBox->setAttribute( mbcr->blueAttribute() );
319 
320  mDisableMinMaxWidgetRefresh++;
321  setMinMaxValue( mbcr->redContrastEnhancement(), mRedMinLineEdit, mRedMaxLineEdit );
322  setMinMaxValue( mbcr->greenContrastEnhancement(), mGreenMinLineEdit, mGreenMaxLineEdit );
323  setMinMaxValue( mbcr->blueContrastEnhancement(), mBlueMinLineEdit, mBlueMaxLineEdit );
324  mDisableMinMaxWidgetRefresh--;
325  }
326  else
327  {
328  if ( mRedAttributeComboBox->findText( QStringLiteral( "Red" ) ) > -1 && mRedAttributeComboBox->findText( QStringLiteral( "Green" ) ) > -1 &&
329  mRedAttributeComboBox->findText( QStringLiteral( "Blue" ) ) > -1 )
330  {
331  mRedAttributeComboBox->setAttribute( QStringLiteral( "Red" ) );
332  mGreenAttributeComboBox->setAttribute( QStringLiteral( "Green" ) );
333  mBlueAttributeComboBox->setAttribute( QStringLiteral( "Blue" ) );
334  }
335  else
336  {
337  mRedAttributeComboBox->setCurrentIndex( mRedAttributeComboBox->count() > 1 ? 1 : 0 );
338  mGreenAttributeComboBox->setCurrentIndex( mGreenAttributeComboBox->count() > 2 ? 2 : 0 );
339  mBlueAttributeComboBox->setCurrentIndex( mBlueAttributeComboBox->count() > 3 ? 3 : 0 );
340  }
341  }
342  mBlockChangedSignal = false;
343 }
344 
QgsPointCloudRendererWidget
Base class for point cloud 2D renderer settings widgets.
Definition: qgspointcloudrendererwidget.h:36
QgsPointCloudRgbRenderer
An RGB renderer for 2d visualisation of point clouds using embedded red, green and blue attributes.
Definition: qgspointcloudrgbrenderer.h:71
QgsContrastEnhancement::maximumValue
double maximumValue() const
Returns the maximum value for the contrast enhancement range.
Definition: qgscontrastenhancement.h:155
QgsPointCloudRgbRenderer::greenAttribute
QString greenAttribute() const
Returns the attribute to use for the green channel.
Definition: qgspointcloudrgbrenderer.cpp:350
QgsContrastEnhancement::setContrastEnhancementAlgorithm
void setContrastEnhancementAlgorithm(ContrastEnhancementAlgorithm algorithm, bool generateTable=true)
Sets the contrast enhancement algorithm.
Definition: qgscontrastenhancement.cpp:132
QgsContrastEnhancement::minimumValue
double minimumValue() const
Returns the minimum value for the contrast enhancement range.
Definition: qgscontrastenhancement.h:158
QgsPointCloudLayer
Represents a map layer supporting display of point clouds.
Definition: qgspointcloudlayer.h:45
qgscontrastenhancement.h
QgsContrastEnhancement::setMinimumValue
void setMinimumValue(double value, bool generateTable=true)
Sets the minimum value for the contrast enhancement range.
Definition: qgscontrastenhancement.cpp:200
QgsPointCloudRgbRenderer::redContrastEnhancement
const QgsContrastEnhancement * redContrastEnhancement() const
Returns the contrast enhancement to use for the red channel.
Definition: qgspointcloudrgbrenderer.cpp:370
QgsContrastEnhancement::StretchAndClipToMinimumMaximum
@ StretchAndClipToMinimumMaximum
Definition: qgscontrastenhancement.h:52
QgsPointCloudStatistics
Class used to store statistics of a point cloud dataset.
Definition: qgspointcloudstatistics.h:61
QgsPointCloudLayer::renderer
QgsPointCloudRenderer * renderer()
Returns the 2D renderer for the point cloud.
Definition: qgspointcloudlayer.cpp:706
qgspointcloudrgbrendererwidget.h
QgsPointCloudStatistics::maximum
double maximum(const QString &attribute) const
Returns the maximum value for the attribute attribute If no matching statistic is available then NaN ...
Definition: qgspointcloudstatistics.cpp:110
QgsPointCloudRgbRenderer::redAttribute
QString redAttribute() const
Returns the attribute to use for the red channel.
Definition: qgspointcloudrgbrenderer.cpp:340
QgsPointCloudRgbRenderer::blueAttribute
QString blueAttribute() const
Returns the attribute to use for the blue channel.
Definition: qgspointcloudrgbrenderer.cpp:360
QgsContrastEnhancement::ContrastEnhancementAlgorithm
ContrastEnhancementAlgorithm
This enumerator describes the types of contrast enhancement algorithms that can be used.
Definition: qgscontrastenhancement.h:48
qgspointcloudlayer.h
qgspointcloudrgbrenderer.h
QgsContrastEnhancement::StretchToMinimumMaximum
@ StretchToMinimumMaximum
Linear histogram.
Definition: qgscontrastenhancement.h:51
QgsPointCloudRgbRenderer::greenContrastEnhancement
const QgsContrastEnhancement * greenContrastEnhancement() const
Returns the contrast enhancement to use for the green channel.
Definition: qgspointcloudrgbrenderer.cpp:380
QgsContrastEnhancement::NoEnhancement
@ NoEnhancement
Default color scaling algorithm, no scaling is applied.
Definition: qgscontrastenhancement.h:50
Qgis::DataType::UnknownDataType
@ UnknownDataType
Unknown or unspecified type.
QgsDoubleValidator
QgsDoubleValidator is a QLineEdit Validator that combines QDoubleValidator and QRegularExpressionVali...
Definition: qgsdoublevalidator.h:40
QgsContrastEnhancement::ClipToMinimumMaximum
@ ClipToMinimumMaximum
Definition: qgscontrastenhancement.h:53
QgsPointCloudRendererWidget::layer
const QgsPointCloudLayer * layer() const
Returns the point cloud layer associated with the widget.
Definition: qgspointcloudrendererwidget.h:69
QgsPointCloudAttributeComboBox::attributeChanged
void attributeChanged(const QString &name)
Emitted when the currently selected attribute changes.
QgsContrastEnhancement::contrastEnhancementAlgorithm
ContrastEnhancementAlgorithm contrastEnhancementAlgorithm() const
Definition: qgscontrastenhancement.h:160
QgsPointCloudRgbRenderer::blueContrastEnhancement
const QgsContrastEnhancement * blueContrastEnhancement() const
Returns the contrast enhancement to use for the blue channel.
Definition: qgspointcloudrgbrenderer.cpp:390
QgsContrastEnhancement
Manipulates raster or point cloud pixel values so that they enhanceContrast or clip into a specified ...
Definition: qgscontrastenhancement.h:42
QgsStyle
Definition: qgsstyle.h:159
QgsDoubleValidator::toDouble
static double toDouble(const QString &input, bool *ok)
Converts input string to double value.
Definition: qgsdoublevalidator.cpp:134
QgsPointCloudRgbRenderer::setBlueContrastEnhancement
void setBlueContrastEnhancement(QgsContrastEnhancement *enhancement)
Sets the contrast enhancement to use for the blue channel.
Definition: qgspointcloudrgbrenderer.cpp:395
QgsPointCloudRenderer
Abstract base class for 2d point cloud renderers.
Definition: qgspointcloudrenderer.h:296
qgsdoublevalidator.h
QgsPointCloudRgbRenderer::setRedContrastEnhancement
void setRedContrastEnhancement(QgsContrastEnhancement *enhancement)
Sets the contrast enhancement to use for the red channel.
Definition: qgspointcloudrgbrenderer.cpp:375
QgsContrastEnhancement::setMaximumValue
void setMaximumValue(double value, bool generateTable=true)
Sets the maximum value for the contrast enhancement range.
Definition: qgscontrastenhancement.cpp:174
QgsPointCloudRgbRenderer::setGreenContrastEnhancement
void setGreenContrastEnhancement(QgsContrastEnhancement *enhancement)
Sets the contrast enhancement to use for the green channel.
Definition: qgspointcloudrgbrenderer.cpp:385