QGIS API Documentation  2.12.0-Lyon
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  Q_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  Q_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" : "", isMeasure() ? "M" : "" );
155 
156  Q_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  //scan through rings and check if dimensionality of rings is different to CurvePolygon.
180  //if so, update the type dimensionality of the CurvePolygon to match
181  bool hasZ = false;
182  bool hasM = false;
183  if ( mExteriorRing )
184  {
185  hasZ = hasZ || mExteriorRing->is3D();
186  hasM = hasM || mExteriorRing->isMeasure();
187  }
188  Q_FOREACH ( const QgsCurveV2* curve, mInteriorRings )
189  {
190  hasZ = hasZ || curve->is3D();
191  hasM = hasM || curve->isMeasure();
192  if ( hasZ && hasM )
193  break;
194  }
195  if ( hasZ )
196  addZValue( 0 );
197  if ( hasM )
198  addMValue( 0 );
199 
200  return true;
201 }
202 
204 {
205  if ( mExteriorRing )
206  {
208  }
209  return QgsRectangle();
210 }
211 
213 {
214  int size = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 );
215  if ( mExteriorRing )
216  {
217  size += mExteriorRing->wkbSize();
218  }
219  Q_FOREACH ( const QgsCurveV2* curve, mInteriorRings )
220  {
221  size += curve->wkbSize();
222  }
223  return size;
224 }
225 
226 unsigned char* QgsCurvePolygonV2::asWkb( int& binarySize ) const
227 {
228  binarySize = wkbSize();
229  unsigned char* geomPtr = new unsigned char[binarySize];
230  QgsWkbPtr wkb( geomPtr );
231  wkb << static_cast<char>( QgsApplication::endian() );
232  wkb << static_cast<quint32>( wkbType() );
233  wkb << static_cast<quint32>(( mExteriorRing != 0 ) + mInteriorRings.size() );
234  if ( mExteriorRing )
235  {
236  int curveWkbLen = 0;
237  unsigned char* ringWkb = mExteriorRing->asWkb( curveWkbLen );
238  memcpy( wkb, ringWkb, curveWkbLen );
239  wkb += curveWkbLen;
240  }
241  Q_FOREACH ( const QgsCurveV2* curve, mInteriorRings )
242  {
243  int curveWkbLen = 0;
244  unsigned char* ringWkb = curve->asWkb( curveWkbLen );
245  memcpy( wkb, ringWkb, curveWkbLen );
246  wkb += curveWkbLen;
247  }
248  return geomPtr;
249 }
250 
251 QString QgsCurvePolygonV2::asWkt( int precision ) const
252 {
253  QString wkt = wktTypeStr() + " (";
254  if ( mExteriorRing )
255  {
256  QString childWkt = mExteriorRing->asWkt( precision );
257  if ( dynamic_cast<QgsLineStringV2*>( mExteriorRing ) )
258  {
259  // Type names of linear geometries are omitted
260  childWkt = childWkt.mid( childWkt.indexOf( "(" ) );
261  }
262  wkt += childWkt + ",";
263  }
264  Q_FOREACH ( const QgsCurveV2* curve, mInteriorRings )
265  {
266  QString childWkt = curve->asWkt( precision );
267  if ( dynamic_cast<const QgsLineStringV2*>( curve ) )
268  {
269  // Type names of linear geometries are omitted
270  childWkt = childWkt.mid( childWkt.indexOf( "(" ) );
271  }
272  wkt += childWkt + ",";
273  }
274  if ( wkt.endsWith( "," ) )
275  {
276  wkt.chop( 1 ); // Remove last ","
277  }
278  wkt += ")";
279  return wkt;
280 }
281 
282 QDomElement QgsCurvePolygonV2::asGML2( QDomDocument& doc, int precision, const QString& ns ) const
283 {
284  // GML2 does not support curves
285  QDomElement elemPolygon = doc.createElementNS( ns, "Polygon" );
286  QDomElement elemOuterBoundaryIs = doc.createElementNS( ns, "outerBoundaryIs" );
287  QgsLineStringV2* exteriorLineString = exteriorRing()->curveToLine();
288  elemOuterBoundaryIs.appendChild( exteriorLineString->asGML2( doc, precision, ns ) );
289  delete exteriorLineString;
290  elemPolygon.appendChild( elemOuterBoundaryIs );
291  QDomElement elemInnerBoundaryIs = doc.createElementNS( ns, "innerBoundaryIs" );
292  for ( int i = 0, n = numInteriorRings(); i < n; ++i )
293  {
294  QgsLineStringV2* interiorLineString = interiorRing( i )->curveToLine();
295  elemInnerBoundaryIs.appendChild( interiorLineString->asGML2( doc, precision, ns ) );
296  delete interiorLineString;
297  }
298  elemPolygon.appendChild( elemInnerBoundaryIs );
299  return elemPolygon;
300 }
301 
302 QDomElement QgsCurvePolygonV2::asGML3( QDomDocument& doc, int precision, const QString& ns ) const
303 {
304  QDomElement elemCurvePolygon = doc.createElementNS( ns, "Polygon" );
305  QDomElement elemExterior = doc.createElementNS( ns, "exterior" );
306  elemExterior.appendChild( exteriorRing()->asGML2( doc, precision, ns ) );
307  elemCurvePolygon.appendChild( elemExterior );
308  QDomElement elemInterior = doc.createElementNS( ns, "interior" );
309  for ( int i = 0, n = numInteriorRings(); i < n; ++i )
310  {
311  elemInterior.appendChild( interiorRing( i )->asGML2( doc, precision, ns ) );
312  }
313  elemCurvePolygon.appendChild( elemInterior );
314  return elemCurvePolygon;
315 }
316 
317 QString QgsCurvePolygonV2::asJSON( int precision ) const
318 {
319  // GeoJSON does not support curves
320  QString json = "{\"type\": \"Polygon\", \"coordinates\": [";
321 
322  QgsLineStringV2* exteriorLineString = exteriorRing()->curveToLine();
323  QList<QgsPointV2> exteriorPts;
324  exteriorLineString->points( exteriorPts );
325  json += QgsGeometryUtils::pointsToJSON( exteriorPts, precision ) + ", ";
326  delete exteriorLineString;
327 
328  for ( int i = 0, n = numInteriorRings(); i < n; ++i )
329  {
330  QgsLineStringV2* interiorLineString = interiorRing( i )->curveToLine();
331  QList<QgsPointV2> interiorPts;
332  interiorLineString->points( interiorPts );
333  json += QgsGeometryUtils::pointsToJSON( interiorPts, precision ) + ", ";
334  delete interiorLineString;
335  }
336  if ( json.endsWith( ", " ) )
337  {
338  json.chop( 2 ); // Remove last ", "
339  }
340  json += "] }";
341  return json;
342 }
343 
345 {
346  if ( !mExteriorRing )
347  {
348  return 0.0;
349  }
350 
351  double totalArea = 0.0;
352 
353  if ( mExteriorRing->isClosed() )
354  {
355  double area = 0.0;
356  mExteriorRing->sumUpArea( area );
357  totalArea += qAbs( area );
358  }
359 
361  for ( ; ringIt != mInteriorRings.constEnd(); ++ringIt )
362  {
363  double area = 0.0;
364  if (( *ringIt )->isClosed() )
365  {
366  ( *ringIt )->sumUpArea( area );
367  totalArea -= qAbs( area );
368  }
369  }
370  return totalArea;
371 }
372 
374 {
375  //sum perimeter of rings
376  double perimeter = mExteriorRing->length();
378  for ( ; ringIt != mInteriorRings.constEnd(); ++ringIt )
379  {
380  perimeter += ( *ringIt )->length();
381  }
382  return perimeter;
383 }
384 
386 {
387  return QgsPointV2( 0, 0 );
388 }
389 
391 {
392  QgsPolygonV2* polygon = new QgsPolygonV2();
393  polygon->setExteriorRing( exteriorRing()->curveToLine() );
394  QList<QgsCurveV2*> interiors;
395  int n = numInteriorRings();
396  interiors.reserve( n );
397  for ( int i = 0; i < n; ++i )
398  {
399  interiors.append( interiorRing( i )->curveToLine() );
400  }
401  polygon->setInteriorRings( interiors );
402  return polygon;
403 }
404 
406 {
407  if ( !mExteriorRing )
408  {
409  return 0;
410  }
411 
412  QgsPolygonV2* poly = new QgsPolygonV2();
414 
415  QList<QgsCurveV2*> rings;
417  for ( ; it != mInteriorRings.constEnd(); ++it )
418  {
419  rings.push_back(( *it )->curveToLine() );
420  }
421  poly->setInteriorRings( rings );
422  return poly;
423 }
424 
426 {
427  return mInteriorRings.size();
428 }
429 
431 {
432  return mExteriorRing;
433 }
434 
436 {
437  if ( i >= mInteriorRings.size() )
438  {
439  return 0;
440  }
441  return mInteriorRings.at( i );
442 }
443 
445 {
446  if ( !ring )
447  {
448  return;
449  }
450  delete mExteriorRing;
451  mExteriorRing = ring;
452 
453  //set proper wkb type
454  if ( geometryType() == "Polygon" )
455  {
457  }
458  else if ( geometryType() == "CurvePolygon" )
459  {
461  }
462 }
463 
465 {
466  qDeleteAll( mInteriorRings );
467  mInteriorRings = rings;
468 }
469 
471 {
472  mInteriorRings.append( ring );
473 }
474 
476 {
477  if ( nr >= mInteriorRings.size() )
478  {
479  return false;
480  }
481  delete mInteriorRings.takeAt( nr );
482  return true;
483 }
484 
486 {
487  if ( mInteriorRings.size() < 1 )
488  {
489  if ( mExteriorRing )
490  {
492  }
493  }
494  else
495  {
496  QPainterPath path;
498 
500  for ( ; it != mInteriorRings.constEnd(); ++it )
501  {
502  ( *it )->addToPainterPath( path );
503  }
504  p.drawPath( path );
505  }
506 }
507 
509 {
510  if ( mExteriorRing )
511  {
512  mExteriorRing->transform( ct, d );
513  }
514 
516  for ( ; it != mInteriorRings.end(); ++it )
517  {
518  ( *it )->transform( ct, d );
519  }
520 }
521 
523 {
524  if ( mExteriorRing )
525  {
526  mExteriorRing->transform( t );
527  }
528 
530  for ( ; it != mInteriorRings.end(); ++it )
531  {
532  ( *it )->transform( t );
533  }
534 }
535 
537 {
538  coord.clear();
539 
540  QList< QList< QgsPointV2 > > coordinates;
541  QList< QgsPointV2 > ringCoords;
542  if ( mExteriorRing )
543  {
544  mExteriorRing->points( ringCoords );
545  coordinates.append( ringCoords );
546  }
547 
549  for ( ; it != mInteriorRings.constEnd(); ++it )
550  {
551  ( *it )->points( ringCoords );
552  coordinates.append( ringCoords );
553  }
554  coord.append( coordinates );
555 }
556 
557 double QgsCurvePolygonV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
558 {
559  if ( !mExteriorRing )
560  {
561  return 0.0;
562  }
563  QList<QgsCurveV2*> segmentList;
564  segmentList.append( mExteriorRing );
565  segmentList.append( mInteriorRings );
566  return QgsGeometryUtils::closestSegmentFromComponents( segmentList, QgsGeometryUtils::RING, pt, segmentPt, vertexAfter, leftOf, epsilon );
567 }
568 
570 {
571  if ( !mExteriorRing || vId.ring >= 1 + mInteriorRings.size() )
572  {
573  return false;
574  }
575 
576  if ( vId.ring < 0 )
577  {
578  vId.ring = 0; vId.vertex = -1;
579  if ( vId.part < 0 )
580  {
581  vId.part = 0;
582  }
583  return mExteriorRing->nextVertex( vId, vertex );
584  }
585  else
586  {
587  QgsCurveV2* ring = vId.ring == 0 ? mExteriorRing : mInteriorRings[vId.ring - 1];
588 
589  if ( ring->nextVertex( vId, vertex ) )
590  {
591  return true;
592  }
593  ++vId.ring;
594  vId.vertex = -1;
595  if ( vId.ring >= 1 + mInteriorRings.size() )
596  {
597  return false;
598  }
599  ring = mInteriorRings[ vId.ring - 1 ];
600  return ring->nextVertex( vId, vertex );
601  }
602 }
603 
604 bool QgsCurvePolygonV2::insertVertex( const QgsVertexId& vId, const QgsPointV2& vertex )
605 {
606  if ( !mExteriorRing || vId.ring < 0 || vId.ring >= 1 + mInteriorRings.size() )
607  {
608  return false;
609  }
610 
611  QgsCurveV2* ring = vId.ring == 0 ? mExteriorRing : mInteriorRings[vId.ring - 1];
612  int n = ring->numPoints();
613  bool success = ring->insertVertex( QgsVertexId( 0, 0, vId.vertex ), vertex );
614  if ( !success )
615  {
616  return false;
617  }
618 
619  // If first or last vertex is inserted, re-sync the last/first vertex
620  if ( vId.vertex == 0 )
621  ring->moveVertex( QgsVertexId( 0, 0, n ), vertex );
622  else if ( vId.vertex == n )
623  ring->moveVertex( QgsVertexId( 0, 0, 0 ), vertex );
624 
626  return true;
627 }
628 
629 bool QgsCurvePolygonV2::moveVertex( const QgsVertexId& vId, const QgsPointV2& newPos )
630 {
631  if ( !mExteriorRing || vId.ring < 0 || vId.ring >= 1 + mInteriorRings.size() )
632  {
633  return false;
634  }
635 
636  QgsCurveV2* ring = vId.ring == 0 ? mExteriorRing : mInteriorRings[vId.ring - 1];
637  int n = ring->numPoints();
638  bool success = ring->moveVertex( vId, newPos );
639  if ( success )
640  {
641  // If first or last vertex is moved, also move the last/first vertex
642  if ( vId.vertex == 0 )
643  ring->moveVertex( QgsVertexId( vId.part, vId.ring, n - 1 ), newPos );
644  else if ( vId.vertex == n - 1 )
645  ring->moveVertex( QgsVertexId( vId.part, vId.ring, 0 ), newPos );
647  }
648  return success;
649 }
650 
652 {
653  if ( !mExteriorRing || vId.ring < 0 || vId.ring >= 1 + mInteriorRings.size() )
654  {
655  return false;
656  }
657 
658  QgsCurveV2* ring = vId.ring == 0 ? mExteriorRing : mInteriorRings[vId.ring - 1];
659  int n = ring->numPoints();
660  if ( n <= 2 )
661  {
662  //no points will be left in ring, so remove whole ring
663  if ( vId.ring == 0 )
664  {
665  delete mExteriorRing;
666  mExteriorRing = 0;
667  if ( !mInteriorRings.isEmpty() )
668  {
670  }
671  }
672  else
673  {
674  removeInteriorRing( vId.ring - 1 );
675  }
677  return true;
678  }
679 
680  bool success = ring->deleteVertex( vId );
681  if ( success )
682  {
683  // If first or last vertex is removed, re-sync the last/first vertex
684  if ( vId.vertex == 0 )
685  ring->moveVertex( QgsVertexId( 0, 0, n - 2 ), ring->vertexAt( QgsVertexId( 0, 0, 0 ) ) );
686  else if ( vId.vertex == n - 1 )
687  ring->moveVertex( QgsVertexId( 0, 0, 0 ), ring->vertexAt( QgsVertexId( 0, 0, n - 2 ) ) );
689  }
690  return success;
691 }
692 
694 {
696  {
697  return true;
698  }
699 
701  for ( ; it != mInteriorRings.constEnd(); ++it )
702  {
703  if (( *it )->hasCurvedSegments() )
704  {
705  return true;
706  }
707  }
708  return false;
709 }
710 
712 {
713  return toPolygon();
714 }
715 
716 double QgsCurvePolygonV2::vertexAngle( const QgsVertexId& vertex ) const
717 {
718  if ( !mExteriorRing || vertex.ring < 0 || vertex.ring >= 1 + mInteriorRings.size() )
719  {
720  //makes no sense - conversion of false to double!
721  return false;
722  }
723 
724  QgsCurveV2* ring = vertex.ring == 0 ? mExteriorRing : mInteriorRings[vertex.ring - 1];
725  return ring->vertexAngle( vertex );
726 }
727 
728 int QgsCurvePolygonV2::vertexCount( int /*part*/, int ring ) const
729 {
730  return ring == 0 ? mExteriorRing->vertexCount() : mInteriorRings[ring - 1]->vertexCount();
731 }
732 
734 {
735  return id.ring == 0 ? mExteriorRing->vertexAt( id ) : mInteriorRings[id.ring - 1]->vertexAt( id );
736 }
737 
738 bool QgsCurvePolygonV2::addZValue( double zValue )
739 {
740  if ( QgsWKBTypes::hasZ( mWkbType ) )
741  return false;
742 
744 
745  if ( mExteriorRing )
746  mExteriorRing->addZValue( zValue );
747  Q_FOREACH ( QgsCurveV2* curve, mInteriorRings )
748  {
749  curve->addZValue( zValue );
750  }
751  return true;
752 }
753 
754 bool QgsCurvePolygonV2::addMValue( double mValue )
755 {
756  if ( QgsWKBTypes::hasM( mWkbType ) )
757  return false;
758 
760 
761  if ( mExteriorRing )
762  mExteriorRing->addMValue( mValue );
763  Q_FOREACH ( QgsCurveV2* curve, mInteriorRings )
764  {
765  curve->addMValue( mValue );
766  }
767  return true;
768 }
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.
virtual bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
virtual double vertexAngle(const QgsVertexId &vertex) const =0
Returns approximate rotation angle for a vertex.
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 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 of the geometry.
QgsPolygonV2 * surfaceToPolygon() const override
virtual void points(QList< QgsPointV2 > &pt) const =0
Returns a list of points within the curve.
void reserve(int alloc)
virtual QgsPointV2 vertexAt(const QgsVertexId &id) const override
Returns the point corresponding to a specified vertex id.
void removeFirst()
const T & at(int i) const
static QString pointsToJSON(const QList< QgsPointV2 > &points, int precision)
Returns a geoJSON coordinates string.
QgsCurveV2 * exteriorRing() const
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.
TransformDirection
Enum used to indicate the direction (forward or inverse) of the transform.
T takeAt(int i)
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)
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 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 bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
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 setInteriorRings(const QList< QgsCurveV2 * > &rings)
Sets all interior rings (takes ownership)
void append(const T &value)
virtual bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
virtual double perimeter() const override
Returns the perimeter of the geometry.
virtual QString geometryType() const override
Returns a unique string representing the geometry type.
static bool hasM(Type type)
Tests whether a WKB type contains m values.
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 int vertexCount(int=0, int=0) const override
Definition: qgscurvev2.h:92
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type.
virtual bool fromWkb(const unsigned char *wkb)=0
Sets the geometry from a WKB string.
Point geometry type.
Definition: qgspointv2.h:29
bool isEmpty() const
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
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
virtual void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform)=0
Transforms the geometry using a coordinate transform.
void setZMTypeFromSubGeometry(const QgsAbstractGeometryV2 *subggeom, QgsWKBTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform) override
Transforms the geometry using a coordinate transform.
T & first()
virtual bool nextVertex(QgsVertexId &id, QgsPointV2 &vertex) const override
Returns next vertex id and coordinates.
Definition: qgscurvev2.cpp:55
virtual int vertexCount(int=0, int ring=0) const override
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.
virtual QgsCurvePolygonV2 * clone() const override
Clones the geometry by performing a deep copy.
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()
virtual bool fromWkb(const unsigned char *wkb) override
Sets the geometry from a WKB string.
virtual void sumUpArea(double &sum) const =0
Calculates the area of the curve.
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
T takeFirst()
virtual bool isClosed() const
Returns true if the curve is closed.
Definition: qgscurvev2.cpp:27
virtual bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
Class for doing transforms between two map coordinate systems.
virtual QString asWkt(int precision=17) const =0
Returns a WKT representation of the geometry.
virtual QgsPointV2 vertexAt(const QgsVertexId &id) const override
Returns the point corresponding to a specified vertex id.
Definition: qgscurvev2.cpp:85
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
double vertexAngle(const QgsVertexId &vertex) const override
Returns approximate rotation angle for a vertex.
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()
QgsCurveV2 * interiorRing(int i) const
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.
virtual double area() const override
Returns the area of the geometry.
QgsCurveV2 * mExteriorRing