QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
18#include <memory>
19#include <nlohmann/json.hpp>
20
21#include "qgsapplication.h"
22#include "qgscircularstring.h"
23#include "qgscompoundcurve.h"
24#include "qgscurve.h"
25#include "qgsgeometryutils.h"
26#include "qgslinestring.h"
27#include "qgsmultipoint.h"
28
29#include <QJsonObject>
30
35
37{
39}
40
41const QgsCurve *QgsMultiCurve::curveN( int index ) const
42{
44}
45
47{
48 return QStringLiteral( "MultiCurve" );
49}
50
52{
53 auto result = std::make_unique< QgsMultiCurve >();
54 result->mWkbType = mWkbType;
55 return result.release();
56}
57
59{
60 return new QgsMultiCurve( *this );
61}
62
68
70{
71 return clone();
72}
73
74bool QgsMultiCurve::fromWkt( const QString &wkt )
75{
76 return fromCollectionWkt( wkt,
78 QStringLiteral( "LineString" ) );
79}
80
81QDomElement QgsMultiCurve::asGml2( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
82{
83 // GML2 does not support curves
84 QDomElement elemMultiLineString = doc.createElementNS( ns, QStringLiteral( "MultiLineString" ) );
85
86 if ( isEmpty() )
87 return elemMultiLineString;
88
89 for ( const QgsAbstractGeometry *geom : mGeometries )
90 {
92 {
93 std::unique_ptr< QgsLineString > lineString( static_cast<const QgsCurve *>( geom )->curveToLine() );
94
95 QDomElement elemLineStringMember = doc.createElementNS( ns, QStringLiteral( "lineStringMember" ) );
96 elemLineStringMember.appendChild( lineString->asGml2( doc, precision, ns, axisOrder ) );
97 elemMultiLineString.appendChild( elemLineStringMember );
98 }
99 }
100
101 return elemMultiLineString;
102}
103
104QDomElement QgsMultiCurve::asGml3( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
105{
106 QDomElement elemMultiCurve = doc.createElementNS( ns, QStringLiteral( "MultiCurve" ) );
107
108 if ( isEmpty() )
109 return elemMultiCurve;
110
111 for ( const QgsAbstractGeometry *geom : mGeometries )
112 {
114 {
115 const QgsCurve *curve = static_cast<const QgsCurve *>( geom );
116
117 QDomElement elemCurveMember = doc.createElementNS( ns, QStringLiteral( "curveMember" ) );
118 elemCurveMember.appendChild( curve->asGml3( doc, precision, ns, axisOrder ) );
119 elemMultiCurve.appendChild( elemCurveMember );
120 }
121 }
122
123 return elemMultiCurve;
124}
125
126json QgsMultiCurve::asJsonObject( int precision ) const
127{
128 json coordinates( json::array( ) );
129 for ( const QgsAbstractGeometry *geom : std::as_const( mGeometries ) )
130 {
132 {
133 std::unique_ptr< QgsLineString > lineString( static_cast<const QgsCurve *>( geom )->curveToLine() );
135 lineString->points( pts );
136 coordinates.push_back( QgsGeometryUtils::pointsToJson( pts, precision ) );
137 }
138 }
139 return
140 {
141 { "type", "MultiLineString" },
142 { "coordinates", coordinates }
143 };
144}
145
147{
149 {
150 delete g;
151 return false;
152 }
153
154 if ( mGeometries.empty() )
155 {
157 }
158 if ( is3D() && !g->is3D() )
159 g->addZValue();
160 else if ( !is3D() && g->is3D() )
161 g->dropZValue();
162 if ( isMeasure() && !g->isMeasure() )
163 g->addMValue();
164 else if ( !isMeasure() && g->isMeasure() )
165 g->dropMValue();
166
168}
169
170bool QgsMultiCurve::addGeometries( const QVector<QgsAbstractGeometry *> &geometries )
171{
172 for ( QgsAbstractGeometry *g : geometries )
173 {
175 {
176 qDeleteAll( geometries );
177 return false;
178 }
179 }
180
181 if ( mGeometries.empty() && !geometries.empty() )
182 {
184 }
185 mGeometries.reserve( mGeometries.size() + geometries.size() );
186 for ( QgsAbstractGeometry *g : geometries )
187 {
188 if ( is3D() && !g->is3D() )
189 g->addZValue();
190 else if ( !is3D() && g->is3D() )
191 g->dropZValue();
192 if ( isMeasure() && !g->isMeasure() )
193 g->addMValue();
194 else if ( !isMeasure() && g->isMeasure() )
195 g->dropMValue();
196 mGeometries.append( g );
197 }
198
199 clearCache();
200 return true;
201}
202
204{
205 if ( !g || !qgsgeometry_cast<QgsCurve *>( g ) )
206 {
207 delete g;
208 return false;
209 }
210
211 return QgsGeometryCollection::insertGeometry( g, index );
212}
213
215{
216 auto res = std::make_unique< QgsMultiCurve >();
217 res->reserve( mGeometries.size() );
218 for ( int i = 0; i < mGeometries.size(); ++i )
219 {
220 res->addGeometry( mGeometries.at( i )->simplifyByDistance( tolerance ) );
221 }
222 return res.release();
223}
224
226{
227 QgsMultiCurve *reversedMultiCurve = new QgsMultiCurve();
228 reversedMultiCurve->reserve( mGeometries.size() );
229 for ( const QgsAbstractGeometry *geom : mGeometries )
230 {
232 {
233 reversedMultiCurve->addGeometry( static_cast<const QgsCurve *>( geom )->reversed() );
234 }
235 }
236 return reversedMultiCurve;
237}
238
240{
241 auto multiPoint = std::make_unique<QgsMultiPoint>();
242 multiPoint->reserve( mGeometries.size() * 2 );
243 for ( int i = 0; i < mGeometries.size(); ++i )
244 {
245 if ( QgsCurve *curve = qgsgeometry_cast<QgsCurve *>( mGeometries.at( i ) ) )
246 {
247 if ( !curve->isClosed() )
248 {
249 multiPoint->addGeometry( new QgsPoint( curve->startPoint() ) );
250 multiPoint->addGeometry( new QgsPoint( curve->endPoint() ) );
251 }
252 }
253 }
254 if ( multiPoint->numGeometries() == 0 )
255 {
256 return nullptr;
257 }
258 return multiPoint.release();
259}
@ CompoundCurve
CompoundCurve.
Definition qgis.h:288
@ LineString
LineString.
Definition qgis.h:280
@ CircularString
CircularString.
Definition qgis.h:287
@ MultiCurve
MultiCurve.
Definition qgis.h:290
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.
QgsAbstractGeometry()=default
Abstract base class for curved geometry type.
Definition qgscurve.h:36
QVector< QgsAbstractGeometry * > mGeometries
bool fromCollectionWkt(const QString &wkt, const QVector< Qgis::WkbType > &subtypes, const QString &defaultChildWkbType=QString())
Reads a collection from a WKT string.
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.
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.
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.
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:49
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsPoint > QgsPointSequence