QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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
20#include "qgspointcloudlayer.h"
22#include "qgsdoublevalidator.h"
23#include "qgsstyle.h"
25
27
28QgsPointCloudAttributeByRampRendererWidget::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
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 }
119 if ( !mBlockSetMinMaxFromLayer )
120 setMinMaxFromLayer();
121
122 mScalarRecalculateMinMaxButton->setEnabled( !std::isnan( mProviderMin ) && !std::isnan( mProviderMax ) );
123 emitWidgetChanged();
124}
125
126void 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
139void 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
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:2453