QGIS API Documentation  2.14.0-Essen
qgspolygonv2.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgspolygonv2.cpp
3  ----------------
4  begin : September 2014
5  copyright : (C) 2014 by Marco Hugentobler
6  email : marco at sourcepole dot ch
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgspolygonv2.h"
19 #include "qgsapplication.h"
20 #include "qgsgeometryutils.h"
21 #include "qgslinestringv2.h"
22 #include "qgswkbptr.h"
23 
26 {
28 }
29 
30 bool QgsPolygonV2::operator==( const QgsPolygonV2& other ) const
31 {
32  //run cheap checks first
33  if ( mWkbType != other.mWkbType )
34  return false;
35 
36  if (( !mExteriorRing && other.mExteriorRing ) || ( mExteriorRing && !other.mExteriorRing ) )
37  return false;
38 
39  if ( mInteriorRings.count() != other.mInteriorRings.count() )
40  return false;
41 
42  // compare rings
43  if ( mExteriorRing && other.mExteriorRing )
44  {
45  if ( *mExteriorRing != *other.mExteriorRing )
46  return false;
47  }
48 
49  for ( int i = 0; i < mInteriorRings.count(); ++i )
50  {
51  if (( !mInteriorRings.at( i ) && other.mInteriorRings.at( i ) ) ||
52  ( mInteriorRings.at( i ) && !other.mInteriorRings.at( i ) ) )
53  return false;
54 
55  if ( mInteriorRings.at( i ) && other.mInteriorRings.at( i ) &&
56  *mInteriorRings.at( i ) != *other.mInteriorRings.at( i ) )
57  return false;
58  }
59 
60  return true;
61 }
62 
63 bool QgsPolygonV2::operator!=( const QgsPolygonV2& other ) const
64 {
65  return !operator==( other );
66 }
67 
69 {
70  return new QgsPolygonV2( *this );
71 }
72 
74 {
75  clear();
76  if ( !wkbPtr )
77  {
78  return false;
79  }
80 
81  QgsWKBTypes::Type type = wkbPtr.readHeader();
83  {
84  return false;
85  }
86  mWkbType = type;
87 
88  QgsWKBTypes::Type ringType;
89  switch ( mWkbType )
90  {
92  ringType = QgsWKBTypes::LineStringZ;
93  break;
95  ringType = QgsWKBTypes::LineStringM;
96  break;
98  ringType = QgsWKBTypes::LineStringZM;
99  break;
101  ringType = QgsWKBTypes::LineString25D;
102  break;
103  default:
104  ringType = QgsWKBTypes::LineString;
105  break;
106  }
107 
108  int nRings;
109  wkbPtr >> nRings;
110  for ( int i = 0; i < nRings; ++i )
111  {
112  QgsLineStringV2* line = new QgsLineStringV2();
113  line->fromWkbPoints( ringType, wkbPtr );
114  /*if ( !line->isRing() )
115  {
116  delete line; continue;
117  }*/
118 
119  if ( !mExteriorRing )
120  {
121  mExteriorRing = line;
122  }
123  else
124  {
125  mInteriorRings.append( line );
126  }
127  }
128 
129  return true;
130 }
131 
133 {
134  int size = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 );
135  if ( mExteriorRing )
136  {
137  // Endianness and WkbType is not stored for LinearRings
138  size += mExteriorRing->wkbSize() - ( sizeof( char ) + sizeof( quint32 ) );
139  }
140  Q_FOREACH ( const QgsCurveV2* curve, mInteriorRings )
141  {
142  // Endianness and WkbType is not stored for LinearRings
143  size += curve->wkbSize() - ( sizeof( char ) + sizeof( quint32 ) );
144  }
145  return size;
146 }
147 
148 unsigned char* QgsPolygonV2::asWkb( int& binarySize ) const
149 {
150  binarySize = wkbSize();
151  unsigned char* geomPtr = new unsigned char[binarySize];
152  QgsWkbPtr wkb( geomPtr, binarySize );
153  wkb << static_cast<char>( QgsApplication::endian() );
154  wkb << static_cast<quint32>( wkbType() );
155  wkb << static_cast<quint32>(( nullptr != mExteriorRing ) + mInteriorRings.size() );
156  if ( mExteriorRing )
157  {
158  QgsPointSequenceV2 pts;
159  mExteriorRing->points( pts );
161  }
162  Q_FOREACH ( const QgsCurveV2* curve, mInteriorRings )
163  {
164  QgsPointSequenceV2 pts;
165  curve->points( pts );
166  QgsGeometryUtils::pointsToWKB( wkb, pts, curve->is3D(), curve->isMeasure() );
167  }
168 
169  return geomPtr;
170 }
171 
173 {
174  if ( !ring )
175  return;
176 
177  if ( ring->hasCurvedSegments() )
178  {
179  //can't add a curved ring to a QgsPolygonV2
180  QgsLineStringV2* segmented = ring->curveToLine();
181  delete ring;
182  ring = segmented;
183  }
184 
185  QgsLineStringV2* lineString = dynamic_cast< QgsLineStringV2*>( ring );
186  if ( lineString && !lineString->isClosed() )
187  {
188  lineString->close();
189  }
190 
192  {
194  mInteriorRings.append( ring );
195  }
196  else
197  {
199  }
200  clearCache();
201 }
202 
204 {
205  if ( !ring )
206  {
207  return;
208  }
209  delete mExteriorRing;
210 
211  if ( ring->hasCurvedSegments() )
212  {
213  //need to segmentize ring as polygon does not support curves
214  QgsCurveV2* line = ring->segmentize();
215  delete ring;
216  ring = line;
217  }
218 
219  QgsLineStringV2* lineString = dynamic_cast< QgsLineStringV2*>( ring );
220  if ( lineString && !lineString->isClosed() )
221  {
222  lineString->close();
223  }
224 
225  mExteriorRing = ring;
226 
227  //set proper wkb type
229 
230  //match dimensionality for rings
231  Q_FOREACH ( QgsCurveV2* ring, mInteriorRings )
232  {
233  ring->convertTo( mExteriorRing->wkbType() );
234  }
235 
236  clearCache();
237 }
238 
240 {
241  return clone();
242 }
QgsWKBTypes::Type wkbType() const
Returns the WKB type of the geometry.
void close()
Closes the line string by appending the first point to the end of the line, if it is not already clos...
virtual bool fromWkb(QgsConstWkbPtr wkb) override
Sets the geometry from a WKB string.
virtual void addInteriorRing(QgsCurveV2 *ring)
Adds an interior ring to the geometry (takes ownership)
void clear() override
Clears the geometry, ie reset it to a null geometry.
static void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequenceV2 &points, bool is3D, bool isMeasure)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
const T & at(int i) const
unsigned char * asWkb(int &binarySize) const override
Returns a WKB representation of the geometry.
QgsCurveV2 * segmentize() const override
Returns a geometry without curves.
Definition: qgscurvev2.cpp:82
static endian_t endian()
Returns whether this machine uses big or little endian.
virtual int wkbSize() const =0
Returns the size of the WKB representation of the geometry.
int size() const
virtual void clearCache() const override
Clears any cached parameters associated with the geometry, eg bounding boxes.
Definition: qgssurfacev2.h:45
bool operator==(const QgsPolygonV2 &other) const
QgsWKBTypes::Type readHeader() const
Definition: qgswkbptr.cpp:37
Polygon geometry type.
Definition: qgspolygonv2.h:29
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
int count(const T &value) const
void append(const T &value)
virtual void setExteriorRing(QgsCurveV2 *ring) override
Sets the exterior ring of the polygon.
bool isMeasure() const
Returns true if the geometry contains m values.
Line string geometry type, with support for z-dimension and m-values.
virtual QgsPolygonV2 * clone() const override
Clones the geometry by performing a deep copy.
void addInteriorRing(QgsCurveV2 *ring) override
Adds an interior ring to the geometry (takes ownership)
virtual bool hasCurvedSegments() const
Returns true if the geometry contains curved segments.
bool operator!=(const QgsPolygonV2 &other) const
void setZMTypeFromSubGeometry(const QgsAbstractGeometryV2 *subggeom, QgsWKBTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
virtual bool convertTo(QgsWKBTypes::Type type)
Converts the geometry to a specified type.
QList< QgsCurveV2 * > mInteriorRings
virtual QgsLineStringV2 * curveToLine() const =0
Returns a new line string geometry corresponding to a segmentized approximation of the curve...
virtual bool isClosed() const
Returns true if the curve is closed.
Definition: qgscurvev2.cpp:27
QgsPolygonV2 * surfaceToPolygon() const override
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:366
Curve polygon geometry type.
Abstract base class for curved geometry type.
Definition: qgscurvev2.h:32
int wkbSize() const override
Returns the size of the WKB representation of the geometry.
virtual void points(QgsPointSequenceV2 &pt) const =0
Returns a list of points within the curve.
QgsCurveV2 * mExteriorRing