QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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#include "qgsgeometryutils.h"
18#include "qgslinestring.h"
19#include "qgspolygon.h"
20#include "qgscurvepolygon.h"
21#include "qgsmultilinestring.h"
22
23#include <QJsonObject>
24#include <nlohmann/json.hpp>
25
27{
29}
30
32{
33 return qgsgeometry_cast< QgsPolygon * >( geometryN( index ) );
34}
35
36const QgsPolygon *QgsMultiPolygon::polygonN( int index ) const
37{
38 return qgsgeometry_cast< const QgsPolygon * >( geometryN( index ) );
39}
40
42{
43 return QStringLiteral( "MultiPolygon" );
44}
45
47{
50}
51
53{
54 auto result = std::make_unique< QgsMultiPolygon >();
55 result->mWkbType = mWkbType;
56 return result.release();
57}
58
60{
61 return new QgsMultiPolygon( *this );
62}
63
64bool QgsMultiPolygon::fromWkt( const QString &wkt )
65{
66 return fromCollectionWkt( wkt, QVector<QgsAbstractGeometry *>() << new QgsPolygon, QStringLiteral( "Polygon" ) );
67}
68
69QDomElement QgsMultiPolygon::asGml2( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
70{
71 // GML2 does not support curves
72 QDomElement elemMultiPolygon = doc.createElementNS( ns, QStringLiteral( "MultiPolygon" ) );
73
74 if ( isEmpty() )
75 return elemMultiPolygon;
76
77 for ( const QgsAbstractGeometry *geom : mGeometries )
78 {
79 if ( qgsgeometry_cast<const QgsPolygon *>( geom ) )
80 {
81 QDomElement elemPolygonMember = doc.createElementNS( ns, QStringLiteral( "polygonMember" ) );
82 elemPolygonMember.appendChild( geom->asGml2( doc, precision, ns, axisOrder ) );
83 elemMultiPolygon.appendChild( elemPolygonMember );
84 }
85 }
86
87 return elemMultiPolygon;
88}
89
90QDomElement QgsMultiPolygon::asGml3( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
91{
92 QDomElement elemMultiSurface = doc.createElementNS( ns, QStringLiteral( "MultiSurface" ) );
93
94 if ( isEmpty() )
95 return elemMultiSurface;
96
97 for ( const QgsAbstractGeometry *geom : mGeometries )
98 {
99 if ( qgsgeometry_cast<const QgsPolygon *>( geom ) )
100 {
101 QDomElement elemSurfaceMember = doc.createElementNS( ns, QStringLiteral( "surfaceMember" ) );
102 elemSurfaceMember.appendChild( geom->asGml3( doc, precision, ns, axisOrder ) );
103 elemMultiSurface.appendChild( elemSurfaceMember );
104 }
105 }
106
107 return elemMultiSurface;
108}
109
111{
112 json polygons( json::array( ) );
113 for ( const QgsAbstractGeometry *geom : std::as_const( mGeometries ) )
114 {
115 if ( qgsgeometry_cast<const QgsPolygon *>( geom ) )
116 {
117 json coordinates( json::array( ) );
118 const QgsPolygon *polygon = static_cast<const QgsPolygon *>( geom );
119
120 std::unique_ptr< QgsLineString > exteriorLineString( polygon->exteriorRing()->curveToLine() );
121 QgsPointSequence exteriorPts;
122 exteriorLineString->points( exteriorPts );
123 coordinates.push_back( QgsGeometryUtils::pointsToJson( exteriorPts, precision ) );
124
125 std::unique_ptr< QgsLineString > interiorLineString;
126 for ( int i = 0, n = polygon->numInteriorRings(); i < n; ++i )
127 {
128 interiorLineString.reset( polygon->interiorRing( i )->curveToLine() );
129 QgsPointSequence interiorPts;
130 interiorLineString->points( interiorPts );
131 coordinates.push_back( QgsGeometryUtils::pointsToJson( interiorPts, precision ) );
132 }
133 polygons.push_back( coordinates );
134 }
135 }
136 return
137 {
138 { "type", "MultiPolygon" },
139 { "coordinates", polygons }
140 };
141}
142
144{
145 if ( !qgsgeometry_cast<QgsPolygon *>( g ) )
146 {
147 delete g;
148 return false;
149 }
150
151 if ( mGeometries.empty() )
152 {
154 }
155 if ( is3D() && !g->is3D() )
156 g->addZValue();
157 else if ( !is3D() && g->is3D() )
158 g->dropZValue();
159 if ( isMeasure() && !g->isMeasure() )
160 g->addMValue();
161 else if ( !isMeasure() && g->isMeasure() )
162 g->dropMValue();
163
164 return QgsGeometryCollection::addGeometry( g ); // NOLINT(bugprone-parent-virtual-call) clazy:exclude=skipped-base-method
165}
166
168{
169 if ( !g || !qgsgeometry_cast< QgsPolygon * >( g ) )
170 {
171 delete g;
172 return false;
173 }
174
175 return QgsMultiSurface::insertGeometry( g, index );
176}
177
179{
180 QgsMultiSurface *multiSurface = new QgsMultiSurface();
181 multiSurface->reserve( mGeometries.size() );
182 for ( int i = 0; i < mGeometries.size(); ++i )
183 {
184 multiSurface->addGeometry( mGeometries.at( i )->clone() );
185 }
186 return multiSurface;
187}
188
190{
191 std::unique_ptr< QgsMultiLineString > multiLine( new QgsMultiLineString() );
192 multiLine->reserve( mGeometries.size() );
193 for ( int i = 0; i < mGeometries.size(); ++i )
194 {
195 if ( QgsPolygon *polygon = qgsgeometry_cast<QgsPolygon *>( mGeometries.at( i ) ) )
196 {
197 QgsAbstractGeometry *polygonBoundary = polygon->boundary();
198
199 if ( QgsLineString *lineStringBoundary = qgsgeometry_cast< QgsLineString * >( polygonBoundary ) )
200 {
201 multiLine->addGeometry( lineStringBoundary );
202 }
203 else if ( QgsMultiLineString *multiLineStringBoundary = qgsgeometry_cast< QgsMultiLineString * >( polygonBoundary ) )
204 {
205 for ( int j = 0; j < multiLineStringBoundary->numGeometries(); ++j )
206 {
207 multiLine->addGeometry( multiLineStringBoundary->geometryN( j )->clone() );
208 }
209 delete multiLineStringBoundary;
210 }
211 else
212 {
213 delete polygonBoundary;
214 }
215 }
216 }
217 if ( multiLine->numGeometries() == 0 )
218 {
219 return nullptr;
220 }
221 return multiLine.release();
222}
223
225{
226 return true;
227}
@ MultiPolygon
MultiPolygon.
Abstract base class for all geometries.
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
virtual QgsAbstractGeometry * boundary() const =0
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
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.
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
void reserve(int size)
Attempts to allocate memory for at least size geometries.
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.
bool fromCollectionWkt(const QString &wkt, const QVector< QgsAbstractGeometry * > &subtypes, const QString &defaultChildWkbType=QString())
Reads a collection from a WKT string.
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.
Definition: qgslinestring.h:45
Multi line string geometry collection.
Multi polygon 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.
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...
Multi surface geometry collection.
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
QVector< QgsPoint > QgsPointSequence
int precision