QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsmultipolygon.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmultipolygon.cpp
3  -------------------------------------------------------------------
4 Date : 28 Oct 2014
5 Copyright : (C) 2014 by Marco Hugentobler
6 email : 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 "qgsapplication.h"
18 #include "qgsgeometryutils.h"
19 #include "qgssurface.h"
20 #include "qgslinestring.h"
21 #include "qgspolygon.h"
22 #include "qgscurvepolygon.h"
23 #include "qgsmultilinestring.h"
24 
25 #include <QJsonObject>
26 #include <nlohmann/json.hpp>
27 
29 {
31 }
32 
34 {
35  return QStringLiteral( "MultiPolygon" );
36 }
37 
39 {
42 }
43 
45 {
46  auto result = qgis::make_unique< QgsMultiPolygon >();
47  result->mWkbType = mWkbType;
48  return result.release();
49 }
50 
52 {
53  return new QgsMultiPolygon( *this );
54 }
55 
56 bool QgsMultiPolygon::fromWkt( const QString &wkt )
57 {
58  return fromCollectionWkt( wkt, QVector<QgsAbstractGeometry *>() << new QgsPolygon, QStringLiteral( "Polygon" ) );
59 }
60 
61 QDomElement QgsMultiPolygon::asGml2( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
62 {
63  // GML2 does not support curves
64  QDomElement elemMultiPolygon = doc.createElementNS( ns, QStringLiteral( "MultiPolygon" ) );
65 
66  if ( isEmpty() )
67  return elemMultiPolygon;
68 
69  for ( const QgsAbstractGeometry *geom : mGeometries )
70  {
71  if ( qgsgeometry_cast<const QgsPolygon *>( geom ) )
72  {
73  QDomElement elemPolygonMember = doc.createElementNS( ns, QStringLiteral( "polygonMember" ) );
74  elemPolygonMember.appendChild( geom->asGml2( doc, precision, ns, axisOrder ) );
75  elemMultiPolygon.appendChild( elemPolygonMember );
76  }
77  }
78 
79  return elemMultiPolygon;
80 }
81 
82 QDomElement QgsMultiPolygon::asGml3( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
83 {
84  QDomElement elemMultiSurface = doc.createElementNS( ns, QStringLiteral( "MultiPolygon" ) );
85 
86  if ( isEmpty() )
87  return elemMultiSurface;
88 
89  for ( const QgsAbstractGeometry *geom : mGeometries )
90  {
91  if ( qgsgeometry_cast<const QgsPolygon *>( geom ) )
92  {
93  QDomElement elemSurfaceMember = doc.createElementNS( ns, QStringLiteral( "polygonMember" ) );
94  elemSurfaceMember.appendChild( geom->asGml3( doc, precision, ns, axisOrder ) );
95  elemMultiSurface.appendChild( elemSurfaceMember );
96  }
97  }
98 
99  return elemMultiSurface;
100 }
101 
103 {
104  json polygons( json::array( ) );
105  for ( const QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
106  {
107  if ( qgsgeometry_cast<const QgsPolygon *>( geom ) )
108  {
109  json coordinates( json::array( ) );
110  const QgsPolygon *polygon = static_cast<const QgsPolygon *>( geom );
111 
112  std::unique_ptr< QgsLineString > exteriorLineString( polygon->exteriorRing()->curveToLine() );
113  QgsPointSequence exteriorPts;
114  exteriorLineString->points( exteriorPts );
115  coordinates.push_back( QgsGeometryUtils::pointsToJson( exteriorPts, precision ) );
116 
117  std::unique_ptr< QgsLineString > interiorLineString;
118  for ( int i = 0, n = polygon->numInteriorRings(); i < n; ++i )
119  {
120  interiorLineString.reset( polygon->interiorRing( i )->curveToLine() );
121  QgsPointSequence interiorPts;
122  interiorLineString->points( interiorPts );
123  coordinates.push_back( QgsGeometryUtils::pointsToJson( interiorPts, precision ) );
124  }
125  polygons.push_back( coordinates );
126  }
127  }
128  return
129  {
130  { "type", "MultiPolygon" },
131  { "coordinates", polygons }
132  };
133 }
134 
136 {
137  if ( !qgsgeometry_cast<QgsPolygon *>( g ) )
138  {
139  delete g;
140  return false;
141  }
142 
143  if ( mGeometries.empty() )
144  {
146  }
147  if ( is3D() && !g->is3D() )
148  g->addZValue();
149  else if ( !is3D() && g->is3D() )
150  g->dropZValue();
151  if ( isMeasure() && !g->isMeasure() )
152  g->addMValue();
153  else if ( !isMeasure() && g->isMeasure() )
154  g->dropMValue();
155 
156  return QgsGeometryCollection::addGeometry( g ); // clazy:exclude=skipped-base-method
157 }
158 
160 {
161  if ( !g || !qgsgeometry_cast< QgsPolygon * >( g ) )
162  {
163  delete g;
164  return false;
165  }
166 
167  return QgsMultiSurface::insertGeometry( g, index );
168 }
169 
171 {
172  QgsMultiSurface *multiSurface = new QgsMultiSurface();
173  multiSurface->reserve( mGeometries.size() );
174  for ( int i = 0; i < mGeometries.size(); ++i )
175  {
176  multiSurface->addGeometry( mGeometries.at( i )->clone() );
177  }
178  return multiSurface;
179 }
180 
182 {
183  std::unique_ptr< QgsMultiLineString > multiLine( new QgsMultiLineString() );
184  multiLine->reserve( mGeometries.size() );
185  for ( int i = 0; i < mGeometries.size(); ++i )
186  {
187  if ( QgsPolygon *polygon = qgsgeometry_cast<QgsPolygon *>( mGeometries.at( i ) ) )
188  {
189  QgsAbstractGeometry *polygonBoundary = polygon->boundary();
190 
191  if ( QgsLineString *lineStringBoundary = qgsgeometry_cast< QgsLineString * >( polygonBoundary ) )
192  {
193  multiLine->addGeometry( lineStringBoundary );
194  }
195  else if ( QgsMultiLineString *multiLineStringBoundary = qgsgeometry_cast< QgsMultiLineString * >( polygonBoundary ) )
196  {
197  for ( int j = 0; j < multiLineStringBoundary->numGeometries(); ++j )
198  {
199  multiLine->addGeometry( multiLineStringBoundary->geometryN( j )->clone() );
200  }
201  delete multiLineStringBoundary;
202  }
203  else
204  {
205  delete polygonBoundary;
206  }
207  }
208  }
209  if ( multiLine->numGeometries() == 0 )
210  {
211  return nullptr;
212  }
213  return multiLine.release();
214 }
215 
217 {
218  return true;
219 }
qgspolygon.h
QgsAbstractGeometry::dropMValue
virtual bool dropMValue()=0
Drops any measure values which exist in the geometry.
QgsAbstractGeometry::dropZValue
virtual bool dropZValue()=0
Drops any z-dimensions which exist in the geometry.
QgsMultiPolygon::boundary
QgsAbstractGeometry * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
Definition: qgsmultipolygon.cpp:181
QgsGeometryUtils::pointsToJson
static json pointsToJson(const QgsPointSequence &points, int precision)
Returns coordinates as json object.
Definition: qgsgeometryutils.cpp:1268
QgsPolygon
Polygon geometry type.
Definition: qgspolygon.h:33
qgslinestring.h
QgsAbstractGeometry::addZValue
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
QgsWkbTypes::MultiPolygon
@ MultiPolygon
Definition: qgswkbtypes.h:77
QgsMultiPolygon::clone
QgsMultiPolygon * clone() const override
Clones the geometry by performing a deep copy.
Definition: qgsmultipolygon.cpp:51
QgsGeometryCollection::reserve
void reserve(int size)
Attempts to allocate memory for at least size geometries.
Definition: qgsgeometrycollection.cpp:202
QgsAbstractGeometry::addMValue
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
QgsMultiLineString
Multi line string geometry collection.
Definition: qgsmultilinestring.h:29
QgsCurvePolygon::exteriorRing
const QgsCurve * exteriorRing() const
Returns the curve polygon's exterior ring.
Definition: qgscurvepolygon.h:86
QgsGeometryCollection::mGeometries
QVector< QgsAbstractGeometry * > mGeometries
Definition: qgsgeometrycollection.h:317
QgsAbstractGeometry::mWkbType
QgsWkbTypes::Type mWkbType
Definition: qgsabstractgeometry.h:1005
QgsMultiSurface
Multi surface geometry collection.
Definition: qgsmultisurface.h:29
QgsLineString
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:43
QgsMultiPolygon::wktOmitChildType
bool wktOmitChildType() const override
Returns whether child type names are omitted from Wkt representations of the collection.
Definition: qgsmultipolygon.cpp:216
QgsCurvePolygon::interiorRing
const QgsCurve * interiorRing(int i) const
Retrieves an interior ring from the curve polygon.
Definition: qgscurvepolygon.h:99
QgsMultiPolygon::clear
void clear() override
Clears the geometry, ie reset it to a null geometry.
Definition: qgsmultipolygon.cpp:38
qgsapplication.h
precision
int precision
Definition: qgswfsgetfeature.cpp:103
qgsmultipolygon.h
QgsAbstractGeometry::AxisOrder
AxisOrder
Axis order for GML generation.
Definition: qgsabstractgeometry.h:128
QgsGeometryCollection::isEmpty
bool isEmpty() const override
Returns true if the geometry is empty.
Definition: qgsgeometrycollection.cpp:213
QgsGeometryCollection::addGeometry
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
Definition: qgsgeometrycollection.cpp:226
QgsGeometryCollection::fromCollectionWkt
bool fromCollectionWkt(const QString &wkt, const QVector< QgsAbstractGeometry * > &subtypes, const QString &defaultChildWkbType=QString())
Reads a collection from a WKT string.
Definition: qgsgeometrycollection.cpp:676
QgsMultiPolygon::fromWkt
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
Definition: qgsmultipolygon.cpp:56
QgsAbstractGeometry::is3D
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
Definition: qgsabstractgeometry.h:202
QgsMultiPolygon
Multi polygon geometry collection.
Definition: qgsmultipolygon.h:29
QgsMultiSurface::clear
void clear() override
Clears the geometry, ie reset it to a null geometry.
Definition: qgsmultisurface.cpp:39
QgsMultiPolygon::geometryType
QString geometryType() const override
Returns a unique string representing the geometry type.
Definition: qgsmultipolygon.cpp:33
QgsMultiPolygon::createEmptyWithSameType
QgsMultiPolygon * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
Definition: qgsmultipolygon.cpp:44
qgscurvepolygon.h
QgsAbstractGeometry
Abstract base class for all geometries.
Definition: qgsabstractgeometry.h:71
QgsMultiPolygon::asJsonObject
json asJsonObject(int precision=17) const override
Returns a json object representation of the geometry.
Definition: qgsmultipolygon.cpp:102
qgsgeometryutils.h
QgsMultiSurface::insertGeometry
bool insertGeometry(QgsAbstractGeometry *g, int index) override
Inserts a geometry before a specified index and takes ownership.
Definition: qgsmultisurface.cpp:169
QgsCurvePolygon::numInteriorRings
int numInteriorRings() const
Returns the number of interior rings contained with the curve polygon.
Definition: qgscurvepolygon.h:76
QgsPointSequence
QVector< QgsPoint > QgsPointSequence
Definition: qgsabstractgeometry.h:44
QgsMultiPolygon::addGeometry
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
Definition: qgsmultipolygon.cpp:135
QgsMultiPolygon::toCurveType
QgsMultiSurface * toCurveType() const override
Returns the geometry converted to the more generic curve type QgsMultiSurface.
Definition: qgsmultipolygon.cpp:170
QgsMultiPolygon::QgsMultiPolygon
QgsMultiPolygon()
Definition: qgsmultipolygon.cpp:28
QgsMultiPolygon::asGml3
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.
Definition: qgsmultipolygon.cpp:82
QgsAbstractGeometry::isMeasure
bool isMeasure() const
Returns true if the geometry contains m values.
Definition: qgsabstractgeometry.h:211
QgsMultiSurface::addGeometry
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
Definition: qgsmultisurface.cpp:145
QgsAbstractGeometry::boundary
virtual QgsAbstractGeometry * boundary() const =0
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
QgsMultiPolygon::insertGeometry
bool insertGeometry(QgsAbstractGeometry *g, int index) override
Inserts a geometry before a specified index and takes ownership.
Definition: qgsmultipolygon.cpp:159
QgsAbstractGeometry::setZMTypeFromSubGeometry
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, QgsWkbTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
Definition: qgsabstractgeometry.cpp:43
QgsCurve::curveToLine
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.
qgsmultilinestring.h
QgsMultiSurface::QgsMultiSurface
QgsMultiSurface()
Definition: qgsmultisurface.cpp:29
qgssurface.h
QgsMultiPolygon::asGml2
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.
Definition: qgsmultipolygon.cpp:61