QGIS API Documentation 4.3.0-Master (c8cdfe19d7b)
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#include <QString>
31
32using namespace Qt::StringLiterals;
33
38
40{
42}
43
44const QgsCurve *QgsMultiCurve::curveN( int index ) const
45{
47}
48
50{
51 return u"MultiCurve"_s;
52}
53
55{
56 auto result = std::make_unique< QgsMultiCurve >();
57 result->mWkbType = mWkbType;
58 return result.release();
59}
60
62{
63 return new QgsMultiCurve( *this );
64}
65
71
73{
74 return clone();
75}
76
81
82QDomElement QgsMultiCurve::asGml2( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
83{
84 // GML2 does not support curves
85 QDomElement elemMultiLineString = doc.createElementNS( ns, u"MultiLineString"_s );
86
87 if ( isEmpty() )
88 return elemMultiLineString;
89
90 for ( const QgsAbstractGeometry *geom : mGeometries )
91 {
93 {
94 std::unique_ptr< QgsLineString > lineString( static_cast<const QgsCurve *>( geom )->curveToLine() );
95
96 QDomElement elemLineStringMember = doc.createElementNS( ns, u"lineStringMember"_s );
97 elemLineStringMember.appendChild( lineString->asGml2( doc, precision, ns, axisOrder ) );
98 elemMultiLineString.appendChild( elemLineStringMember );
99 }
100 }
101
102 return elemMultiLineString;
103}
104
105QDomElement QgsMultiCurve::asGml3( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
106{
107 QDomElement elemMultiCurve = doc.createElementNS( ns, u"MultiCurve"_s );
108
109 if ( isEmpty() )
110 return elemMultiCurve;
111
112 for ( const QgsAbstractGeometry *geom : mGeometries )
113 {
115 {
116 const QgsCurve *curve = static_cast<const QgsCurve *>( geom );
117
118 QDomElement elemCurveMember = doc.createElementNS( ns, u"curveMember"_s );
119 elemCurveMember.appendChild( curve->asGml3( doc, precision, ns, axisOrder ) );
120 elemMultiCurve.appendChild( elemCurveMember );
121 }
122 }
123
124 return elemMultiCurve;
125}
126
127json QgsMultiCurve::asJsonObject( int precision, Qgis::GeoJsonProfile profile ) const
128{
129 switch ( profile )
130 {
133 {
134 json coordinates( json::array() );
135 for ( const QgsAbstractGeometry *geom : std::as_const( mGeometries ) )
136 {
137 if ( auto curveGeom = qgsgeometry_cast<const QgsCurve *>( geom ) )
138 {
139 std::unique_ptr< QgsLineString > lineString( curveGeom->curveToLine() );
141 lineString->points( pts );
142 coordinates.push_back( QgsGeometryUtils::pointsToJson( pts, precision, profile ) );
143 }
144 }
145 return { { "type", "MultiLineString" }, { "coordinates", coordinates } };
146 }
149 {
150 json geometries( json::array() );
151 for ( const QgsAbstractGeometry *geom : std::as_const( mGeometries ) )
152 {
153 if ( auto curveGeom = qgsgeometry_cast<const QgsCurve *>( geom ) )
154 {
155 geometries.push_back( curveGeom->asJsonObject( precision, profile ) );
156 }
157 }
158 return { { "type", "MultiCurve" }, { "geometries", geometries } };
159 }
160 }
162}
163
165{
167 {
168 delete g;
169 return false;
170 }
171
172 //As it is a fresh type and not supported by other software, NurbsCurve not allowed in MultiCurves at the moment
173 const Qgis::WkbType flatType = QgsWkbTypes::flatType( g->wkbType() );
174 if ( !( flatType == Qgis::WkbType::LineString || flatType == Qgis::WkbType::CircularString || flatType == Qgis::WkbType::CompoundCurve ) )
175 {
176 delete g;
177 return false;
178 }
179
180 if ( mGeometries.empty() )
181 {
183 }
184 if ( is3D() && !g->is3D() )
185 g->addZValue();
186 else if ( !is3D() && g->is3D() )
187 g->dropZValue();
188 if ( isMeasure() && !g->isMeasure() )
189 g->addMValue();
190 else if ( !isMeasure() && g->isMeasure() )
191 g->dropMValue();
192
194}
195
196bool QgsMultiCurve::addGeometries( const QVector<QgsAbstractGeometry *> &geometries )
197{
198 for ( QgsAbstractGeometry *g : geometries )
199 {
201 {
202 qDeleteAll( geometries );
203 return false;
204 }
205
206 //As it is a fresh type and not supported by other software, NurbsCurve not allowed in MultiCurves at the moment
207 const Qgis::WkbType flatType = QgsWkbTypes::flatType( g->wkbType() );
208 if ( !( flatType == Qgis::WkbType::LineString || flatType == Qgis::WkbType::CircularString || flatType == Qgis::WkbType::CompoundCurve ) )
209 {
210 qDeleteAll( geometries );
211 return false;
212 }
213 }
214
215 if ( mGeometries.empty() && !geometries.empty() )
216 {
218 }
219 mGeometries.reserve( mGeometries.size() + geometries.size() );
220 for ( QgsAbstractGeometry *g : geometries )
221 {
222 if ( is3D() && !g->is3D() )
223 g->addZValue();
224 else if ( !is3D() && g->is3D() )
225 g->dropZValue();
226 if ( isMeasure() && !g->isMeasure() )
227 g->addMValue();
228 else if ( !isMeasure() && g->isMeasure() )
229 g->dropMValue();
230 mGeometries.append( g );
231 }
232
233 clearCache();
234 return true;
235}
236
238{
239 if ( !g || !qgsgeometry_cast<QgsCurve *>( g ) )
240 {
241 delete g;
242 return false;
243 }
244
245 //As it is a fresh type and not supported by other software, NurbsCurve not allowed in MultiCurves at the moment
246 const Qgis::WkbType flatType = QgsWkbTypes::flatType( g->wkbType() );
247 if ( !( flatType == Qgis::WkbType::LineString || flatType == Qgis::WkbType::CircularString || flatType == Qgis::WkbType::CompoundCurve ) )
248 {
249 delete g;
250 return false;
251 }
252
253 return QgsGeometryCollection::insertGeometry( g, index );
254}
255
257{
258 auto res = std::make_unique< QgsMultiCurve >();
259 res->reserve( mGeometries.size() );
260 for ( int i = 0; i < mGeometries.size(); ++i )
261 {
262 res->addGeometry( mGeometries.at( i )->simplifyByDistance( tolerance ) );
263 }
264 return res.release();
265}
266
267std::unique_ptr<QgsMultiCurve> QgsMultiCurve::reversed() const
268{
269 auto reversedMultiCurve = std::make_unique<QgsMultiCurve>();
270 reversedMultiCurve->reserve( mGeometries.size() );
271 for ( const QgsAbstractGeometry *geom : mGeometries )
272 {
274 {
275 reversedMultiCurve->addGeometry( static_cast<const QgsCurve *>( geom )->reversed() );
276 }
277 }
278 return reversedMultiCurve;
279}
280
282{
283 auto multiPoint = std::make_unique<QgsMultiPoint>();
284 multiPoint->reserve( mGeometries.size() * 2 );
285 for ( int i = 0; i < mGeometries.size(); ++i )
286 {
287 if ( QgsCurve *curve = qgsgeometry_cast<QgsCurve *>( mGeometries.at( i ) ) )
288 {
289 if ( !curve->isClosed() )
290 {
291 multiPoint->addGeometry( new QgsPoint( curve->startPoint() ) );
292 multiPoint->addGeometry( new QgsPoint( curve->endPoint() ) );
293 }
294 }
295 }
296 if ( multiPoint->numGeometries() == 0 )
297 {
298 return nullptr;
299 }
300 return multiPoint.release();
301}
GeoJsonProfile
GeoJson export Profile according to OGC Features and Geometries JSON - Part 1: Core https://docs....
Definition qgis.h:5146
@ Legacy
Legacy GeoJson profile used in QGIS prior to 4.2, which included some non-standard extensions and dev...
Definition qgis.h:5147
@ Rfc7946
GeoJson profile compliant with RFC7946 standard "http://www.opengis.net/def/profile/OGC/0/rfc7946".
Definition qgis.h:5148
@ JsonFg
GeoJson profile from OGC Features and Geometries JSON Part 1: core "http://www.opengis....
Definition qgis.h:5149
@ JsonFgPlus
GeoJson profile from OGC Features and Geometries JSON Part 1: core "http://www.opengis....
Definition qgis.h:5150
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:314
@ CompoundCurve
CompoundCurve.
Definition qgis.h:325
@ LineString
LineString.
Definition qgis.h:317
@ CircularString
CircularString.
Definition qgis.h:324
@ MultiCurve
MultiCurve.
Definition qgis.h:327
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.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
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 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, Qgis::GeoJsonProfile profile)
Returns coordinates as json object.
std::unique_ptr< QgsMultiCurve > reversed() const
Returns a copy of the multi curve, where each component curve has had its line direction reversed.
QString geometryType() const override
Returns a unique string representing the geometry type.
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.
json asJsonObject(int precision=17, Qgis::GeoJsonProfile profile=Qgis::GeoJsonProfile::Legacy) const override
Returns a json object representation of the geometry with the given precision and profile.
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:53
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
#define BUILTIN_UNREACHABLE
Definition qgis.h:8467
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsPoint > QgsPointSequence