QGIS API Documentation  2.10.1-Pisa
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgscurvepolygonv2.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscurvepolygonv2.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 "qgscurvepolygonv2.h"
19 #include "qgsapplication.h"
20 #include "qgscircularstringv2.h"
21 #include "qgscompoundcurvev2.h"
22 #include "qgsgeometryutils.h"
23 #include "qgslinestringv2.h"
24 #include "qgspolygonv2.h"
25 #include "qgswkbptr.h"
26 #include <QPainter>
27 #include <QPainterPath>
28 
30 {
31 
32 }
33 
35 {
36  clear();
37 }
38 
40 {
41  if ( p.mExteriorRing )
42  {
43  mExteriorRing = static_cast<QgsCurveV2*>( p.mExteriorRing->clone() );
44  }
45 
46  foreach ( const QgsCurveV2* ring, p.mInteriorRings )
47  {
48  mInteriorRings.push_back( static_cast<QgsCurveV2*>( ring->clone() ) );
49  }
50 }
51 
53 {
54  if ( &p != this )
55  {
57  if ( p.mExteriorRing )
58  {
59  mExteriorRing = static_cast<QgsCurveV2*>( p.mExteriorRing->clone() );
60  }
61 
62  foreach ( const QgsCurveV2* ring, p.mInteriorRings )
63  {
64  mInteriorRings.push_back( static_cast<QgsCurveV2*>( ring->clone() ) );
65  }
66  }
67  return *this;
68 }
69 
71 {
72  return new QgsCurvePolygonV2( *this );
73 }
74 
76 {
77  delete mExteriorRing;
78  mExteriorRing = 0;
79  qDeleteAll( mInteriorRings );
82 }
83 
84 
85 bool QgsCurvePolygonV2::fromWkb( const unsigned char* wkb )
86 {
87  clear();
88  if ( !wkb )
89  {
90  return false;
91  }
92  QgsConstWkbPtr wkbPtr( wkb );
93  QgsWKBTypes::Type type = wkbPtr.readHeader();
95  {
96  return false;
97  }
98  mWkbType = type;
99 
100  int nRings;
101  wkbPtr >> nRings;
102  QgsCurveV2* currentCurve = 0;
103  int currentCurveSize = 0;
104  for ( int i = 0; i < nRings; ++i )
105  {
106  wkbPtr += 1; //skip endian
107  QgsWKBTypes::Type curveType;
108  wkbPtr >> curveType;
109  wkbPtr -= ( 1 + sizeof( int ) );
110  if ( curveType == QgsWKBTypes::LineString || curveType == QgsWKBTypes::LineStringZ || curveType == QgsWKBTypes::LineStringM ||
111  curveType == QgsWKBTypes::LineStringZM || curveType == QgsWKBTypes::LineString25D )
112  {
113  currentCurve = new QgsLineStringV2();
114  }
115  else if ( curveType == QgsWKBTypes::CircularString || curveType == QgsWKBTypes::CircularStringZ || curveType == QgsWKBTypes::CircularStringZM ||
116  curveType == QgsWKBTypes::CircularStringM )
117  {
118  currentCurve = new QgsCircularStringV2();
119  }
120  else if ( curveType == QgsWKBTypes::CompoundCurve || curveType == QgsWKBTypes::CompoundCurveZ || curveType == QgsWKBTypes::CompoundCurveZM )
121  {
122  currentCurve = new QgsCompoundCurveV2();
123  }
124  else
125  {
126  return false;
127  }
128  currentCurve->fromWkb( wkbPtr );
129  currentCurveSize = currentCurve->wkbSize();
130  if ( i == 0 )
131  {
132  mExteriorRing = currentCurve;
133  }
134  else
135  {
136  mInteriorRings.append( currentCurve );
137  }
138  wkbPtr += currentCurveSize;
139  }
140 
141  return true;
142 }
143 
145 {
146  clear();
147 
149 
150  if ( QgsWKBTypes::flatType( parts.first ) != QgsWKBTypes::parseType( geometryType() ) )
151  return false;
152  mWkbType = parts.first;
153 
154  QString defaultChildWkbType = QString( "LineString%1%2" ).arg( is3D() ? "Z" : "" ).arg( isMeasure() ? "M" : "" );
155 
156  foreach ( const QString& childWkt, QgsGeometryUtils::wktGetChildBlocks( parts.second, defaultChildWkbType ) )
157  {
159 
160  if ( QgsWKBTypes::flatType( childParts.first ) == QgsWKBTypes::LineString )
162  else if ( QgsWKBTypes::flatType( childParts.first ) == QgsWKBTypes::CircularString )
164  else
165  {
166  clear();
167  return false;
168  }
169  if ( !mInteriorRings.back()->fromWkt( childWkt ) )
170  {
171  clear();
172  return false;
173  }
174  }
175 
178 
179  return true;
180 }
181 
183 {
184  if ( mExteriorRing )
185  {
187  }
188  return QgsRectangle();
189 }
190 
192 {
193  int size = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 );
194  if ( mExteriorRing )
195  {
196  size += mExteriorRing->wkbSize();
197  }
198  foreach ( const QgsCurveV2* curve, mInteriorRings )
199  {
200  size += curve->wkbSize();
201  }
202  return size;
203 }
204 
205 unsigned char* QgsCurvePolygonV2::asWkb( int& binarySize ) const
206 {
207  binarySize = wkbSize();
208  unsigned char* geomPtr = new unsigned char[binarySize];
209  QgsWkbPtr wkb( geomPtr );
210  wkb << static_cast<char>( QgsApplication::endian() );
211  wkb << static_cast<quint32>( wkbType() );
212  wkb << static_cast<quint32>(( mExteriorRing != 0 ) + mInteriorRings.size() );
213  if ( mExteriorRing )
214  {
215  int curveWkbLen = 0;
216  unsigned char* ringWkb = mExteriorRing->asWkb( curveWkbLen );
217  memcpy( wkb, ringWkb, curveWkbLen );
218  wkb += curveWkbLen;
219  }
220  foreach ( const QgsCurveV2* curve, mInteriorRings )
221  {
222  int curveWkbLen = 0;
223  unsigned char* ringWkb = curve->asWkb( curveWkbLen );
224  memcpy( wkb, ringWkb, curveWkbLen );
225  wkb += curveWkbLen;
226  }
227  return geomPtr;
228 }
229 
230 QString QgsCurvePolygonV2::asWkt( int precision ) const
231 {
232  QString wkt = wktTypeStr() + " (";
233  if ( mExteriorRing )
234  {
235  QString childWkt = mExteriorRing->asWkt( precision );
236  if ( dynamic_cast<QgsLineStringV2*>( mExteriorRing ) )
237  {
238  // Type names of linear geometries are omitted
239  childWkt = childWkt.mid( childWkt.indexOf( "(" ) );
240  }
241  wkt += childWkt + ",";
242  }
243  foreach ( const QgsCurveV2* curve, mInteriorRings )
244  {
245  QString childWkt = curve->asWkt( precision );
246  if ( dynamic_cast<const QgsLineStringV2*>( curve ) )
247  {
248  // Type names of linear geometries are omitted
249  childWkt = childWkt.mid( childWkt.indexOf( "(" ) );
250  }
251  wkt += childWkt + ",";
252  }
253  if ( wkt.endsWith( "," ) )
254  {
255  wkt.chop( 1 ); // Remove last ","
256  }
257  wkt += ")";
258  return wkt;
259 }
260 
261 QDomElement QgsCurvePolygonV2::asGML2( QDomDocument& doc, int precision, const QString& ns ) const
262 {
263  // GML2 does not support curves
264  QDomElement elemPolygon = doc.createElementNS( ns, "Polygon" );
265  QDomElement elemOuterBoundaryIs = doc.createElementNS( ns, "outerBoundaryIs" );
266  QgsLineStringV2* exteriorLineString = exteriorRing()->curveToLine();
267  elemOuterBoundaryIs.appendChild( exteriorLineString->asGML2( doc, precision, ns ) );
268  delete exteriorLineString;
269  elemPolygon.appendChild( elemOuterBoundaryIs );
270  QDomElement elemInnerBoundaryIs = doc.createElementNS( ns, "innerBoundaryIs" );
271  for ( int i = 0, n = numInteriorRings(); i < n; ++i )
272  {
273  QgsLineStringV2* interiorLineString = interiorRing( i )->curveToLine();
274  elemInnerBoundaryIs.appendChild( interiorLineString->asGML2( doc, precision, ns ) );
275  delete interiorLineString;
276  }
277  elemPolygon.appendChild( elemInnerBoundaryIs );
278  return elemPolygon;
279 }
280 
281 QDomElement QgsCurvePolygonV2::asGML3( QDomDocument& doc, int precision, const QString& ns ) const
282 {
283  QDomElement elemCurvePolygon = doc.createElementNS( ns, "Polygon" );
284  QDomElement elemExterior = doc.createElementNS( ns, "exterior" );
285  elemExterior.appendChild( exteriorRing()->asGML2( doc, precision, ns ) );
286  elemCurvePolygon.appendChild( elemExterior );
287  QDomElement elemInterior = doc.createElementNS( ns, "interior" );
288  for ( int i = 0, n = numInteriorRings(); i < n; ++i )
289  {
290  elemInterior.appendChild( interiorRing( i )->asGML2( doc, precision, ns ) );
291  }
292  elemCurvePolygon.appendChild( elemInterior );
293  return elemCurvePolygon;
294 }
295 
296 QString QgsCurvePolygonV2::asJSON( int precision ) const
297 {
298  // GeoJSON does not support curves
299  QString json = "{\"type\": \"Polygon\", \"coordinates\": [";
300 
301  QgsLineStringV2* exteriorLineString = exteriorRing()->curveToLine();
302  QList<QgsPointV2> exteriorPts;
303  exteriorLineString->points( exteriorPts );
304  json += QgsGeometryUtils::pointsToJSON( exteriorPts, precision ) + ", ";
305  delete exteriorLineString;
306 
307  for ( int i = 0, n = numInteriorRings(); i < n; ++i )
308  {
309  QgsLineStringV2* interiorLineString = interiorRing( i )->curveToLine();
310  QList<QgsPointV2> interiorPts;
311  interiorLineString->points( interiorPts );
312  json += QgsGeometryUtils::pointsToJSON( interiorPts, precision ) + ", ";
313  delete interiorLineString;
314  }
315  if ( json.endsWith( ", " ) )
316  {
317  json.chop( 2 ); // Remove last ", "
318  }
319  json += "] }";
320  return json;
321 }
322 
324 {
325  if ( !mExteriorRing )
326  {
327  return 0.0;
328  }
329 
330  double area = mExteriorRing->area();
332  for ( ; ringIt != mInteriorRings.constEnd(); ++ringIt )
333  {
334  area -= ( *ringIt )->area();
335  }
336  return area;
337 }
338 
340 {
341  //sum perimeter of rings
342  double length = mExteriorRing->length();
344  for ( ; ringIt != mInteriorRings.constEnd(); ++ringIt )
345  {
346  length += ( *ringIt )->length();
347  }
348  return length;
349 }
350 
352 {
353  return QgsPointV2( 0, 0 );
354 }
355 
357 {
358  return QgsPointV2( 0, 0 );
359 }
360 
362 {
363  QgsPolygonV2* polygon = new QgsPolygonV2();
364  polygon->setExteriorRing( exteriorRing()->curveToLine() );
365  QList<QgsCurveV2*> interiors;
366  for ( int i = 0, n = numInteriorRings(); i < n; ++i )
367  {
368  interiors.append( interiorRing( i )->curveToLine() );
369  }
370  polygon->setInteriorRings( interiors );
371  return polygon;
372 }
373 
375 {
376  if ( !mExteriorRing )
377  {
378  return 0;
379  }
380 
381  QgsPolygonV2* poly = new QgsPolygonV2();
383 
384  QList<QgsCurveV2*> rings;
386  for ( ; it != mInteriorRings.constEnd(); ++it )
387  {
388  rings.push_back(( *it )->curveToLine() );
389  }
390  poly->setInteriorRings( rings );
391  return poly;
392 }
393 
395 {
396  return mInteriorRings.size();
397 }
398 
400 {
401  return mExteriorRing;
402 }
403 
405 {
406  if ( i >= mInteriorRings.size() )
407  {
408  return 0;
409  }
410  return mInteriorRings.at( i );
411 }
412 
414 {
415  if ( !ring )
416  {
417  return;
418  }
419  delete mExteriorRing;
420  mExteriorRing = ring;
421 
422  //set proper wkb type
423  if ( geometryType() == "Polygon" )
424  {
426  }
427  else if ( geometryType() == "CurvePolygon" )
428  {
430  }
431 }
432 
434 {
435  qDeleteAll( mInteriorRings );
436  mInteriorRings = rings;
437 }
438 
440 {
441  mInteriorRings.append( ring );
442 }
443 
445 {
446  if ( nr >= mInteriorRings.size() )
447  {
448  return false;
449  }
450  mInteriorRings.removeAt( nr );
451  return true;
452 }
453 
455 {
456  if ( mInteriorRings.size() < 1 )
457  {
458  if ( mExteriorRing )
459  {
461  }
462  }
463  else
464  {
465  QPainterPath path;
467 
469  for ( ; it != mInteriorRings.constEnd(); ++it )
470  {
471  ( *it )->addToPainterPath( path );
472  }
473  p.drawPath( path );
474  }
475 }
476 
478 {
479  if ( mExteriorRing )
480  {
481  mExteriorRing->transform( ct );
482  }
483 
485  for ( ; it != mInteriorRings.end(); ++it )
486  {
487  ( *it )->transform( ct );
488  }
489 }
490 
492 {
493  if ( mExteriorRing )
494  {
495  mExteriorRing->transform( t );
496  }
497 
499  for ( ; it != mInteriorRings.end(); ++it )
500  {
501  ( *it )->transform( t );
502  }
503 }
504 
506 {
507  coord.clear();
508 
509  QList< QList< QgsPointV2 > > coordinates;
510  QList< QgsPointV2 > ringCoords;
511  if ( mExteriorRing )
512  {
513  mExteriorRing->points( ringCoords );
514  coordinates.append( ringCoords );
515  }
516 
518  for ( ; it != mInteriorRings.constEnd(); ++it )
519  {
520  ( *it )->points( ringCoords );
521  coordinates.append( ringCoords );
522  }
523  coord.append( coordinates );
524 }
525 
526 double QgsCurvePolygonV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
527 {
528  if ( !mExteriorRing )
529  {
530  return 0.0;
531  }
532  QList<QgsCurveV2*> segmentList;
533  segmentList.append( mExteriorRing );
534  segmentList.append( mInteriorRings );
535  return QgsGeometryUtils::closestSegmentFromComponents( segmentList, QgsGeometryUtils::RING, pt, segmentPt, vertexAfter, leftOf, epsilon );
536 }
537 
539 {
540  if ( !mExteriorRing || vId.ring >= 1 + mInteriorRings.size() )
541  {
542  return false;
543  }
544 
545  if ( vId.ring < 0 )
546  {
547  vId.ring = 0; vId.vertex = -1;
548  if ( vId.part < 0 )
549  {
550  vId.part = 0;
551  }
552  return mExteriorRing->nextVertex( vId, vertex );
553  }
554  else
555  {
556  QgsCurveV2* ring = vId.ring == 0 ? mExteriorRing : mInteriorRings[vId.ring - 1];
557 
558  if ( ring->nextVertex( vId, vertex ) )
559  {
560  return true;
561  }
562  ++vId.ring;
563  vId.vertex = -1;
564  if ( vId.ring >= 1 + mInteriorRings.size() )
565  {
566  return false;
567  }
568  ring = mInteriorRings[ vId.ring - 1 ];
569  return ring->nextVertex( vId, vertex );
570  }
571 }
572 
573 bool QgsCurvePolygonV2::insertVertex( const QgsVertexId& vId, const QgsPointV2& vertex )
574 {
575  if ( !mExteriorRing || vId.ring < 0 || vId.ring >= 1 + mInteriorRings.size() )
576  {
577  return false;
578  }
579 
580  QgsCurveV2* ring = vId.ring == 0 ? mExteriorRing : mInteriorRings[vId.ring - 1];
581  int n = ring->numPoints();
582  bool success = ring->insertVertex( QgsVertexId( 0, 0, vId.vertex ), vertex );
583  // If first or last vertex is inserted, re-sync the last/first vertex
584  if ( vId.vertex == 0 )
585  ring->moveVertex( QgsVertexId( 0, 0, n ), vertex );
586  else if ( vId.vertex == n )
587  ring->moveVertex( QgsVertexId( 0, 0, 0 ), vertex );
588 
589  return success;
590 }
591 
592 bool QgsCurvePolygonV2::moveVertex( const QgsVertexId& vId, const QgsPointV2& newPos )
593 {
594  if ( !mExteriorRing || vId.ring < 0 || vId.ring >= 1 + mInteriorRings.size() )
595  {
596  return false;
597  }
598 
599  QgsCurveV2* ring = vId.ring == 0 ? mExteriorRing : mInteriorRings[vId.ring - 1];
600  int n = ring->numPoints();
601  bool success = ring->moveVertex( vId, newPos );
602  if ( success )
603  {
604  // If first or last vertex is moved, also move the last/first vertex
605  if ( vId.vertex == 0 )
606  ring->moveVertex( QgsVertexId( vId.part, vId.ring, n - 1 ), newPos );
607  else if ( vId.vertex == n - 1 )
608  ring->moveVertex( QgsVertexId( vId.part, vId.ring, 0 ), newPos );
610  }
611  return success;
612 }
613 
615 {
616  if ( !mExteriorRing || vId.ring < 0 || vId.ring >= 1 + mInteriorRings.size() )
617  {
618  return false;
619  }
620 
621  QgsCurveV2* ring = vId.ring == 0 ? mExteriorRing : mInteriorRings[vId.ring - 1];
622  int n = ring->numPoints();
623  if ( n <= 4 )
624  {
625  return false;
626  }
627  bool success = ring->deleteVertex( vId );
628  if ( success )
629  {
630  // If first or last vertex is removed, re-sync the last/first vertex
631  if ( vId.vertex == 0 )
632  ring->moveVertex( QgsVertexId( 0, 0, n - 2 ), ring->vertexAt( QgsVertexId( 0, 0, 0 ) ) );
633  else if ( vId.vertex == n - 1 )
634  ring->moveVertex( QgsVertexId( 0, 0, 0 ), ring->vertexAt( QgsVertexId( 0, 0, n - 2 ) ) );
636  }
637  return success;
638 }
639 
641 {
643  {
644  return true;
645  }
646 
648  for ( ; it != mInteriorRings.constEnd(); ++it )
649  {
650  if (( *it )->hasCurvedSegments() )
651  {
652  return true;
653  }
654  }
655  return false;
656 }
657 
659 {
660  return toPolygon();
661 }
const QgsCurveV2 * exteriorRing() const
void clear()
bool removeInteriorRing(int nr)
Removes ring.
bool hasCurvedSegments() const override
Returns true if the geometry contains curved segments.
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QgsWKBTypes::Type wkbType() const
Returns the WKB type of the geometry.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
virtual bool deleteVertex(const QgsVertexId &position) override
Deletes a vertex within the geometry.
QDomElement asGML2(QDomDocument &doc, int precision=17, const QString &ns="gml") const override
Returns a GML2 representation of the geometry.
static QPair< QgsWKBTypes::Type, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
virtual bool moveVertex(const QgsVertexId &position, const QgsPointV2 &newPos) override
Moves a vertex within the geometry.
QDomElement asGML2(QDomDocument &doc, int precision=17, const QString &ns="gml") const override
Returns a GML2 representation of the geometry.
virtual QgsRectangle calculateBoundingBox() const override
Calculates the minimal bounding box for the geometry.
virtual QgsAbstractGeometryV2 & operator=(const QgsAbstractGeometryV2 &geom)
QDomNode appendChild(const QDomNode &newChild)
void addInteriorRing(QgsCurveV2 *ring)
Adds an interior ring to the geometry (takes ownership)
void transform(const QgsCoordinateTransform &ct) override
Transforms the geometry using a coordinate transform.
void push_back(const T &value)
void clear() override
Clears the geometry, ie reset it to a null geometry.
void points(QList< QgsPointV2 > &pt) const override
Returns a list of points within the curve.
virtual bool moveVertex(const QgsVertexId &position, const QgsPointV2 &newPos)=0
Moves a vertex within the geometry.
Circular string geometry type.
virtual double length() const
Returns the length (or perimeter for area geometries) of the geometry.
QgsPolygonV2 * surfaceToPolygon() const override
virtual void points(QList< QgsPointV2 > &pt) const =0
Returns a list of points within the curve.
void removeFirst()
const T & at(int i) const
static QString pointsToJSON(const QList< QgsPointV2 > &points, int precision)
Returns a geoJSON coordinates string.
void removeAt(int i)
virtual void addToPainterPath(QPainterPath &path) const =0
Adds a curve to a painter path.
Abstract base class for all geometries.
static QStringList wktGetChildBlocks(const QString &wkt, const QString &defaultType="")
Parses a WKT string and returns of list of blocks contained in the WKT.
static double closestSegmentFromComponents(T &container, componentType ctype, const QgsPointV2 &pt, QgsPointV2 &segmentPt, QgsVertexId &vertexAfter, bool *leftOf, double epsilon)
QDomElement createElementNS(const QString &nsURI, const QString &qName)
QgsPointV2 vertexAt(const QgsVertexId &id) const
Returns the point corresponding to a specified vertex id.
void chop(int n)
static endian_t endian()
Returns whether this machine uses big or little endian.
QString wktTypeStr() const
Returns the WKT type string of the geometry.
virtual int wkbSize() const =0
Returns the size of the WKB representation of the geometry.
virtual double length() const override
Returns the length (or perimeter for area geometries) of the geometry.
virtual void coordinateSequence(QList< QList< QList< QgsPointV2 > > > &coord) const override
Retrieves the sequence of geometries, rings and nodes.
int size() const
virtual bool insertVertex(const QgsVertexId &position, const QgsPointV2 &vertex)=0
Inserts a vertex into the geometry.
virtual QgsAbstractGeometryV2 * clone() const override
Clones the geometry by performing a deep copy.
virtual int numPoints() const =0
Returns the number of points in the curve.
QgsWKBTypes::Type readHeader() const
Definition: qgswkbptr.cpp:8
int wkbSize() const override
Returns the size of the WKB representation of the geometry.
Polygon geometry type.
Definition: qgspolygonv2.h:29
static Type flatType(Type type)
Definition: qgswkbtypes.cpp:46
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
void append(const T &value)
virtual bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
virtual QString geometryType() const override
Returns a unique string representing the geometry type.
Utility class for identifying a unique vertex within a geometry.
bool isMeasure() const
Returns true if the geometry contains m values.
Line string geometry type.
virtual QgsRectangle calculateBoundingBox() const
Calculates the minimal bounding box for the geometry.
virtual bool fromWkb(const unsigned char *wkb)=0
Sets the geometry from a WKB string.
Point geometry type.
Definition: qgspointv2.h:29
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
QgsCurvePolygonV2 & operator=(const QgsCurvePolygonV2 &p)
virtual bool hasCurvedSegments() const
Returns true if the geometry contains curved segments.
virtual unsigned char * asWkb(int &binarySize) const =0
Returns a WKB representation of the geometry.
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
virtual QgsPolygonV2 * toPolygon() const
void setZMTypeFromSubGeometry(const QgsAbstractGeometryV2 *subggeom, QgsWKBTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
T & first()
virtual bool nextVertex(QgsVertexId &id, QgsPointV2 &vertex) const override
Returns next vertex id and coordinates.
Definition: qgscurvev2.cpp:47
unsigned char * asWkb(int &binarySize) const override
Returns a WKB representation of the geometry.
virtual void draw(QPainter &p) const override
Draws the geometry using the specified QPainter.
double closestSegment(const QgsPointV2 &pt, QgsPointV2 &segmentPt, QgsVertexId &vertexAfter, bool *leftOf, double epsilon) const override
Searches for the closest segment of the geometry to a given point.
Compound curve geometry type.
iterator end()
const QgsCurveV2 * interiorRing(int i) const
virtual bool fromWkb(const unsigned char *wkb) override
Sets the geometry from a WKB string.
bool nextVertex(QgsVertexId &id, QgsPointV2 &vertex) const override
Returns next vertex id and coordinates.
virtual bool deleteVertex(const QgsVertexId &position)=0
Deletes a vertex within the geometry.
QList< QgsCurveV2 * > mInteriorRings
virtual QgsLineStringV2 * curveToLine() const =0
Returns a new line string geometry corresponding to a segmentized approximation of the curve...
QString asJSON(int precision=17) const override
Returns a GeoJSON representation of the geometry.
QString mid(int position, int n) const
void drawPath(const QPainterPath &path)
void setExteriorRing(QgsCurveV2 *ring)
Sets exterior ring (takes ownership)
QgsPointV2 pointOnSurface() const override
virtual double area() const override
Returns the area of the geometry.
Definition: qgscurvev2.cpp:72
virtual void transform(const QgsCoordinateTransform &ct)=0
Transforms the geometry using a coordinate transform.
Class for doing transforms between two map coordinate systems.
virtual QString asWkt(int precision=17) const =0
Returns a WKT representation of the geometry.
QgsPointV2 centroid() const override
virtual void drawAsPolygon(QPainter &p) const =0
Draws the curve as a polygon on the specified QPainter.
static Type parseType(const QString &wktStr)
Definition: qgswkbtypes.cpp:56
QgsAbstractGeometryV2 * segmentize() const override
Returns a version of the geometry without curves.
double ANALYSIS_EXPORT leftOf(Point3D *thepoint, Point3D *p1, Point3D *p2)
Returns whether 'thepoint' is left or right of the line from 'p1' to 'p2'.
Curve polygon geometry type.
virtual bool insertVertex(const QgsVertexId &position, const QgsPointV2 &vertex) override
Inserts a vertex into the geometry.
const_iterator constEnd() const
int numInteriorRings() const
const_iterator constBegin() const
virtual QgsAbstractGeometryV2 * clone() const =0
Clones the geometry by performing a deep copy.
Abstract base class for curved geometry type.
Definition: qgscurvev2.h:32
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QDomElement asGML3(QDomDocument &doc, int precision=17, const QString &ns="gml") const override
Returns a GML3 representation of the geometry.
T & back()
iterator begin()
virtual double area() const override
Returns the area of the geometry.
void setInteriorRings(QList< QgsCurveV2 * > rings)
Sets all interior rings (takes ownership)
QgsCurveV2 * mExteriorRing