QGIS API Documentation 4.3.0-Master (0978c174f8e)
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
268{
269 QgsMultiCurve *reversedMultiCurve = new 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:5061
@ Legacy
Legacy GeoJson profile used in QGIS prior to 4.2, which included some non-standard extensions and dev...
Definition qgis.h:5062
@ Rfc7946
GeoJson profile compliant with RFC7946 standard "http://www.opengis.net/def/profile/OGC/0/rfc7946".
Definition qgis.h:5063
@ JsonFg
GeoJson profile from OGC Features and Geometries JSON Part 1: core "http://www.opengis....
Definition qgis.h:5064
@ JsonFgPlus
GeoJson profile from OGC Features and Geometries JSON Part 1: core "http://www.opengis....
Definition qgis.h:5065
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:294
@ CompoundCurve
CompoundCurve.
Definition qgis.h:305
@ LineString
LineString.
Definition qgis.h:297
@ CircularString
CircularString.
Definition qgis.h:304
@ MultiCurve
MultiCurve.
Definition qgis.h:307
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 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, Qgis::GeoJsonProfile profile)
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.
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:8051
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsPoint > QgsPointSequence