QGIS API Documentation 3.43.0-Master (ebb4087afc0)
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#include "moc_qgspointcloudlayerelevationproperties.cpp"
20#include "qgspointcloudlayer.h"
21#include "qgsapplication.h"
23#include "qgscolorutils.h"
24#include "qgsvirtualpointcloudprovider.h"
25
28{
30
31 if ( QgsPointCloudLayer *pcLayer = qobject_cast< QgsPointCloudLayer * >( parent ) )
32 {
33 connect( pcLayer, &QgsPointCloudLayer::rendererChanged, this, [this]
34 {
35 if ( mRespectLayerColors )
37 } );
38 }
39}
40
42{
43 return true;
44}
45
46QDomElement QgsPointCloudLayerElevationProperties::writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context )
47{
48 QDomElement element = document.createElement( QStringLiteral( "elevation" ) );
49 writeCommonProperties( element, document, context );
50
51 element.setAttribute( QStringLiteral( "max_screen_error" ), qgsDoubleToString( mMaximumScreenError ) );
52 element.setAttribute( QStringLiteral( "max_screen_error_unit" ), QgsUnitTypes::encodeUnit( mMaximumScreenErrorUnit ) );
53 element.setAttribute( QStringLiteral( "point_size" ), qgsDoubleToString( mPointSize ) );
54 element.setAttribute( QStringLiteral( "point_size_unit" ), QgsUnitTypes::encodeUnit( mPointSizeUnit ) );
55 element.setAttribute( QStringLiteral( "point_symbol" ), qgsEnumValueToKey( mPointSymbol ) );
56 element.setAttribute( QStringLiteral( "point_color" ), QgsColorUtils::colorToString( mPointColor ) );
57 element.setAttribute( QStringLiteral( "respect_layer_colors" ), mRespectLayerColors ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
58 element.setAttribute( QStringLiteral( "opacity_by_distance" ), mApplyOpacityByDistanceEffect ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
59
60 parentElement.appendChild( element );
61 return element;
62}
63
64bool QgsPointCloudLayerElevationProperties::readXml( const QDomElement &element, const QgsReadWriteContext &context )
65{
66 const QDomElement elevationElement = element.firstChildElement( QStringLiteral( "elevation" ) ).toElement();
67 readCommonProperties( elevationElement, context );
68
69 mMaximumScreenError = elevationElement.attribute( QStringLiteral( "max_screen_error" ), QStringLiteral( "0.3" ) ).toDouble();
70 bool ok = false;
71 mMaximumScreenErrorUnit = QgsUnitTypes::decodeRenderUnit( elevationElement.attribute( QStringLiteral( "max_screen_error_unit" ) ), &ok );
72 if ( !ok )
73 mMaximumScreenErrorUnit = Qgis::RenderUnit::Millimeters;
74 mPointSize = elevationElement.attribute( QStringLiteral( "point_size" ), QStringLiteral( "0.6" ) ).toDouble();
75 mPointSizeUnit = QgsUnitTypes::decodeRenderUnit( elevationElement.attribute( QStringLiteral( "point_size_unit" ) ), &ok );
76 if ( !ok )
77 mPointSizeUnit = Qgis::RenderUnit::Millimeters;
78 mPointSymbol = qgsEnumKeyToValue( elevationElement.attribute( QStringLiteral( "point_symbol" ) ), Qgis::PointCloudSymbol::Square );
79 const QString colorString = elevationElement.attribute( QStringLiteral( "point_color" ) );
80 if ( !colorString.isEmpty() )
81 {
82 mPointColor = QgsColorUtils::colorFromString( elevationElement.attribute( QStringLiteral( "point_color" ) ) );
83 }
84 else
85 {
87 }
88 mRespectLayerColors = elevationElement.attribute( QStringLiteral( "respect_layer_colors" ), QStringLiteral( "1" ) ).toInt();
89 mApplyOpacityByDistanceEffect = elevationElement.attribute( QStringLiteral( "opacity_by_distance" ) ).toInt();
90
91 return true;
92}
93
95{
96 auto res = std::make_unique< QgsPointCloudLayerElevationProperties >( nullptr );
97 res->copyCommonProperties( this );
98
99 res->mMaximumScreenError = mMaximumScreenError;
100 res->mMaximumScreenErrorUnit = mMaximumScreenErrorUnit;
101 res->mPointSize = mPointSize;
102 res->mPointSizeUnit = mPointSizeUnit;
103 res->mPointSymbol = mPointSymbol;
104 res->mPointColor = mPointColor;
105 res->mRespectLayerColors = mRespectLayerColors;
106 res->mApplyOpacityByDistanceEffect = mApplyOpacityByDistanceEffect;
107
108 return res.release();
109}
110
112{
113 QStringList properties;
114 properties << tr( "Scale: %1" ).arg( mZScale );
115 properties << tr( "Offset: %1" ).arg( mZOffset );
116 return QStringLiteral( "<ul><li>%1</li></ul>" ).arg( properties.join( QLatin1String( "</li><li>" ) ) );
117}
118
120{
121 // TODO -- test actual point cloud z range
122 return true;
123}
124
126{
127 if ( QgsPointCloudLayer *pcLayer = qobject_cast< QgsPointCloudLayer * >( layer ) )
128 {
129 if ( pcLayer->dataProvider() )
130 {
131 double zMin = std::numeric_limits<double>::quiet_NaN();
132 double zMax = std::numeric_limits<double>::quiet_NaN();
133 const QgsPointCloudStatistics stats = pcLayer->statistics();
134 if ( !stats.statisticsMap().isEmpty() )
135 {
136 // try to fetch z range from provider metadata
137 zMin = stats.minimum( QStringLiteral( "Z" ) );
138 zMax = stats.maximum( QStringLiteral( "Z" ) );
139 }
140 // try to fetch the elevation properties from virtual point cloud metadata
141 else if ( QgsVirtualPointCloudProvider *virtualProvider = dynamic_cast< QgsVirtualPointCloudProvider * >( pcLayer->dataProvider() ) )
142 {
143 for ( QgsPointCloudSubIndex subIndex : virtualProvider->subIndexes() )
144 {
145 const QgsDoubleRange newRange = subIndex.zRange();
146 if ( newRange.isInfinite() ) continue;
147 zMin = std::isnan( zMin ) ? newRange.lower() : std::min( zMin, newRange.lower() );
148 zMax = std::isnan( zMax ) ? newRange.upper() : std::max( zMax, newRange.upper() );
149 }
150 }
151
152 if ( !std::isnan( zMin ) && !std::isnan( zMax ) )
153 {
154 return QgsDoubleRange( zMin * mZScale + mZOffset, zMax * mZScale + mZOffset );
155 }
156 }
157 }
158
159 return QgsDoubleRange();
160}
161
163{
164 const QgsDoubleRange range = calculateZRange( layer );
165 if ( !range.isInfinite() && range.lower() != range.upper() )
166 return {range.lower(), range.upper() };
167 else if ( !range.isInfinite() )
168 return {range.lower() };
169 else
170 return {};
171}
172
177
179{
180 if ( qgsDoubleNear( error, mMaximumScreenError ) )
181 return;
182
183 mMaximumScreenError = error;
184 emit changed();
186}
187
189{
190 if ( unit == mMaximumScreenErrorUnit )
191 return;
192
193 mMaximumScreenErrorUnit = unit;
194 emit changed();
196}
197
202
204{
205 if ( mPointSymbol == symbol )
206 return;
207
208 mPointSymbol = symbol;
209 emit changed();
211}
212
214{
215 if ( color == mPointColor )
216 return;
217
218 mPointColor = color;
219 emit changed();
221}
222
224{
225 if ( apply == mApplyOpacityByDistanceEffect )
226 return;
227
228 mApplyOpacityByDistanceEffect = apply;
229 emit changed();
230
231 // turning ON opacity by distance requires a profile regeneration, turning it off does not.
232 if ( mApplyOpacityByDistanceEffect )
234 else
236}
237
239{
240 if ( qgsDoubleNear( size, mPointSize ) )
241 return;
242
243 mPointSize = size;
244 emit changed();
246}
247
249{
250 if ( mPointSizeUnit == units )
251 return;
252
253 mPointSizeUnit = units;
254 emit changed();
256}
257
259{
260 if ( mRespectLayerColors == enabled )
261 return;
262
263 mRespectLayerColors = enabled;
264 emit changed();
265
266 // turning ON respect layer colors requires a profile regeneration, turning it off does not.
267 if ( mRespectLayerColors )
269 else
271}
PointCloudSymbol
Rendering symbols for point cloud points.
Definition qgis.h:4075
@ Square
Renders points as squares.
RenderUnit
Rendering size units.
Definition qgis.h:4991
@ Millimeters
Millimeters.
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:233
bool isInfinite() const
Returns true if the range consists of all possible values.
Definition qgsrange.h:287
Base class for storage of map layer elevation properties.
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 ...
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:76
void rendererChanged()
Signal emitted when renderer is changed.
Point cloud layer specific subclass of QgsMapLayerElevationProperties.
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.
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 ...
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:78
T upper() const
Returns the upper bound of the range.
Definition qgsrange.h:85
The class is used as a container of context for various read/write operations on other 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:6396
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition qgis.h:6103
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:6377
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition qgis.h:6186