QGIS API Documentation 3.99.0-Master (752b475928d)
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 if ( !mUseProjectLayerTree )
59 {
60 mLayerTree->writeXml( profileElem, context );
61 }
62 else
63 {
64 profileElem.setAttribute( QStringLiteral( "useProjectLayerTree" ), QStringLiteral( "1" ) );
65 }
66
67 if ( mSubsectionsSymbol )
68 {
69 QDomElement subsectionsElement = document.createElement( QStringLiteral( "subsections" ) );
70 const QDomElement symbolElement = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "subsections" ), mSubsectionsSymbol.get(), document, context );
71 subsectionsElement.appendChild( symbolElement );
72 profileElem.appendChild( subsectionsElement );
73 }
74
75 return profileElem;
76}
77
78bool QgsElevationProfile::readXml( const QDomElement &element, const QDomDocument &, const QgsReadWriteContext &context )
79{
80 if ( element.nodeName() != QLatin1String( "ElevationProfile" ) )
81 {
82 return false;
83 }
84
85 setName( element.attribute( QStringLiteral( "name" ) ) );
86
87 const QDomNodeList crsNodeList = element.elementsByTagName( QStringLiteral( "crs" ) );
89 if ( !crsNodeList.isEmpty() )
90 {
91 const QDomElement crsElem = crsNodeList.at( 0 ).toElement();
92 crs.readXml( crsElem );
93 }
94 mCrs = crs;
95
96 setDistanceUnit( qgsEnumKeyToValue( element.attribute( QStringLiteral( "distanceUnit" ) ), mCrs.mapUnits() ) );
97
98 const QDomNodeList curveNodeList = element.elementsByTagName( QStringLiteral( "curve" ) );
99 if ( !curveNodeList.isEmpty() )
100 {
101 const QDomElement curveElem = curveNodeList.at( 0 ).toElement();
102 const QgsGeometry curve = QgsGeometry::fromWkt( curveElem.text() );
103 // clang-tidy false positive
104 // NOLINTBEGIN(bugprone-branch-clone)
105 if ( const QgsCurve *curveGeom = qgsgeometry_cast< const QgsCurve * >( curve.constGet() ) )
106 {
107 mProfileCurve.reset( curveGeom->clone() );
108 }
109 else
110 {
111 mProfileCurve.reset();
112 }
113 // NOLINTEND(bugprone-branch-clone)
114 }
115
116 mTolerance = element.attribute( QStringLiteral( "tolerance" ) ).toDouble();
117 mLockAxisScales = element.attribute( QStringLiteral( "lockAxisScales" ), QStringLiteral( "0" ) ).toInt();
118
119 setUseProjectLayerTree( element.attribute( QStringLiteral( "useProjectLayerTree" ), QStringLiteral( "0" ) ).toInt() );
120 if ( !mUseProjectLayerTree )
121 {
122 const QDomElement layerTreeElem = element.firstChildElement( QStringLiteral( "layer-tree-group" ) );
123 mLayerTree = QgsLayerTree::readXml( layerTreeElem, context );
124 setupLayerTreeConnections();
125 }
126
127 const QDomElement subsectionsElement = element.firstChildElement( QStringLiteral( "subsections" ) );
128 const QDomElement symbolsElement = subsectionsElement.firstChildElement( QStringLiteral( "symbol" ) );
129 if ( !symbolsElement.isNull() )
130 {
131 std::unique_ptr< QgsLineSymbol > subSectionsSymbol = QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol >( symbolsElement, context );
132 if ( subSectionsSymbol )
133 {
134 setSubsectionsSymbol( subSectionsSymbol.release() );
135 }
136 }
137
138 return true;
139}
140
142{
143 mLayerTree->resolveReferences( project );
144}
145
147{
148 return QIcon();
149}
150
152{
153 return !mUseProjectLayerTree ? mLayerTree.get() : nullptr;
154}
155
157{
158 if ( mCrs == crs )
159 return;
160
161 mCrs = crs;
162 dirtyProject();
163}
164
169
171{
172 if ( curve == mProfileCurve.get() )
173 return;
174 mProfileCurve.reset( curve );
175 dirtyProject();
176}
177
179{
180 return mProfileCurve.get();
181}
182
184{
185 if ( qgsDoubleNear( tolerance, mTolerance ) )
186 return;
187
188 mTolerance = tolerance;
189 dirtyProject();
190}
191
193{
194 return mTolerance;
195}
196
198{
199 return mLockAxisScales;
200}
201
203{
204 return mDistanceUnit;
205}
206
208{
209 if ( lock == mLockAxisScales )
210 return;
211
212 mLockAxisScales = lock;
213 dirtyProject();
214}
215
217{
218 if ( mDistanceUnit == unit )
219 return;
220
221 mDistanceUnit = unit;
222 dirtyProject();
223}
224
226{
227 if ( mUseProjectLayerTree == useProjectTree )
228 return;
229
230 mUseProjectLayerTree = useProjectTree;
231 emit useProjectLayerTreeChanged( mUseProjectLayerTree );
232 dirtyProject();
233}
234
235void QgsElevationProfile::dirtyProject()
236{
237 if ( mProject )
238 mProject->setDirty();
239}
240
241void QgsElevationProfile::setupLayerTreeConnections()
242{
243 connect( mLayerTree.get(), &QgsLayerTree::layerOrderChanged, this, &QgsElevationProfile::dirtyProject );
244 connect( mLayerTree.get(), &QgsLayerTree::visibilityChanged, this, &QgsElevationProfile::dirtyProject );
245 connect( mLayerTree.get(), &QgsLayerTree::nameChanged, this, &QgsElevationProfile::dirtyProject );
246}
247
249{
250 return mSubsectionsSymbol.get();
251}
252
254{
255 if ( symbol == mSubsectionsSymbol.get() )
256 return;
257
258 mSubsectionsSymbol.reset( symbol );
259 dirtyProject();
260}
261
262void QgsElevationProfile::setName( const QString &name )
263{
264 if ( name == mName )
265 return;
266
267 mName = name;
268 dirtyProject();
269 emit nameChanged( mName );
270}
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 useProjectLayerTreeChanged(bool useProjectTree)
Emitted when the use project layer tree property is changed.
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.
void setUseProjectLayerTree(bool useProjectTree)
Sets whether the profile should always use the project's layer tree.
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)