QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgsmultipolygon.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmultipolygon.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 "qgsmultipolygon.h"
17
18#include <nlohmann/json.hpp>
19
20#include "qgscurvepolygon.h"
21#include "qgsgeometryutils.h"
22#include "qgslinestring.h"
23#include "qgsmultilinestring.h"
24#include "qgspolygon.h"
25
26#include <QJsonObject>
27#include <QString>
28
29using namespace Qt::StringLiterals;
30
35
36QgsMultiPolygon::QgsMultiPolygon( const QList<QgsPolygon> &polygons )
37{
38 if ( polygons.empty() )
39 return;
40
41 mGeometries.reserve( polygons.size() );
42 for ( const QgsPolygon &poly : polygons )
43 {
44 mGeometries.append( poly.clone() );
45 }
46
48}
49
50QgsMultiPolygon::QgsMultiPolygon( const QList<QgsPolygon *> &polygons )
51{
52 if ( polygons.empty() )
53 return;
54
55 mGeometries.reserve( polygons.size() );
56 for ( QgsPolygon *poly : polygons )
57 {
58 mGeometries.append( poly );
59 }
60
62}
63
68
69const QgsPolygon *QgsMultiPolygon::polygonN( int index ) const
70{
72}
73
75{
76 return u"MultiPolygon"_s;
77}
78
84
86{
87 auto result = std::make_unique< QgsMultiPolygon >();
88 result->mWkbType = mWkbType;
89 return result.release();
90}
91
93{
94 return new QgsMultiPolygon( *this );
95}
96
97bool QgsMultiPolygon::fromWkt( const QString &wkt )
98{
99 return fromCollectionWkt( wkt, { Qgis::WkbType::Polygon }, u"Polygon"_s );
100}
101
102QDomElement QgsMultiPolygon::asGml2( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
103{
104 // GML2 does not support curves
105 QDomElement elemMultiPolygon = doc.createElementNS( ns, u"MultiPolygon"_s );
106
107 if ( isEmpty() )
108 return elemMultiPolygon;
109
110 for ( const QgsAbstractGeometry *geom : mGeometries )
111 {
113 {
114 QDomElement elemPolygonMember = doc.createElementNS( ns, u"polygonMember"_s );
115 elemPolygonMember.appendChild( geom->asGml2( doc, precision, ns, axisOrder ) );
116 elemMultiPolygon.appendChild( elemPolygonMember );
117 }
118 }
119
120 return elemMultiPolygon;
121}
122
123QDomElement QgsMultiPolygon::asGml3( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
124{
125 QDomElement elemMultiSurface = doc.createElementNS( ns, u"MultiSurface"_s );
126
127 if ( isEmpty() )
128 return elemMultiSurface;
129
130 for ( const QgsAbstractGeometry *geom : mGeometries )
131 {
133 {
134 QDomElement elemSurfaceMember = doc.createElementNS( ns, u"surfaceMember"_s );
135 elemSurfaceMember.appendChild( geom->asGml3( doc, precision, ns, axisOrder ) );
136 elemMultiSurface.appendChild( elemSurfaceMember );
137 }
138 }
139
140 return elemMultiSurface;
141}
142
143json QgsMultiPolygon::asJsonObject( int precision ) const
144{
145 json polygons( json::array( ) );
146 for ( const QgsAbstractGeometry *geom : std::as_const( mGeometries ) )
147 {
149 {
150 json coordinates( json::array( ) );
151 const QgsPolygon *polygon = static_cast<const QgsPolygon *>( geom );
152
153 std::unique_ptr< QgsLineString > exteriorLineString( polygon->exteriorRing()->curveToLine() );
154 QgsPointSequence exteriorPts;
155 exteriorLineString->points( exteriorPts );
156 coordinates.push_back( QgsGeometryUtils::pointsToJson( exteriorPts, precision ) );
157
158 std::unique_ptr< QgsLineString > interiorLineString;
159 for ( int i = 0, n = polygon->numInteriorRings(); i < n; ++i )
160 {
161 interiorLineString.reset( polygon->interiorRing( i )->curveToLine() );
162 QgsPointSequence interiorPts;
163 interiorLineString->points( interiorPts );
164 coordinates.push_back( QgsGeometryUtils::pointsToJson( interiorPts, precision ) );
165 }
166 polygons.push_back( coordinates );
167 }
168 }
169 return
170 {
171 { "type", "MultiPolygon" },
172 { "coordinates", polygons }
173 };
174}
175
177{
179 {
180 delete g;
181 return false;
182 }
183
184 if ( mGeometries.empty() )
185 {
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
197 return QgsGeometryCollection::addGeometry( g ); // NOLINT(bugprone-parent-virtual-call) clazy:exclude=skipped-base-method
198}
199
200bool QgsMultiPolygon::addGeometries( const QVector<QgsAbstractGeometry *> &geometries )
201{
202 for ( QgsAbstractGeometry *g : geometries )
203 {
205 {
206 qDeleteAll( geometries );
207 return false;
208 }
209 }
210
211 if ( mGeometries.empty() && !geometries.empty() )
212 {
214 }
215 mGeometries.reserve( mGeometries.size() + geometries.size() );
216 for ( QgsAbstractGeometry *g : geometries )
217 {
218 if ( is3D() && !g->is3D() )
219 g->addZValue();
220 else if ( !is3D() && g->is3D() )
221 g->dropZValue();
222 if ( isMeasure() && !g->isMeasure() )
223 g->addMValue();
224 else if ( !isMeasure() && g->isMeasure() )
225 g->dropMValue();
226 mGeometries.append( g );
227 }
228
229 clearCache();
230 return true;
231}
232
234{
235 if ( !g || !qgsgeometry_cast< QgsPolygon * >( g ) )
236 {
237 delete g;
238 return false;
239 }
240
241 return QgsMultiSurface::insertGeometry( g, index );
242}
243
245{
246 auto res = std::make_unique< QgsMultiPolygon >();
247 res->reserve( mGeometries.size() );
248 for ( int i = 0; i < mGeometries.size(); ++i )
249 {
250 res->addGeometry( mGeometries.at( i )->simplifyByDistance( tolerance ) );
251 }
252 return res.release();
253}
254
256{
257 QgsMultiSurface *multiSurface = new QgsMultiSurface();
258 multiSurface->reserve( mGeometries.size() );
259 for ( int i = 0; i < mGeometries.size(); ++i )
260 {
261 multiSurface->addGeometry( mGeometries.at( i )->clone() );
262 }
263 return multiSurface;
264}
265
267{
268 auto multiLine = std::make_unique<QgsMultiLineString>();
269 multiLine->reserve( mGeometries.size() );
270 for ( int i = 0; i < mGeometries.size(); ++i )
271 {
272 if ( QgsPolygon *polygon = qgsgeometry_cast<QgsPolygon *>( mGeometries.at( i ) ) )
273 {
274 QgsAbstractGeometry *polygonBoundary = polygon->boundary();
275
276 if ( QgsLineString *lineStringBoundary = qgsgeometry_cast< QgsLineString * >( polygonBoundary ) )
277 {
278 multiLine->addGeometry( lineStringBoundary );
279 }
280 else if ( QgsMultiLineString *multiLineStringBoundary = qgsgeometry_cast< QgsMultiLineString * >( polygonBoundary ) )
281 {
282 for ( int j = 0; j < multiLineStringBoundary->numGeometries(); ++j )
283 {
284 multiLine->addGeometry( multiLineStringBoundary->geometryN( j )->clone() );
285 }
286 delete multiLineStringBoundary;
287 }
288 else
289 {
290 delete polygonBoundary;
291 }
292 }
293 }
294 if ( multiLine->numGeometries() == 0 )
295 {
296 return nullptr;
297 }
298 return multiLine.release();
299}
300
302{
303 return true;
304}
@ Polygon
Polygon.
Definition qgis.h:284
@ MultiPolygon
MultiPolygon.
Definition qgis.h:288
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 bool dropZValue()=0
Drops any z-dimensions which exist in the geometry.
QgsAbstractGeometry()=default
int numInteriorRings() const
Returns the number of interior rings contained with the curve polygon.
const QgsCurve * exteriorRing() const
Returns the curve polygon's exterior ring.
const QgsCurve * interiorRing(int i) const
Retrieves an interior ring from the curve polygon.
virtual QgsLineString * curveToLine(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const =0
Returns a new line string geometry corresponding to a segmentized approximation of the curve.
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 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.
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.
Line string geometry type, with support for z-dimension and m-values.
Multi line string geometry collection.
bool wktOmitChildType() const override
Returns whether child type names are omitted from Wkt representations of the collection.
bool insertGeometry(QgsAbstractGeometry *g, int index) override
Inserts a geometry before a specified index and takes ownership.
QgsMultiSurface * toCurveType() const override
Returns the geometry converted to the more generic curve type QgsMultiSurface.
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.
QgsMultiPolygon * simplifyByDistance(double tolerance) const override
Simplifies the geometry by applying the Douglas Peucker simplification by distance algorithm.
bool addGeometries(const QVector< QgsAbstractGeometry * > &geometries) final
Adds a list of geometries to the collection, transferring ownership to the collection.
void clear() override
Clears the geometry, ie reset it to a null geometry.
QgsMultiPolygon()
Constructor for an empty multipolygon geometry.
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.
QString geometryType() const override
Returns a unique string representing the geometry type.
QgsMultiPolygon * clone() const override
Clones the geometry by performing a deep copy.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
json asJsonObject(int precision=17) const override
Returns a json object representation of the geometry.
QgsPolygon * polygonN(int index)
Returns the polygon with the specified index.
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
QgsMultiPolygon * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
QgsAbstractGeometry * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
QgsMultiSurface()
Constructor for an empty multisurface geometry.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
bool insertGeometry(QgsAbstractGeometry *g, int index) override
Inserts a geometry before a specified index and takes ownership.
void clear() override
Clears the geometry, ie reset it to a null geometry.
Polygon geometry type.
Definition qgspolygon.h:37
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsPoint > QgsPointSequence