QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
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 "moc_qgspointcloudattributebyramprendererwidget.cpp"
21#include "qgspointcloudlayer.h"
23#include "qgsdoublevalidator.h"
24#include "qgsstyle.h"
26
28
29QgsPointCloudAttributeByRampRendererWidget::QgsPointCloudAttributeByRampRendererWidget( QgsPointCloudLayer *layer, QgsStyle *style )
30 : QgsPointCloudRendererWidget( layer, style )
31{
32 setupUi( this );
33
34 mAttributeComboBox->setAllowEmptyAttributeName( false );
35 mAttributeComboBox->setFilters( QgsPointCloudAttributeProxyModel::AllTypes );
36
37 mMinSpin->setShowClearButton( false );
38 mMaxSpin->setShowClearButton( false );
39
40 if ( layer )
41 {
42 mAttributeComboBox->setLayer( layer );
43
44 setFromRenderer( layer->renderer() );
45 }
46
47 connect( mAttributeComboBox, &QgsPointCloudAttributeComboBox::attributeChanged, 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
55QgsPointCloudRendererWidget *QgsPointCloudAttributeByRampRendererWidget::create( QgsPointCloudLayer *layer, QgsStyle *style, QgsPointCloudRenderer * )
56{
57 return new QgsPointCloudAttributeByRampRendererWidget( layer, style );
58}
59
60QgsPointCloudRenderer *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
78void QgsPointCloudAttributeByRampRendererWidget::emitWidgetChanged()
79{
80 if ( !mBlockChangedSignal )
81 emit widgetChanged();
82}
83
84void QgsPointCloudAttributeByRampRendererWidget::minMaxChanged()
85{
86 if ( mBlockMinMaxChanged )
87 return;
88
89 mScalarColorRampShaderWidget->setMinimumMaximumAndClassify( mMinSpin->value(), mMaxSpin->value() );
90}
91
92void 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 if ( !mBlockSetMinMaxFromLayer )
119 setMinMaxFromLayer();
120
121 mScalarRecalculateMinMaxButton->setEnabled( !std::isnan( mProviderMin ) && !std::isnan( mProviderMax ) );
122 emitWidgetChanged();
123}
124
125void QgsPointCloudAttributeByRampRendererWidget::setMinMaxFromLayer()
126{
127 if ( std::isnan( mProviderMin ) || std::isnan( mProviderMax ) )
128 return;
129
130 mBlockMinMaxChanged = true;
131 mMinSpin->setValue( mProviderMin );
132 mMaxSpin->setValue( mProviderMax );
133 mBlockMinMaxChanged = false;
134
135 minMaxChanged();
136}
137
138void QgsPointCloudAttributeByRampRendererWidget::setFromRenderer( const QgsPointCloudRenderer *r )
139{
140 mBlockChangedSignal = true;
141 const QgsPointCloudAttributeByRampRenderer *mbcr = dynamic_cast<const QgsPointCloudAttributeByRampRenderer *>( r );
142 if ( mbcr )
143 {
144 // we will be restoring the existing ramp classes -- we don't want to regenerate any automatically!
145 mBlockSetMinMaxFromLayer = true;
146
147 mAttributeComboBox->setAttribute( mbcr->attribute() );
148
149 mMinSpin->setValue( mbcr->minimum() );
150 mMaxSpin->setValue( mbcr->maximum() );
151
152 whileBlocking( mScalarColorRampShaderWidget )->setFromShader( mbcr->colorRampShader() );
153 whileBlocking( mScalarColorRampShaderWidget )->setMinimumMaximum( mbcr->minimum(), mbcr->maximum() );
154 }
155 else
156 {
157 if ( mAttributeComboBox->findText( QStringLiteral( "Intensity" ) ) > -1 )
158 {
159 mAttributeComboBox->setAttribute( QStringLiteral( "Intensity" ) );
160 }
161 else
162 {
163 mAttributeComboBox->setCurrentIndex( mAttributeComboBox->count() > 1 ? 1 : 0 );
164 }
165 }
166 attributeChanged();
167 mBlockChangedSignal = false;
168 mBlockSetMinMaxFromLayer = false;
169}
170
void widgetChanged()
Widget changed.
An RGB renderer for 2d visualisation of point clouds using embedded red, green and blue attributes.
double maximum() const
Returns the maximum value for attributes which will be used by the color ramp shader.
QgsColorRampShader colorRampShader() const
Returns the color ramp shader function used to visualize the attribute.
double minimum() const
Returns the minimum value for attributes which will be used by the color ramp shader.
QString attribute() const
Returns the attribute to use for the renderer.
void setAttribute(const QString &attribute)
Sets the attribute to use for the renderer.
void attributeChanged(const QString &name)
Emitted when the currently selected attribute changes.
Point cloud layer specific subclass of QgsMapLayerElevationProperties.
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.
Class 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 ...
double minimum(const QString &attribute) const
Returns the minimum value for the attribute attribute If no matching statistic is available then NaN ...
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:5970