QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
32
33QgsMultiPolygon::QgsMultiPolygon( const QList<QgsPolygon> &polygons )
34{
35 if ( polygons.empty() )
36 return;
37
38 mGeometries.reserve( polygons.size() );
39 for ( const QgsPolygon &poly : polygons )
40 {
41 mGeometries.append( poly.clone() );
42 }
43
45}
46
47QgsMultiPolygon::QgsMultiPolygon( const QList<QgsPolygon *> &polygons )
48{
49 if ( polygons.empty() )
50 return;
51
52 mGeometries.reserve( polygons.size() );
53 for ( QgsPolygon *poly : polygons )
54 {
55 mGeometries.append( poly );
56 }
57
59}
60
65
66const QgsPolygon *QgsMultiPolygon::polygonN( int index ) const
67{
69}
70
72{
73 return QStringLiteral( "MultiPolygon" );
74}
75
81
83{
84 auto result = std::make_unique< QgsMultiPolygon >();
85 result->mWkbType = mWkbType;
86 return result.release();
87}
88
90{
91 return new QgsMultiPolygon( *this );
92}
93
94bool QgsMultiPolygon::fromWkt( const QString &wkt )
95{
96 return fromCollectionWkt( wkt, { Qgis::WkbType::Polygon }, QStringLiteral( "Polygon" ) );
97}
98
99QDomElement QgsMultiPolygon::asGml2( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
100{
101 // GML2 does not support curves
102 QDomElement elemMultiPolygon = doc.createElementNS( ns, QStringLiteral( "MultiPolygon" ) );
103
104 if ( isEmpty() )
105 return elemMultiPolygon;
106
107 for ( const QgsAbstractGeometry *geom : mGeometries )
108 {
110 {
111 QDomElement elemPolygonMember = doc.createElementNS( ns, QStringLiteral( "polygonMember" ) );
112 elemPolygonMember.appendChild( geom->asGml2( doc, precision, ns, axisOrder ) );
113 elemMultiPolygon.appendChild( elemPolygonMember );
114 }
115 }
116
117 return elemMultiPolygon;
118}
119
120QDomElement QgsMultiPolygon::asGml3( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
121{
122 QDomElement elemMultiSurface = doc.createElementNS( ns, QStringLiteral( "MultiSurface" ) );
123
124 if ( isEmpty() )
125 return elemMultiSurface;
126
127 for ( const QgsAbstractGeometry *geom : mGeometries )
128 {
130 {
131 QDomElement elemSurfaceMember = doc.createElementNS( ns, QStringLiteral( "surfaceMember" ) );
132 elemSurfaceMember.appendChild( geom->asGml3( doc, precision, ns, axisOrder ) );
133 elemMultiSurface.appendChild( elemSurfaceMember );
134 }
135 }
136
137 return elemMultiSurface;
138}
139
140json QgsMultiPolygon::asJsonObject( int precision ) const
141{
142 json polygons( json::array( ) );
143 for ( const QgsAbstractGeometry *geom : std::as_const( mGeometries ) )
144 {
146 {
147 json coordinates( json::array( ) );
148 const QgsPolygon *polygon = static_cast<const QgsPolygon *>( geom );
149
150 std::unique_ptr< QgsLineString > exteriorLineString( polygon->exteriorRing()->curveToLine() );
151 QgsPointSequence exteriorPts;
152 exteriorLineString->points( exteriorPts );
153 coordinates.push_back( QgsGeometryUtils::pointsToJson( exteriorPts, precision ) );
154
155 std::unique_ptr< QgsLineString > interiorLineString;
156 for ( int i = 0, n = polygon->numInteriorRings(); i < n; ++i )
157 {
158 interiorLineString.reset( polygon->interiorRing( i )->curveToLine() );
159 QgsPointSequence interiorPts;
160 interiorLineString->points( interiorPts );
161 coordinates.push_back( QgsGeometryUtils::pointsToJson( interiorPts, precision ) );
162 }
163 polygons.push_back( coordinates );
164 }
165 }
166 return
167 {
168 { "type", "MultiPolygon" },
169 { "coordinates", polygons }
170 };
171}
172
174{
176 {
177 delete g;
178 return false;
179 }
180
181 if ( mGeometries.empty() )
182 {
184 }
185 if ( is3D() && !g->is3D() )
186 g->addZValue();
187 else if ( !is3D() && g->is3D() )
188 g->dropZValue();
189 if ( isMeasure() && !g->isMeasure() )
190 g->addMValue();
191 else if ( !isMeasure() && g->isMeasure() )
192 g->dropMValue();
193
194 return QgsGeometryCollection::addGeometry( g ); // NOLINT(bugprone-parent-virtual-call) clazy:exclude=skipped-base-method
195}
196
197bool QgsMultiPolygon::addGeometries( const QVector<QgsAbstractGeometry *> &geometries )
198{
199 for ( QgsAbstractGeometry *g : geometries )
200 {
202 {
203 qDeleteAll( geometries );
204 return false;
205 }
206 }
207
208 if ( mGeometries.empty() && !geometries.empty() )
209 {
211 }
212 mGeometries.reserve( mGeometries.size() + geometries.size() );
213 for ( QgsAbstractGeometry *g : geometries )
214 {
215 if ( is3D() && !g->is3D() )
216 g->addZValue();
217 else if ( !is3D() && g->is3D() )
218 g->dropZValue();
219 if ( isMeasure() && !g->isMeasure() )
220 g->addMValue();
221 else if ( !isMeasure() && g->isMeasure() )
222 g->dropMValue();
223 mGeometries.append( g );
224 }
225
226 clearCache();
227 return true;
228}
229
231{
232 if ( !g || !qgsgeometry_cast< QgsPolygon * >( g ) )
233 {
234 delete g;
235 return false;
236 }
237
238 return QgsMultiSurface::insertGeometry( g, index );
239}
240
242{
243 auto res = std::make_unique< QgsMultiPolygon >();
244 res->reserve( mGeometries.size() );
245 for ( int i = 0; i < mGeometries.size(); ++i )
246 {
247 res->addGeometry( mGeometries.at( i )->simplifyByDistance( tolerance ) );
248 }
249 return res.release();
250}
251
253{
254 QgsMultiSurface *multiSurface = new QgsMultiSurface();
255 multiSurface->reserve( mGeometries.size() );
256 for ( int i = 0; i < mGeometries.size(); ++i )
257 {
258 multiSurface->addGeometry( mGeometries.at( i )->clone() );
259 }
260 return multiSurface;
261}
262
264{
265 auto multiLine = std::make_unique<QgsMultiLineString>();
266 multiLine->reserve( mGeometries.size() );
267 for ( int i = 0; i < mGeometries.size(); ++i )
268 {
269 if ( QgsPolygon *polygon = qgsgeometry_cast<QgsPolygon *>( mGeometries.at( i ) ) )
270 {
271 QgsAbstractGeometry *polygonBoundary = polygon->boundary();
272
273 if ( QgsLineString *lineStringBoundary = qgsgeometry_cast< QgsLineString * >( polygonBoundary ) )
274 {
275 multiLine->addGeometry( lineStringBoundary );
276 }
277 else if ( QgsMultiLineString *multiLineStringBoundary = qgsgeometry_cast< QgsMultiLineString * >( polygonBoundary ) )
278 {
279 for ( int j = 0; j < multiLineStringBoundary->numGeometries(); ++j )
280 {
281 multiLine->addGeometry( multiLineStringBoundary->geometryN( j )->clone() );
282 }
283 delete multiLineStringBoundary;
284 }
285 else
286 {
287 delete polygonBoundary;
288 }
289 }
290 }
291 if ( multiLine->numGeometries() == 0 )
292 {
293 return nullptr;
294 }
295 return multiLine.release();
296}
297
299{
300 return true;
301}
@ Polygon
Polygon.
Definition qgis.h:281
@ MultiPolygon
MultiPolygon.
Definition qgis.h:285
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:33
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsPoint > QgsPointSequence