QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
qgselevationprofile.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgselevationprofile.cpp
3 ------------------
4 Date : July 2025
5 Copyright : (C) 2025 Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15#include "qgselevationprofile.h"
16
17#include "qgscurve.h"
18#include "qgslayertree.h"
19#include "qgslinesymbol.h"
20#include "qgsproject.h"
21#include "qgssymbollayerutils.h"
22
23#include "moc_qgselevationprofile.cpp"
24
26 : mProject( project )
27 , mLayerTree( std::make_unique< QgsLayerTree >() )
28{
29 setupLayerTreeConnections();
30}
31
33
34QDomElement QgsElevationProfile::writeXml( QDomDocument &document, const QgsReadWriteContext &context ) const
35{
36 QDomElement profileElem = document.createElement( QStringLiteral( "ElevationProfile" ) );
37 profileElem.setAttribute( QStringLiteral( "name" ), mName );
38
39 profileElem.setAttribute( QStringLiteral( "distanceUnit" ), qgsEnumValueToKey( mDistanceUnit ) );
40
41 profileElem.setAttribute( QStringLiteral( "tolerance" ), mTolerance );
42 if ( mLockAxisScales )
43 profileElem.setAttribute( QStringLiteral( "lockAxisScales" ), QStringLiteral( "1" ) );
44
45 if ( mCrs.isValid() )
46 {
47 QDomElement crsElem = document.createElement( QStringLiteral( "crs" ) );
48 mCrs.writeXml( crsElem, document );
49 profileElem.appendChild( crsElem );
50 }
51 if ( mProfileCurve )
52 {
53 QDomElement curveElem = document.createElement( QStringLiteral( "curve" ) );
54 curveElem.appendChild( document.createTextNode( mProfileCurve->asWkt( ) ) );
55 profileElem.appendChild( curveElem );
56 }
57
58 mLayerTree->writeXml( profileElem, context );
59
60 if ( mSubsectionsSymbol )
61 {
62 QDomElement subsectionsElement = document.createElement( QStringLiteral( "subsections" ) );
63 const QDomElement symbolElement = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "subsections" ), mSubsectionsSymbol.get(), document, context );
64 subsectionsElement.appendChild( symbolElement );
65 profileElem.appendChild( subsectionsElement );
66 }
67
68 return profileElem;
69}
70
71bool QgsElevationProfile::readXml( const QDomElement &element, const QDomDocument &, const QgsReadWriteContext &context )
72{
73 if ( element.nodeName() != QLatin1String( "ElevationProfile" ) )
74 {
75 return false;
76 }
77
78 setName( element.attribute( QStringLiteral( "name" ) ) );
79
80 const QDomNodeList crsNodeList = element.elementsByTagName( QStringLiteral( "crs" ) );
82 if ( !crsNodeList.isEmpty() )
83 {
84 const QDomElement crsElem = crsNodeList.at( 0 ).toElement();
85 crs.readXml( crsElem );
86 }
87 mCrs = crs;
88
89 setDistanceUnit( qgsEnumKeyToValue( element.attribute( QStringLiteral( "distanceUnit" ) ), mCrs.mapUnits() ) );
90
91 const QDomNodeList curveNodeList = element.elementsByTagName( QStringLiteral( "curve" ) );
92 if ( !curveNodeList.isEmpty() )
93 {
94 const QDomElement curveElem = curveNodeList.at( 0 ).toElement();
95 const QgsGeometry curve = QgsGeometry::fromWkt( curveElem.text() );
96 // clang-tidy false positive
97 // NOLINTBEGIN(bugprone-branch-clone)
98 if ( const QgsCurve *curveGeom = qgsgeometry_cast< const QgsCurve * >( curve.constGet() ) )
99 {
100 mProfileCurve.reset( curveGeom->clone() );
101 }
102 else
103 {
104 mProfileCurve.reset();
105 }
106 // NOLINTEND(bugprone-branch-clone)
107 }
108
109 mTolerance = element.attribute( QStringLiteral( "tolerance" ) ).toDouble();
110 mLockAxisScales = element.attribute( QStringLiteral( "lockAxisScales" ), QStringLiteral( "0" ) ).toInt();
111
112 {
113 const QDomElement layerTreeElem = element.firstChildElement( QStringLiteral( "layer-tree-group" ) );
114 mLayerTree = QgsLayerTree::readXml( layerTreeElem, context );
115 setupLayerTreeConnections();
116 }
117
118 const QDomElement subsectionsElement = element.firstChildElement( QStringLiteral( "subsections" ) );
119 const QDomElement symbolsElement = subsectionsElement.firstChildElement( QStringLiteral( "symbol" ) );
120 if ( !symbolsElement.isNull() )
121 {
122 std::unique_ptr< QgsLineSymbol > subSectionsSymbol = QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol >( symbolsElement, context );
123 if ( subSectionsSymbol )
124 {
125 setSubsectionsSymbol( subSectionsSymbol.release() );
126 }
127 }
128
129 return true;
130}
131
133{
134 mLayerTree->resolveReferences( project );
135}
136
138{
139 return QIcon();
140}
141
143{
144 return mLayerTree.get();
145}
146
148{
149 if ( mCrs == crs )
150 return;
151
152 mCrs = crs;
153 dirtyProject();
154}
155
160
162{
163 if ( curve == mProfileCurve.get() )
164 return;
165 mProfileCurve.reset( curve );
166 dirtyProject();
167}
168
170{
171 return mProfileCurve.get();
172}
173
175{
176 if ( qgsDoubleNear( tolerance, mTolerance ) )
177 return;
178
179 mTolerance = tolerance;
180 dirtyProject();
181}
182
184{
185 return mTolerance;
186}
187
189{
190 return mLockAxisScales;
191}
192
194{
195 return mDistanceUnit;
196}
197
199{
200 if ( lock == mLockAxisScales )
201 return;
202
203 mLockAxisScales = lock;
204 dirtyProject();
205}
206
208{
209 if ( mDistanceUnit == unit )
210 return;
211
212 mDistanceUnit = unit;
213 dirtyProject();
214}
215
216void QgsElevationProfile::dirtyProject()
217{
218 if ( mProject )
219 mProject->setDirty();
220}
221
222void QgsElevationProfile::setupLayerTreeConnections()
223{
224 connect( mLayerTree.get(), &QgsLayerTree::layerOrderChanged, this, &QgsElevationProfile::dirtyProject );
225 connect( mLayerTree.get(), &QgsLayerTree::visibilityChanged, this, &QgsElevationProfile::dirtyProject );
226 connect( mLayerTree.get(), &QgsLayerTree::nameChanged, this, &QgsElevationProfile::dirtyProject );
227}
228
230{
231 return mSubsectionsSymbol.get();
232}
233
235{
236 if ( symbol == mSubsectionsSymbol.get() )
237 return;
238
239 mSubsectionsSymbol.reset( symbol );
240 dirtyProject();
241}
242
243void QgsElevationProfile::setName( const QString &name )
244{
245 if ( name == mName )
246 return;
247
248 mName = name;
249 dirtyProject();
250 emit nameChanged( mName );
251}
DistanceUnit
Units of distance.
Definition qgis.h:5013
Represents a coordinate reference system (CRS).
Abstract base class for curved geometry type.
Definition qgscurve.h:36
void setName(const QString &name)
Sets the profile's unique name.
QgsCoordinateReferenceSystem crs() const
Returns the crs associated with the profile's map coordinates.
QDomElement writeXml(QDomDocument &document, const QgsReadWriteContext &context) const
Returns the profiles's state encapsulated in a DOM element.
double tolerance() const
Returns the tolerance of the profile (in crs() units).
void setLockAxisScales(bool lock)
Sets whether the distance and elevation scales are locked to each other.
QgsElevationProfile(QgsProject *project)
Constructor for QgsElevationProfile.
QgsLineSymbol * subsectionsSymbol()
Returns the symbol used to draw the subsections.
void setSubsectionsSymbol(QgsLineSymbol *symbol)
Sets the symbol used to draw the subsections.
void nameChanged(const QString &newName)
Emitted when the profile is renamed.
void setDistanceUnit(Qgis::DistanceUnit unit)
Sets the distance unit used by the profile.
QgsCurve * profileCurve() const
Returns the profile curve.
void resolveReferences(const QgsProject *project)
After reading settings from XML, resolves references to any layers in a project that have been read a...
void setTolerance(double tolerance)
Sets the profile tolerance (in crs() units).
QIcon icon() const
Returns the icon to use for the elevation profile.
bool lockAxisScales() const
Returns true if the distance and elevation scales are locked to each other.
QString name() const
Returns the profile's unique name.
Qgis::DistanceUnit distanceUnit() const
Returns the distance unit used by the profile.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs associated with the profile's map coordinates.
QgsLayerTree * layerTree()
Returns the layer tree used by the profile.
void setProfileCurve(QgsCurve *curve)
Sets the profile curve.
bool readXml(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context)
Sets the profiles's state from a DOM element.
~QgsElevationProfile() override
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static Q_INVOKABLE QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
void nameChanged(QgsLayerTreeNode *node, QString name)
Emitted when the name of the node is changed.
void visibilityChanged(QgsLayerTreeNode *node)
Emitted when check state of a node within the tree has been changed.
Namespace with helper functions for layer tree operations.
static std::unique_ptr< QgsLayerTree > readXml(const QDomElement &element, const QgsReadWriteContext &context)
Load the layer tree from an XML element.
void layerOrderChanged()
Emitted when the layer order has changed.
A line symbol type, for rendering LineString and MultiLineString geometries.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:109
A container for the context for various read/write operations on objects.
static std::unique_ptr< QgsSymbol > loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
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:6817
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:6798
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6607
T qgsgeometry_cast(QgsAbstractGeometry *geom)