QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgspointcloudlayerelevationproperties.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspointcloudlayerelevationproperties.cpp
3 ---------------
4 begin : November 2020
5 copyright : (C) 2020 by Nyall Dawson
6 email : nyall dot dawson 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
20#include "qgsapplication.h"
22#include "qgscolorutils.h"
23#include "qgspointcloudlayer.h"
24#include "qgsvirtualpointcloudprovider.h"
25
26#include <QString>
27
28#include "moc_qgspointcloudlayerelevationproperties.cpp"
29
30using namespace Qt::StringLiterals;
31
34{
36
37 if ( QgsPointCloudLayer *pcLayer = qobject_cast< QgsPointCloudLayer * >( parent ) )
38 {
39 connect( pcLayer, &QgsPointCloudLayer::rendererChanged, this, [this]
40 {
41 if ( mRespectLayerColors )
43 } );
44 }
45}
46
48{
49 return true;
50}
51
52QDomElement QgsPointCloudLayerElevationProperties::writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context )
53{
54 QDomElement element = document.createElement( u"elevation"_s );
55 writeCommonProperties( element, document, context );
56
57 element.setAttribute( u"max_screen_error"_s, qgsDoubleToString( mMaximumScreenError ) );
58 element.setAttribute( u"max_screen_error_unit"_s, QgsUnitTypes::encodeUnit( mMaximumScreenErrorUnit ) );
59 element.setAttribute( u"point_size"_s, qgsDoubleToString( mPointSize ) );
60 element.setAttribute( u"point_size_unit"_s, QgsUnitTypes::encodeUnit( mPointSizeUnit ) );
61 element.setAttribute( u"point_symbol"_s, qgsEnumValueToKey( mPointSymbol ) );
62 element.setAttribute( u"point_color"_s, QgsColorUtils::colorToString( mPointColor ) );
63 element.setAttribute( u"respect_layer_colors"_s, mRespectLayerColors ? u"1"_s : u"0"_s );
64 element.setAttribute( u"opacity_by_distance"_s, mApplyOpacityByDistanceEffect ? u"1"_s : u"0"_s );
65
66 parentElement.appendChild( element );
67 return element;
68}
69
70bool QgsPointCloudLayerElevationProperties::readXml( const QDomElement &element, const QgsReadWriteContext &context )
71{
72 const QDomElement elevationElement = element.firstChildElement( u"elevation"_s ).toElement();
73 readCommonProperties( elevationElement, context );
74
75 mMaximumScreenError = elevationElement.attribute( u"max_screen_error"_s, u"0.3"_s ).toDouble();
76 bool ok = false;
77 mMaximumScreenErrorUnit = QgsUnitTypes::decodeRenderUnit( elevationElement.attribute( u"max_screen_error_unit"_s ), &ok );
78 if ( !ok )
79 mMaximumScreenErrorUnit = Qgis::RenderUnit::Millimeters;
80 mPointSize = elevationElement.attribute( u"point_size"_s, u"0.6"_s ).toDouble();
81 mPointSizeUnit = QgsUnitTypes::decodeRenderUnit( elevationElement.attribute( u"point_size_unit"_s ), &ok );
82 if ( !ok )
83 mPointSizeUnit = Qgis::RenderUnit::Millimeters;
84 mPointSymbol = qgsEnumKeyToValue( elevationElement.attribute( u"point_symbol"_s ), Qgis::PointCloudSymbol::Square );
85 const QString colorString = elevationElement.attribute( u"point_color"_s );
86 if ( !colorString.isEmpty() )
87 {
88 mPointColor = QgsColorUtils::colorFromString( elevationElement.attribute( u"point_color"_s ) );
89 }
90 else
91 {
93 }
94 mRespectLayerColors = elevationElement.attribute( u"respect_layer_colors"_s, u"1"_s ).toInt();
95 mApplyOpacityByDistanceEffect = elevationElement.attribute( u"opacity_by_distance"_s ).toInt();
96
97 return true;
98}
99
101{
102 auto res = std::make_unique< QgsPointCloudLayerElevationProperties >( nullptr );
103 res->copyCommonProperties( this );
104
105 res->mMaximumScreenError = mMaximumScreenError;
106 res->mMaximumScreenErrorUnit = mMaximumScreenErrorUnit;
107 res->mPointSize = mPointSize;
108 res->mPointSizeUnit = mPointSizeUnit;
109 res->mPointSymbol = mPointSymbol;
110 res->mPointColor = mPointColor;
111 res->mRespectLayerColors = mRespectLayerColors;
112 res->mApplyOpacityByDistanceEffect = mApplyOpacityByDistanceEffect;
113
114 return res.release();
115}
116
118{
119 QStringList properties;
120 properties << tr( "Scale: %1" ).arg( mZScale );
121 properties << tr( "Offset: %1" ).arg( mZOffset );
122 return u"<ul><li>%1</li></ul>"_s.arg( properties.join( "</li><li>"_L1 ) );
123}
124
126{
127 // TODO -- test actual point cloud z range
128 return true;
129}
130
132{
133 if ( QgsPointCloudLayer *pcLayer = qobject_cast< QgsPointCloudLayer * >( layer ) )
134 {
135 if ( pcLayer->dataProvider() )
136 {
137 double zMin = std::numeric_limits<double>::quiet_NaN();
138 double zMax = std::numeric_limits<double>::quiet_NaN();
139 const QgsPointCloudStatistics stats = pcLayer->statistics();
140 if ( !stats.statisticsMap().isEmpty() )
141 {
142 // try to fetch z range from provider metadata
143 zMin = stats.minimum( u"Z"_s );
144 zMax = stats.maximum( u"Z"_s );
145 }
146 // try to fetch the elevation properties from virtual point cloud metadata
147 else if ( QgsVirtualPointCloudProvider *virtualProvider = dynamic_cast< QgsVirtualPointCloudProvider * >( pcLayer->dataProvider() ) )
148 {
149 for ( QgsPointCloudSubIndex subIndex : virtualProvider->subIndexes() )
150 {
151 const QgsDoubleRange newRange = subIndex.zRange();
152 if ( newRange.isInfinite() ) continue;
153 zMin = std::isnan( zMin ) ? newRange.lower() : std::min( zMin, newRange.lower() );
154 zMax = std::isnan( zMax ) ? newRange.upper() : std::max( zMax, newRange.upper() );
155 }
156 }
157
158 if ( !std::isnan( zMin ) && !std::isnan( zMax ) )
159 {
160 return QgsDoubleRange( zMin * mZScale + mZOffset, zMax * mZScale + mZOffset );
161 }
162 }
163 }
164
165 return QgsDoubleRange();
166}
167
169{
170 const QgsDoubleRange range = calculateZRange( layer );
171 if ( !range.isInfinite() && range.lower() != range.upper() )
172 return {range.lower(), range.upper() };
173 else if ( !range.isInfinite() )
174 return {range.lower() };
175 else
176 return {};
177}
178
183
185{
186 if ( qgsDoubleNear( error, mMaximumScreenError ) )
187 return;
188
189 mMaximumScreenError = error;
190 emit changed();
192}
193
195{
196 if ( unit == mMaximumScreenErrorUnit )
197 return;
198
199 mMaximumScreenErrorUnit = unit;
200 emit changed();
202}
203
208
210{
211 if ( mPointSymbol == symbol )
212 return;
213
214 mPointSymbol = symbol;
215 emit changed();
217}
218
220{
221 if ( color == mPointColor )
222 return;
223
224 mPointColor = color;
225 emit changed();
227}
228
230{
231 if ( apply == mApplyOpacityByDistanceEffect )
232 return;
233
234 mApplyOpacityByDistanceEffect = apply;
235 emit changed();
236
237 // turning ON opacity by distance requires a profile regeneration, turning it off does not.
238 if ( mApplyOpacityByDistanceEffect )
240 else
242}
243
245{
246 if ( qgsDoubleNear( size, mPointSize ) )
247 return;
248
249 mPointSize = size;
250 emit changed();
252}
253
255{
256 if ( mPointSizeUnit == units )
257 return;
258
259 mPointSizeUnit = units;
260 emit changed();
262}
263
265{
266 if ( mRespectLayerColors == enabled )
267 return;
268
269 mRespectLayerColors = enabled;
270 emit changed();
271
272 // turning ON respect layer colors requires a profile regeneration, turning it off does not.
273 if ( mRespectLayerColors )
275 else
277}
PointCloudSymbol
Rendering symbols for point cloud points.
Definition qgis.h:4305
@ Square
Renders points as squares.
Definition qgis.h:4306
RenderUnit
Rendering size units.
Definition qgis.h:5255
@ Millimeters
Millimeters.
Definition qgis.h:5256
static QgsColorSchemeRegistry * colorSchemeRegistry()
Returns the application's color scheme registry, used for managing color schemes.
QColor fetchRandomStyleColor() const
Returns a random color for use with a new symbol style (e.g.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
QgsRange which stores a range of double values.
Definition qgsrange.h:236
bool isInfinite() const
Returns true if the range consists of all possible values.
Definition qgsrange.h:290
void writeCommonProperties(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context)
Writes common class properties to a DOM element, to be used later with readXml().
void profileGenerationPropertyChanged()
Emitted when any of the elevation properties which relate solely to generation of elevation profiles ...
QgsMapLayerElevationProperties(QObject *parent)
Constructor for QgsMapLayerElevationProperties, with the specified parent object.
void readCommonProperties(const QDomElement &element, const QgsReadWriteContext &context)
Reads common class properties from a DOM element previously written by writeXml().
void changed()
Emitted when any of the elevation properties have changed.
void profileRenderingPropertyChanged()
Emitted when any of the elevation properties which relate solely to presentation of elevation results...
Base class for all map layer types.
Definition qgsmaplayer.h:83
void rendererChanged()
Signal emitted when renderer is changed.
void setRespectLayerColors(bool enabled)
Sets whether layer coloring should be respected when rendering elevation profile plots.
QString htmlSummary() const override
Returns a HTML formatted summary of the properties.
void setPointColor(const QColor &color)
Sets the color used drawing points in elevation profile charts.
bool showByDefaultInElevationProfilePlots() const override
Returns true if the layer should be visible by default in newly created elevation profile plots.
bool hasElevation() const override
Returns true if the layer has an elevation or z component.
void setApplyOpacityByDistanceEffect(bool apply)
Sets whether a reduced opacity by distance from profile curve effect should be applied when drawing p...
QDomElement writeXml(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context) override
Writes the properties to a DOM element, to be used later with readXml().
void setPointSize(double size)
Sets the point size used for drawing points in elevation profile charts.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context) override
Reads the elevation properties from a DOM element previously written by writeXml().
void setPointSymbol(Qgis::PointCloudSymbol symbol)
Sets the symbol used drawing points in elevation profile charts.
QgsDoubleRange calculateZRange(QgsMapLayer *layer) const override
Attempts to calculate the overall elevation or z range for the specified layer, using the settings de...
void setMaximumScreenError(double error)
Sets the maximum screen error allowed when generating elevation profiles for the point cloud.
bool isVisibleInZRange(const QgsDoubleRange &range, QgsMapLayer *layer=nullptr) const override
Returns true if the layer should be visible and rendered for the specified z range.
void setPointSizeUnit(const Qgis::RenderUnit units)
Sets the units used for the point size used for drawing points in elevation profile charts.
QgsPointCloudLayerElevationProperties * clone() const override
Creates a clone of the properties.
void setMaximumScreenErrorUnit(Qgis::RenderUnit unit)
Sets the unit for the maximum screen error allowed when generating elevation profiles for the point c...
QList< double > significantZValues(QgsMapLayer *layer) const override
Returns a list of significant elevation/z-values for the specified layer, using the settings defined ...
Qgis::PointCloudSymbol pointSymbol() const
Returns the symbol used drawing points in elevation profile charts.
QgsPointCloudLayerElevationProperties(QObject *parent)
Constructor for QgsPointCloudLayerElevationProperties, with the specified parent object.
Represents a map layer supporting display of point clouds.
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 ...
QMap< QString, QgsPointCloudAttributeStatistics > statisticsMap() const
Returns a map object containing all the statistics.
T lower() const
Returns the lower bound of the range.
Definition qgsrange.h:81
T upper() const
Returns the upper bound of the range.
Definition qgsrange.h:88
A container for the context for various read/write operations on objects.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
Definition qgis.h:7110
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition qgis.h:6817
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:7091
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6900