QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgspointcloudattributebyramprendererwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgspointcloudattributebyramprendererwidget.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 #include "qgsstyle.h"
25 
27 
28 QgsPointCloudAttributeByRampRendererWidget::QgsPointCloudAttributeByRampRendererWidget( QgsPointCloudLayer *layer, QgsStyle *style )
29  : QgsPointCloudRendererWidget( layer, style )
30 {
31  setupUi( this );
32 
33  mAttributeComboBox->setAllowEmptyAttributeName( false );
34  mAttributeComboBox->setFilters( QgsPointCloudAttributeProxyModel::AllTypes );
35 
36  mMinSpin->setShowClearButton( false );
37  mMaxSpin->setShowClearButton( false );
38 
39  if ( layer )
40  {
41  mAttributeComboBox->setLayer( layer );
42 
43  setFromRenderer( layer->renderer() );
44  }
45 
46  connect( mAttributeComboBox, &QgsPointCloudAttributeComboBox::attributeChanged,
47  this, &QgsPointCloudAttributeByRampRendererWidget::attributeChanged );
48  connect( mMinSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloudAttributeByRampRendererWidget::minMaxChanged );
49  connect( mMaxSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloudAttributeByRampRendererWidget::minMaxChanged );
50 
51  connect( mScalarColorRampShaderWidget, &QgsColorRampShaderWidget::widgetChanged, this, &QgsPointCloudAttributeByRampRendererWidget::emitWidgetChanged );
52  connect( mScalarRecalculateMinMaxButton, &QPushButton::clicked, this, &QgsPointCloudAttributeByRampRendererWidget::setMinMaxFromLayer );
53 }
54 
55 QgsPointCloudRendererWidget *QgsPointCloudAttributeByRampRendererWidget::create( QgsPointCloudLayer *layer, QgsStyle *style, QgsPointCloudRenderer * )
56 {
57  return new QgsPointCloudAttributeByRampRendererWidget( layer, style );
58 }
59 
60 QgsPointCloudRenderer *QgsPointCloudAttributeByRampRendererWidget::renderer()
61 {
62  if ( !mLayer )
63  {
64  return nullptr;
65  }
66 
67  std::unique_ptr< QgsPointCloudAttributeByRampRenderer > renderer = std::make_unique< QgsPointCloudAttributeByRampRenderer >();
68  renderer->setAttribute( mAttributeComboBox->currentAttribute() );
69 
70  renderer->setMinimum( mMinSpin->value() );
71  renderer->setMaximum( mMaxSpin->value() );
72 
73  renderer->setColorRampShader( mScalarColorRampShaderWidget->shader() );
74 
75  return renderer.release();
76 }
77 
78 void QgsPointCloudAttributeByRampRendererWidget::emitWidgetChanged()
79 {
80  if ( !mBlockChangedSignal )
81  emit widgetChanged();
82 }
83 
84 void QgsPointCloudAttributeByRampRendererWidget::minMaxChanged()
85 {
86  if ( mBlockMinMaxChanged )
87  return;
88 
89  mScalarColorRampShaderWidget->setMinimumMaximumAndClassify( mMinSpin->value(), mMaxSpin->value() );
90 }
91 
92 void QgsPointCloudAttributeByRampRendererWidget::attributeChanged()
93 {
94  if ( mLayer && mLayer->dataProvider() )
95  {
96  const QgsPointCloudStatistics stats = mLayer->statistics();
97  const double min = stats.minimum( mAttributeComboBox->currentAttribute() );
98  const double max = stats.maximum( mAttributeComboBox->currentAttribute() );
99  if ( !std::isnan( min ) && !std::isnan( max ) )
100  {
101  mProviderMin = min;
102  mProviderMax = max;
103  }
104  else
105  {
106  mProviderMin = std::numeric_limits< double >::quiet_NaN();
107  mProviderMax = std::numeric_limits< double >::quiet_NaN();
108  }
109 
110  if ( mAttributeComboBox->currentAttribute().compare( QLatin1String( "z" ), Qt::CaseInsensitive ) == 0 )
111  {
112  const double zScale = static_cast< const QgsPointCloudLayerElevationProperties * >( mLayer->elevationProperties() )->zScale();
113  const double zOffset = static_cast< const QgsPointCloudLayerElevationProperties * >( mLayer->elevationProperties() )->zOffset();
114  mProviderMin = mProviderMin * zScale + zOffset;
115  mProviderMax = mProviderMax * zScale + zOffset;
116  }
117 
118  }
119  if ( !mBlockSetMinMaxFromLayer )
120  setMinMaxFromLayer();
121 
122  mScalarRecalculateMinMaxButton->setEnabled( !std::isnan( mProviderMin ) && !std::isnan( mProviderMax ) );
123  emitWidgetChanged();
124 }
125 
126 void QgsPointCloudAttributeByRampRendererWidget::setMinMaxFromLayer()
127 {
128  if ( std::isnan( mProviderMin ) || std::isnan( mProviderMax ) )
129  return;
130 
131  mBlockMinMaxChanged = true;
132  mMinSpin->setValue( mProviderMin );
133  mMaxSpin->setValue( mProviderMax );
134  mBlockMinMaxChanged = false;
135 
136  minMaxChanged();
137 }
138 
139 void QgsPointCloudAttributeByRampRendererWidget::setFromRenderer( const QgsPointCloudRenderer *r )
140 {
141  mBlockChangedSignal = true;
142  const QgsPointCloudAttributeByRampRenderer *mbcr = dynamic_cast<const QgsPointCloudAttributeByRampRenderer *>( r );
143  if ( mbcr )
144  {
145  // we will be restoring the existing ramp classes -- we don't want to regenerate any automatically!
146  mBlockSetMinMaxFromLayer = true;
147 
148  mAttributeComboBox->setAttribute( mbcr->attribute() );
149 
150  mMinSpin->setValue( mbcr->minimum() );
151  mMaxSpin->setValue( mbcr->maximum() );
152 
153  whileBlocking( mScalarColorRampShaderWidget )->setFromShader( mbcr->colorRampShader() );
154  whileBlocking( mScalarColorRampShaderWidget )->setMinimumMaximum( mbcr->minimum(), mbcr->maximum() );
155  }
156  else
157  {
158  if ( mAttributeComboBox->findText( QStringLiteral( "Intensity" ) ) > -1 )
159  {
160  mAttributeComboBox->setAttribute( QStringLiteral( "Intensity" ) );
161  }
162  else
163  {
164  mAttributeComboBox->setCurrentIndex( mAttributeComboBox->count() > 1 ? 1 : 0 );
165  }
166  }
167  attributeChanged();
168  mBlockChangedSignal = false;
169  mBlockSetMinMaxFromLayer = false;
170 }
171 
QgsPointCloudRendererWidget
Base class for point cloud 2D renderer settings widgets.
Definition: qgspointcloudrendererwidget.h:36
QgsPointCloudLayerElevationProperties
Point cloud layer specific subclass of QgsMapLayerElevationProperties.
Definition: qgspointcloudlayerelevationproperties.h:33
QgsPointCloudLayer
Represents a map layer supporting display of point clouds.
Definition: qgspointcloudlayer.h:45
qgscontrastenhancement.h
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
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
QgsPointCloudAttributeByRampRenderer::colorRampShader
QgsColorRampShader colorRampShader() const
Returns the color ramp shader function used to visualize the attribute.
Definition: qgspointcloudattributebyramprenderer.cpp:221
qgspointcloudlayer.h
QgsPointCloudAttributeByRampRenderer::setAttribute
void setAttribute(const QString &attribute)
Sets the attribute to use for the renderer.
Definition: qgspointcloudattributebyramprenderer.cpp:216
whileBlocking
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:2191
QgsPointCloudAttributeByRampRenderer::minimum
double minimum() const
Returns the minimum value for attributes which will be used by the color ramp shader.
Definition: qgspointcloudattributebyramprenderer.cpp:231
QgsPointCloudAttributeByRampRenderer::maximum
double maximum() const
Returns the maximum value for attributes which will be used by the color ramp shader.
Definition: qgspointcloudattributebyramprenderer.cpp:241
QgsPointCloudAttributeComboBox::attributeChanged
void attributeChanged(const QString &name)
Emitted when the currently selected attribute changes.
QgsPointCloudAttributeByRampRenderer
An RGB renderer for 2d visualisation of point clouds using embedded red, green and blue attributes.
Definition: qgspointcloudattributebyramprenderer.h:61
qgspointcloudattributebyramprenderer.h
qgsstyle.h
QgsPointCloudStatistics::minimum
double minimum(const QString &attribute) const
Returns the minimum value for the attribute attribute If no matching statistic is available then NaN ...
Definition: qgspointcloudstatistics.cpp:103
QgsColorRampShaderWidget::widgetChanged
void widgetChanged()
Widget changed.
QgsStyle
Definition: qgsstyle.h:159
qgspointcloudattributebyramprendererwidget.h
QgsPointCloudAttributeByRampRenderer::attribute
QString attribute() const
Returns the attribute to use for the renderer.
Definition: qgspointcloudattributebyramprenderer.cpp:211
QgsPointCloudRenderer
Abstract base class for 2d point cloud renderers.
Definition: qgspointcloudrenderer.h:296
qgspointcloudlayerelevationproperties.h
QgsPointCloudAttributeProxyModel::AllTypes
@ AllTypes
All attribute types.
Definition: qgspointcloudattributemodel.h:151
qgsdoublevalidator.h