QGIS API Documentation 3.41.0-Master (cea29feecf2)
Loading...
Searching...
No Matches
qgsmulticurve.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmulticurve.cpp
3 -------------------------------------------------------------------
4Date : 28 Oct 2014
5Copyright : (C) 2014 by Marco Hugentobler
6email : marco.hugentobler at sourcepole 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
16#include "qgsmulticurve.h"
17#include "qgsapplication.h"
18#include "qgscurve.h"
19#include "qgscircularstring.h"
20#include "qgscompoundcurve.h"
21#include "qgsgeometryutils.h"
22#include "qgslinestring.h"
23#include "qgsmultipoint.h"
24
25#include <QJsonObject>
26#include <memory>
27#include <nlohmann/json.hpp>
28
33
35{
36 return qgsgeometry_cast< QgsCurve * >( geometryN( index ) );
37}
38
39const QgsCurve *QgsMultiCurve::curveN( int index ) const
40{
41 return qgsgeometry_cast< const QgsCurve * >( geometryN( index ) );
42}
43
45{
46 return QStringLiteral( "MultiCurve" );
47}
48
50{
51 auto result = std::make_unique< QgsMultiCurve >();
52 result->mWkbType = mWkbType;
53 return result.release();
54}
55
57{
58 return new QgsMultiCurve( *this );
59}
60
66
68{
69 return clone();
70}
71
72bool QgsMultiCurve::fromWkt( const QString &wkt )
73{
74 return fromCollectionWkt( wkt,
75 QVector<QgsAbstractGeometry *>() << new QgsLineString << new QgsCircularString << new QgsCompoundCurve,
76 QStringLiteral( "LineString" ) );
77}
78
79QDomElement QgsMultiCurve::asGml2( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
80{
81 // GML2 does not support curves
82 QDomElement elemMultiLineString = doc.createElementNS( ns, QStringLiteral( "MultiLineString" ) );
83
84 if ( isEmpty() )
85 return elemMultiLineString;
86
87 for ( const QgsAbstractGeometry *geom : mGeometries )
88 {
89 if ( qgsgeometry_cast<const QgsCurve *>( geom ) )
90 {
91 std::unique_ptr< QgsLineString > lineString( static_cast<const QgsCurve *>( geom )->curveToLine() );
92
93 QDomElement elemLineStringMember = doc.createElementNS( ns, QStringLiteral( "lineStringMember" ) );
94 elemLineStringMember.appendChild( lineString->asGml2( doc, precision, ns, axisOrder ) );
95 elemMultiLineString.appendChild( elemLineStringMember );
96 }
97 }
98
99 return elemMultiLineString;
100}
101
102QDomElement QgsMultiCurve::asGml3( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
103{
104 QDomElement elemMultiCurve = doc.createElementNS( ns, QStringLiteral( "MultiCurve" ) );
105
106 if ( isEmpty() )
107 return elemMultiCurve;
108
109 for ( const QgsAbstractGeometry *geom : mGeometries )
110 {
111 if ( qgsgeometry_cast<const QgsCurve *>( geom ) )
112 {
113 const QgsCurve *curve = static_cast<const QgsCurve *>( geom );
114
115 QDomElement elemCurveMember = doc.createElementNS( ns, QStringLiteral( "curveMember" ) );
116 elemCurveMember.appendChild( curve->asGml3( doc, precision, ns, axisOrder ) );
117 elemMultiCurve.appendChild( elemCurveMember );
118 }
119 }
120
121 return elemMultiCurve;
122}
123
125{
126 json coordinates( json::array( ) );
127 for ( const QgsAbstractGeometry *geom : std::as_const( mGeometries ) )
128 {
129 if ( qgsgeometry_cast<const QgsCurve *>( geom ) )
130 {
131 std::unique_ptr< QgsLineString > lineString( static_cast<const QgsCurve *>( geom )->curveToLine() );
133 lineString->points( pts );
134 coordinates.push_back( QgsGeometryUtils::pointsToJson( pts, precision ) );
135 }
136 }
137 return
138 {
139 { "type", "MultiLineString" },
140 { "coordinates", coordinates }
141 };
142}
143
145{
146 if ( !qgsgeometry_cast<QgsCurve *>( g ) )
147 {
148 delete g;
149 return false;
150 }
151
152 if ( mGeometries.empty() )
153 {
155 }
156 if ( is3D() && !g->is3D() )
157 g->addZValue();
158 else if ( !is3D() && g->is3D() )
159 g->dropZValue();
160 if ( isMeasure() && !g->isMeasure() )
161 g->addMValue();
162 else if ( !isMeasure() && g->isMeasure() )
163 g->dropMValue();
164
166}
167
168bool QgsMultiCurve::addGeometries( const QVector<QgsAbstractGeometry *> &geometries )
169{
170 for ( QgsAbstractGeometry *g : geometries )
171 {
172 if ( !qgsgeometry_cast<QgsCurve *>( g ) )
173 {
174 qDeleteAll( geometries );
175 return false;
176 }
177 }
178
179 if ( mGeometries.empty() && !geometries.empty() )
180 {
182 }
183 mGeometries.reserve( mGeometries.size() + geometries.size() );
184 for ( QgsAbstractGeometry *g : geometries )
185 {
186 if ( is3D() && !g->is3D() )
187 g->addZValue();
188 else if ( !is3D() && g->is3D() )
189 g->dropZValue();
190 if ( isMeasure() && !g->isMeasure() )
191 g->addMValue();
192 else if ( !isMeasure() && g->isMeasure() )
193 g->dropMValue();
194 mGeometries.append( g );
195 }
196
197 clearCache();
198 return true;
199}
200
202{
203 if ( !g || !qgsgeometry_cast<QgsCurve *>( g ) )
204 {
205 delete g;
206 return false;
207 }
208
209 return QgsGeometryCollection::insertGeometry( g, index );
210}
211
213{
214 std::unique_ptr< QgsMultiCurve > res = std::make_unique< QgsMultiCurve >();
215 res->reserve( mGeometries.size() );
216 for ( int i = 0; i < mGeometries.size(); ++i )
217 {
218 res->addGeometry( mGeometries.at( i )->simplifyByDistance( tolerance ) );
219 }
220 return res.release();
221}
222
224{
225 QgsMultiCurve *reversedMultiCurve = new QgsMultiCurve();
226 reversedMultiCurve->reserve( mGeometries.size() );
227 for ( const QgsAbstractGeometry *geom : mGeometries )
228 {
229 if ( qgsgeometry_cast<const QgsCurve *>( geom ) )
230 {
231 reversedMultiCurve->addGeometry( static_cast<const QgsCurve *>( geom )->reversed() );
232 }
233 }
234 return reversedMultiCurve;
235}
236
238{
239 std::unique_ptr< QgsMultiPoint > multiPoint( new QgsMultiPoint() );
240 multiPoint->reserve( mGeometries.size() * 2 );
241 for ( int i = 0; i < mGeometries.size(); ++i )
242 {
243 if ( QgsCurve *curve = qgsgeometry_cast<QgsCurve *>( mGeometries.at( i ) ) )
244 {
245 if ( !curve->isClosed() )
246 {
247 multiPoint->addGeometry( new QgsPoint( curve->startPoint() ) );
248 multiPoint->addGeometry( new QgsPoint( curve->endPoint() ) );
249 }
250 }
251 }
252 if ( multiPoint->numGeometries() == 0 )
253 {
254 return nullptr;
255 }
256 return multiPoint.release();
257}
@ MultiCurve
MultiCurve.
Abstract base class for all geometries.
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
virtual bool dropMValue()=0
Drops any measure values which exist in the geometry.
bool isMeasure() const
Returns true if the geometry contains m values.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
AxisOrder
Axis order for GML generation.
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, Qgis::WkbType baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
virtual QDomElement asGml3(QDomDocument &doc, int precision=17, const QString &ns="gml", AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const =0
Returns a GML3 representation of the geometry.
virtual bool dropZValue()=0
Drops any z-dimensions which exist in the geometry.
Circular string geometry type.
Compound curve geometry type.
Abstract base class for curved geometry type.
Definition qgscurve.h:35
virtual QgsCurve * reversed() const =0
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
QVector< QgsAbstractGeometry * > mGeometries
void clear() override
Clears the geometry, ie reset it to a null geometry.
void reserve(int size)
Attempts to allocate memory for at least size geometries.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
virtual bool insertGeometry(QgsAbstractGeometry *g, int index)
Inserts a geometry before a specified index and takes ownership.
bool isEmpty() const override
Returns true if the geometry is empty.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
bool fromCollectionWkt(const QString &wkt, const QVector< QgsAbstractGeometry * > &subtypes, const QString &defaultChildWkbType=QString())
Reads a collection from a WKT string.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
static json pointsToJson(const QgsPointSequence &points, int precision)
Returns coordinates as json object.
Line string geometry type, with support for z-dimension and m-values.
Multi curve geometry collection.
QString geometryType() const override
Returns a unique string representing the geometry type.
QgsMultiCurve * reversed() const
Returns a copy of the multi curve, where each component curve has had its line direction reversed.
json asJsonObject(int precision=17) const override
Returns a json object representation of the geometry.
QgsMultiCurve * simplifyByDistance(double tolerance) const override
Simplifies the geometry by applying the Douglas Peucker simplification by distance algorithm.
QgsMultiCurve * toCurveType() const override
Returns the geometry converted to the more generic curve type.
QDomElement asGml2(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML2 representation of the geometry.
QgsAbstractGeometry * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
bool insertGeometry(QgsAbstractGeometry *g, int index) override
Inserts a geometry before a specified index and takes ownership.
QDomElement asGml3(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML3 representation of the geometry.
QgsMultiCurve * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
bool addGeometries(const QVector< QgsAbstractGeometry * > &geometries) override
Adds a list of geometries to the collection, transferring ownership to the collection.
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
QgsMultiCurve * clone() const override
Clones the geometry by performing a deep copy.
void clear() override
Clears the geometry, ie reset it to a null geometry.
QgsCurve * curveN(int index)
Returns the curve with the specified index.
Multi point geometry collection.
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:49
QVector< QgsPoint > QgsPointSequence
int precision