QGIS API Documentation 3.41.0-Master (3440c17df1d)
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,
48 this, &QgsPointCloudAttributeByRampRendererWidget::attributeChanged );
49 connect( mMinSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloudAttributeByRampRendererWidget::minMaxChanged );
50 connect( mMaxSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloudAttributeByRampRendererWidget::minMaxChanged );
51
52 connect( mScalarColorRampShaderWidget, &QgsColorRampShaderWidget::widgetChanged, this, &QgsPointCloudAttributeByRampRendererWidget::emitWidgetChanged );
53 connect( mScalarRecalculateMinMaxButton, &QPushButton::clicked, this, &QgsPointCloudAttributeByRampRendererWidget::setMinMaxFromLayer );
54}
55
56QgsPointCloudRendererWidget *QgsPointCloudAttributeByRampRendererWidget::create( QgsPointCloudLayer *layer, QgsStyle *style, QgsPointCloudRenderer * )
57{
58 return new QgsPointCloudAttributeByRampRendererWidget( layer, style );
59}
60
61QgsPointCloudRenderer *QgsPointCloudAttributeByRampRendererWidget::renderer()
62{
63 if ( !mLayer )
64 {
65 return nullptr;
66 }
67
68 std::unique_ptr< QgsPointCloudAttributeByRampRenderer > renderer = std::make_unique< QgsPointCloudAttributeByRampRenderer >();
69 renderer->setAttribute( mAttributeComboBox->currentAttribute() );
70
71 renderer->setMinimum( mMinSpin->value() );
72 renderer->setMaximum( mMaxSpin->value() );
73
74 renderer->setColorRampShader( mScalarColorRampShaderWidget->shader() );
75
76 return renderer.release();
77}
78
79void QgsPointCloudAttributeByRampRendererWidget::emitWidgetChanged()
80{
81 if ( !mBlockChangedSignal )
82 emit widgetChanged();
83}
84
85void QgsPointCloudAttributeByRampRendererWidget::minMaxChanged()
86{
87 if ( mBlockMinMaxChanged )
88 return;
89
90 mScalarColorRampShaderWidget->setMinimumMaximumAndClassify( mMinSpin->value(), mMaxSpin->value() );
91}
92
93void QgsPointCloudAttributeByRampRendererWidget::attributeChanged()
94{
95 if ( mLayer && mLayer->dataProvider() )
96 {
97 const QgsPointCloudStatistics stats = mLayer->statistics();
98 const double min = stats.minimum( mAttributeComboBox->currentAttribute() );
99 const double max = stats.maximum( mAttributeComboBox->currentAttribute() );
100 if ( !std::isnan( min ) && !std::isnan( max ) )
101 {
102 mProviderMin = min;
103 mProviderMax = max;
104 }
105 else
106 {
107 mProviderMin = std::numeric_limits< double >::quiet_NaN();
108 mProviderMax = std::numeric_limits< double >::quiet_NaN();
109 }
110
111 if ( mAttributeComboBox->currentAttribute().compare( QLatin1String( "z" ), Qt::CaseInsensitive ) == 0 )
112 {
113 const double zScale = static_cast< const QgsPointCloudLayerElevationProperties * >( mLayer->elevationProperties() )->zScale();
114 const double zOffset = static_cast< const QgsPointCloudLayerElevationProperties * >( mLayer->elevationProperties() )->zOffset();
115 mProviderMin = mProviderMin * zScale + zOffset;
116 mProviderMax = mProviderMax * zScale + zOffset;
117 }
118
119 }
120 if ( !mBlockSetMinMaxFromLayer )
121 setMinMaxFromLayer();
122
123 mScalarRecalculateMinMaxButton->setEnabled( !std::isnan( mProviderMin ) && !std::isnan( mProviderMax ) );
124 emitWidgetChanged();
125}
126
127void QgsPointCloudAttributeByRampRendererWidget::setMinMaxFromLayer()
128{
129 if ( std::isnan( mProviderMin ) || std::isnan( mProviderMax ) )
130 return;
131
132 mBlockMinMaxChanged = true;
133 mMinSpin->setValue( mProviderMin );
134 mMaxSpin->setValue( mProviderMax );
135 mBlockMinMaxChanged = false;
136
137 minMaxChanged();
138}
139
140void QgsPointCloudAttributeByRampRendererWidget::setFromRenderer( const QgsPointCloudRenderer *r )
141{
142 mBlockChangedSignal = true;
143 const QgsPointCloudAttributeByRampRenderer *mbcr = dynamic_cast<const QgsPointCloudAttributeByRampRenderer *>( r );
144 if ( mbcr )
145 {
146 // we will be restoring the existing ramp classes -- we don't want to regenerate any automatically!
147 mBlockSetMinMaxFromLayer = true;
148
149 mAttributeComboBox->setAttribute( mbcr->attribute() );
150
151 mMinSpin->setValue( mbcr->minimum() );
152 mMaxSpin->setValue( mbcr->maximum() );
153
154 whileBlocking( mScalarColorRampShaderWidget )->setFromShader( mbcr->colorRampShader() );
155 whileBlocking( mScalarColorRampShaderWidget )->setMinimumMaximum( mbcr->minimum(), mbcr->maximum() );
156 }
157 else
158 {
159 if ( mAttributeComboBox->findText( QStringLiteral( "Intensity" ) ) > -1 )
160 {
161 mAttributeComboBox->setAttribute( QStringLiteral( "Intensity" ) );
162 }
163 else
164 {
165 mAttributeComboBox->setCurrentIndex( mAttributeComboBox->count() > 1 ? 1 : 0 );
166 }
167 }
168 attributeChanged();
169 mBlockChangedSignal = false;
170 mBlockSetMinMaxFromLayer = false;
171}
172
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:5862