QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsmeshlayerelevationproperties.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmeshlayerelevationproperties.cpp
3 ---------------
4 begin : February 2022
5 copyright : (C) 2022 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 "qgsmeshlayer.h"
20#include "qgslinesymbol.h"
21#include "qgsfillsymbol.h"
22#include "qgssymbollayerutils.h"
23#include "qgslinesymbollayer.h"
24#include "qgsfillsymbollayer.h"
25#include "qgsapplication.h"
27
30{
32 setDefaultProfileLineSymbol( color );
33 setDefaultProfileFillSymbol( color );
34}
35
37
39{
40 return true;
41}
42
43QDomElement QgsMeshLayerElevationProperties::writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context )
44{
45 QDomElement element = document.createElement( QStringLiteral( "elevation" ) );
46 element.setAttribute( QStringLiteral( "mode" ), qgsEnumValueToKey( mMode ) );
47 element.setAttribute( QStringLiteral( "symbology" ), qgsEnumValueToKey( mSymbology ) );
48 if ( !std::isnan( mElevationLimit ) )
49 element.setAttribute( QStringLiteral( "elevationLimit" ), qgsDoubleToString( mElevationLimit ) );
50
51 writeCommonProperties( element, document, context );
52
53 switch ( mMode )
54 {
56 element.setAttribute( QStringLiteral( "lower" ), qgsDoubleToString( mFixedRange.lower() ) );
57 element.setAttribute( QStringLiteral( "upper" ), qgsDoubleToString( mFixedRange.upper() ) );
58 element.setAttribute( QStringLiteral( "includeLower" ), mFixedRange.includeLower() ? "1" : "0" );
59 element.setAttribute( QStringLiteral( "includeUpper" ), mFixedRange.includeUpper() ? "1" : "0" );
60 break;
61
63 break;
64 }
65
66 QDomElement profileLineSymbolElement = document.createElement( QStringLiteral( "profileLineSymbol" ) );
67 profileLineSymbolElement.appendChild( QgsSymbolLayerUtils::saveSymbol( QString(), mProfileLineSymbol.get(), document, context ) );
68 element.appendChild( profileLineSymbolElement );
69
70 QDomElement profileFillSymbolElement = document.createElement( QStringLiteral( "profileFillSymbol" ) );
71 profileFillSymbolElement.appendChild( QgsSymbolLayerUtils::saveSymbol( QString(), mProfileFillSymbol.get(), document, context ) );
72 element.appendChild( profileFillSymbolElement );
73
74 parentElement.appendChild( element );
75 return element;
76}
77
78bool QgsMeshLayerElevationProperties::readXml( const QDomElement &element, const QgsReadWriteContext &context )
79{
80 const QDomElement elevationElement = element.firstChildElement( QStringLiteral( "elevation" ) ).toElement();
81 mMode = qgsEnumKeyToValue( elevationElement.attribute( QStringLiteral( "mode" ) ), Qgis::MeshElevationMode::FromVertices );
82 mSymbology = qgsEnumKeyToValue( elevationElement.attribute( QStringLiteral( "symbology" ) ), Qgis::ProfileSurfaceSymbology::Line );
83 if ( elevationElement.hasAttribute( QStringLiteral( "elevationLimit" ) ) )
84 mElevationLimit = elevationElement.attribute( QStringLiteral( "elevationLimit" ) ).toDouble();
85 else
86 mElevationLimit = std::numeric_limits< double >::quiet_NaN();
87
88 readCommonProperties( elevationElement, context );
89
90 switch ( mMode )
91 {
93 {
94 const double lower = elevationElement.attribute( QStringLiteral( "lower" ) ).toDouble();
95 const double upper = elevationElement.attribute( QStringLiteral( "upper" ) ).toDouble();
96 const bool includeLower = elevationElement.attribute( QStringLiteral( "includeLower" ) ).toInt();
97 const bool includeUpper = elevationElement.attribute( QStringLiteral( "includeUpper" ) ).toInt();
98 mFixedRange = QgsDoubleRange( lower, upper, includeLower, includeUpper );
99 break;
100 }
102 break;
103 }
104
105 const QColor defaultColor = QgsApplication::colorSchemeRegistry()->fetchRandomStyleColor();
106
107 const QDomElement profileLineSymbolElement = elevationElement.firstChildElement( QStringLiteral( "profileLineSymbol" ) ).firstChildElement( QStringLiteral( "symbol" ) );
108 mProfileLineSymbol.reset( QgsSymbolLayerUtils::loadSymbol< QgsLineSymbol >( profileLineSymbolElement, context ) );
109 if ( !mProfileLineSymbol )
110 setDefaultProfileLineSymbol( defaultColor );
111
112 const QDomElement profileFillSymbolElement = elevationElement.firstChildElement( QStringLiteral( "profileFillSymbol" ) ).firstChildElement( QStringLiteral( "symbol" ) );
113 mProfileFillSymbol.reset( QgsSymbolLayerUtils::loadSymbol< QgsFillSymbol >( profileFillSymbolElement, context ) );
114 if ( !mProfileFillSymbol )
115 setDefaultProfileFillSymbol( defaultColor );
116
117 return true;
118}
119
121{
122 QStringList properties;
123 switch ( mMode )
124 {
126 properties << tr( "Elevation range: %1 to %2" ).arg( mFixedRange.lower() ).arg( mFixedRange.upper() );
127 break;
128
130 properties << tr( "Scale: %1" ).arg( mZScale );
131 properties << tr( "Offset: %1" ).arg( mZOffset );
132 break;
133 }
134 return QStringLiteral( "<li>%1</li>" ).arg( properties.join( QLatin1String( "</li><li>" ) ) );
135}
136
138{
139 std::unique_ptr< QgsMeshLayerElevationProperties > res = std::make_unique< QgsMeshLayerElevationProperties >( nullptr );
140 res->setMode( mMode );
141 res->setProfileLineSymbol( mProfileLineSymbol->clone() );
142 res->setProfileFillSymbol( mProfileFillSymbol->clone() );
143 res->setProfileSymbology( mSymbology );
144 res->setElevationLimit( mElevationLimit );
145 res->setFixedRange( mFixedRange );
146 res->copyCommonProperties( this );
147 return res.release();
148}
149
151{
152 switch ( mMode )
153 {
155 return mFixedRange.overlaps( range );
156
158 // TODO -- test actual mesh z range
159 return true;
160 }
162}
163
165{
166 switch ( mMode )
167 {
169 return mFixedRange;
170
172 // TODO -- determine actual z range from mesh statistics
173 return QgsDoubleRange();
174 }
176}
177
179{
180 return true;
181}
182
184{
185 switch ( mMode )
186 {
188 return QgsMapLayerElevationProperties::Flag::FlagDontInvalidateCachedRendersWhenRangeChanges;
189
191 break;
192 }
194}
195
197{
198 return mMode;
199}
200
202{
203 if ( mMode == mode )
204 return;
205
206 mMode = mode;
207 emit changed();
208}
209
211{
212 return mFixedRange;
213}
214
216{
217 if ( range == mFixedRange )
218 return;
219
220 mFixedRange = range;
221 emit changed();
222}
223
225{
226 return mProfileLineSymbol.get();
227}
228
230{
231 mProfileLineSymbol.reset( symbol );
232 emit changed();
234}
235
237{
238 return mProfileFillSymbol.get();
239}
240
242{
243 mProfileFillSymbol.reset( symbol );
244 emit changed();
246}
247
249{
250 if ( mSymbology == symbology )
251 return;
252
253 mSymbology = symbology;
254 emit changed();
256}
257
259{
260 return mElevationLimit;
261}
262
264{
265 if ( qgsDoubleNear( mElevationLimit, limit ) )
266 return;
267
268 mElevationLimit = limit;
269 emit changed();
271}
272
273void QgsMeshLayerElevationProperties::setDefaultProfileLineSymbol( const QColor &color )
274{
275 std::unique_ptr< QgsSimpleLineSymbolLayer > profileLineLayer = std::make_unique< QgsSimpleLineSymbolLayer >( color, 0.6 );
276 mProfileLineSymbol = std::make_unique< QgsLineSymbol>( QgsSymbolLayerList( { profileLineLayer.release() } ) );
277}
278
279void QgsMeshLayerElevationProperties::setDefaultProfileFillSymbol( const QColor &color )
280{
281 std::unique_ptr< QgsSimpleFillSymbolLayer > profileFillLayer = std::make_unique< QgsSimpleFillSymbolLayer >( color );
282 profileFillLayer->setStrokeStyle( Qt::NoPen );
283 mProfileFillSymbol = std::make_unique< QgsFillSymbol>( QgsSymbolLayerList( { profileFillLayer.release() } ) );
284}
MeshElevationMode
Mesh layer elevation modes.
Definition: qgis.h:3291
@ FromVertices
Elevation should be taken from mesh vertices.
@ FixedElevationRange
Layer has a fixed elevation range.
ProfileSurfaceSymbology
Surface symbology type for elevation profile plots.
Definition: qgis.h:3435
@ Line
The elevation surface will be rendered using a line symbol.
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.
QgsRange which stores a range of double values.
Definition: qgsrange.h:231
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgsfillsymbol.h:30
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgslinesymbol.h:30
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 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:75
Mesh layer specific subclass of QgsMapLayerElevationProperties.
QDomElement writeXml(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context) override
Writes the properties to a DOM element, to be used later with readXml().
QgsLineSymbol * profileLineSymbol() const
Returns the line symbol used to render the mesh profile in elevation profile plots.
QgsDoubleRange fixedRange() const
Returns the fixed elevation range for the mesh.
bool hasElevation() const override
Returns true if the layer has an elevation or z component.
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.
Qgis::MeshElevationMode mode() const
Returns the elevation mode.
QgsMeshLayerElevationProperties * clone() const override
Creates a clone of the properties.
void setElevationLimit(double limit)
Sets the elevation limit, which is used when profileSymbology() is Qgis::ProfileSurfaceSymbology::Fil...
QgsFillSymbol * profileFillSymbol() const
Returns the fill symbol used to render the mesh profile in elevation profile plots.
void setProfileSymbology(Qgis::ProfileSurfaceSymbology symbology)
Sets the symbology option used to render the mesh profile in elevation profile plots.
void setProfileFillSymbol(QgsFillSymbol *symbol)
Sets the fill symbol used to render the mesh profile in elevation profile plots.
void setProfileLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the mesh profile in elevation profile plots.
QgsMeshLayerElevationProperties(QObject *parent)
Constructor for QgsMeshLayerElevationProperties, with the specified parent object.
void setMode(Qgis::MeshElevationMode mode)
Sets the elevation mode.
QString htmlSummary() const override
Returns a HTML formatted summary of the properties.
QgsMapLayerElevationProperties::Flags flags() const override
Returns flags associated to the elevation properties.
void setFixedRange(const QgsDoubleRange &range)
Sets the fixed elevation range for the mesh.
bool showByDefaultInElevationProfilePlots() const override
Returns true if the layer should be visible by default in newly created elevation profile plots.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context) override
Reads the elevation properties from a DOM element previously written by writeXml().
double elevationLimit() const
Returns the elevation limit, which is used when profileSymbology() is Qgis::ProfileSurfaceSymbology::...
QgsDoubleRange calculateZRange(QgsMapLayer *layer) const override
Attempts to calculate the overall elevation or z range for the specified layer, using the settings de...
bool includeUpper() const
Returns true if the upper bound is inclusive, or false if the upper bound is exclusive.
Definition: qgsrange.h:101
bool overlaps(const QgsRange< T > &other) const
Returns true if this range overlaps another range.
Definition: qgsrange.h:176
T lower() const
Returns the lower bound of the range.
Definition: qgsrange.h:78
bool includeLower() const
Returns true if the lower bound is inclusive, or false if the lower bound is exclusive.
Definition: qgsrange.h:93
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 QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
int ANALYSIS_EXPORT lower(int n, int i)
Lower function.
Definition: MathUtils.cpp:337
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:5417
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:5124
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition: qgis.h:5398
#define BUILTIN_UNREACHABLE
Definition: qgis.h:5853
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:5207
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition: qgssymbol.h:30