QGIS API Documentation  3.6.0-Noosa (5873452)
qgsabstractgeometry.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsabstractgeometry.h
3  -------------------------------------------------------------------
4 Date : 04 Sept 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 #ifndef QGSABSTRACTGEOMETRYV2
17 #define QGSABSTRACTGEOMETRYV2
18 
19 #include <functional>
20 
21 #include <QString>
22 
23 #include "qgis_core.h"
24 #include "qgscoordinatetransform.h"
25 #include "qgswkbtypes.h"
26 #include "qgswkbptr.h"
27 
28 class QgsMapToPixel;
29 class QgsCurve;
30 class QgsMultiCurve;
31 class QgsMultiPoint;
32 
33 struct QgsVertexId;
34 class QgsVertexIterator;
35 class QPainter;
36 class QDomDocument;
37 class QDomElement;
41 
42 typedef QVector< QgsPoint > QgsPointSequence;
43 #ifndef SIP_RUN
44 typedef QVector< QgsPointSequence > QgsRingSequence;
45 typedef QVector< QgsRingSequence > QgsCoordinateSequence;
46 #else
47 typedef QVector< QVector< QgsPoint > > QgsRingSequence;
48 typedef QVector< QVector< QVector< QgsPoint > > > QgsCoordinateSequence;
49 #endif
50 
57 class CORE_EXPORT QgsAbstractGeometry
58 {
59 
60 #ifdef SIP_RUN
62  if ( qgsgeometry_cast<QgsPoint *>( sipCpp ) != nullptr )
63  sipType = sipType_QgsPoint;
64  else if ( qgsgeometry_cast<QgsLineString *>( sipCpp ) != nullptr )
65  sipType = sipType_QgsLineString;
66  else if ( qgsgeometry_cast<QgsCircularString *>( sipCpp ) != nullptr )
67  sipType = sipType_QgsCircularString;
68  else if ( qgsgeometry_cast<QgsCompoundCurve *>( sipCpp ) != nullptr )
69  sipType = sipType_QgsCompoundCurve;
70  else if ( qgsgeometry_cast<QgsTriangle *>( sipCpp ) != nullptr )
71  sipType = sipType_QgsTriangle;
72  else if ( qgsgeometry_cast<QgsPolygon *>( sipCpp ) != nullptr )
73  sipType = sipType_QgsPolygon;
74  else if ( qgsgeometry_cast<QgsCurvePolygon *>( sipCpp ) != nullptr )
75  sipType = sipType_QgsCurvePolygon;
76  else if ( qgsgeometry_cast<QgsMultiPoint *>( sipCpp ) != nullptr )
77  sipType = sipType_QgsMultiPoint;
78  else if ( qgsgeometry_cast<QgsMultiLineString *>( sipCpp ) != nullptr )
79  sipType = sipType_QgsMultiLineString;
80  else if ( qgsgeometry_cast<QgsMultiPolygon *>( sipCpp ) != nullptr )
81  sipType = sipType_QgsMultiPolygon;
82  else if ( qgsgeometry_cast<QgsMultiSurface *>( sipCpp ) != nullptr )
83  sipType = sipType_QgsMultiSurface;
84  else if ( qgsgeometry_cast<QgsMultiCurve *>( sipCpp ) != nullptr )
85  sipType = sipType_QgsMultiCurve;
86  else if ( qgsgeometry_cast<QgsGeometryCollection *>( sipCpp ) != nullptr )
87  sipType = sipType_QgsGeometryCollection;
88  else
89  sipType = 0;
90  SIP_END
91 #endif
92 
93  Q_GADGET
94 
95  public:
96 
99  {
100 
104  MaximumAngle = 0,
105 
109  MaximumDifference
110  };
111  Q_ENUM( SegmentationToleranceType )
112 
113 
115  {
116 
120  XY = 0,
121 
125  YX
126  };
128 
129 
132  QgsAbstractGeometry() = default;
133  virtual ~QgsAbstractGeometry() = default;
135  QgsAbstractGeometry &operator=( const QgsAbstractGeometry &geom );
136 
137  virtual bool operator==( const QgsAbstractGeometry &other ) const = 0;
138  virtual bool operator!=( const QgsAbstractGeometry &other ) const = 0;
139 
143  virtual QgsAbstractGeometry *clone() const = 0 SIP_FACTORY;
144 
148  virtual void clear() = 0;
149 
153  virtual QgsRectangle boundingBox() const = 0;
154 
155  //mm-sql interface
156 
161  virtual int dimension() const = 0;
162 
168  virtual QString geometryType() const = 0;
169 
175  inline QgsWkbTypes::Type wkbType() const { return mWkbType; }
176 
182  QString wktTypeStr() const;
183 
188  bool is3D() const
189  {
190  return QgsWkbTypes::hasZ( mWkbType );
191  }
192 
197  bool isMeasure() const
198  {
199  return QgsWkbTypes::hasM( mWkbType );
200  }
201 
208  virtual QgsAbstractGeometry *boundary() const = 0 SIP_FACTORY;
209 
210  //import
211 
217  virtual bool fromWkb( QgsConstWkbPtr &wkb ) = 0;
218 
223  virtual bool fromWkt( const QString &wkt ) = 0;
224 
225  //export
226 
235  virtual QByteArray asWkb() const = 0;
236 
245  virtual QString asWkt( int precision = 17 ) const = 0;
246 
258  virtual QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const = 0;
259 
271  virtual QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const = 0;
272 
281  virtual QString asJson( int precision = 17 ) const = 0;
282 
283  //render pipeline
284 
295  virtual void transform( const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform, bool transformZ = false ) SIP_THROW( QgsCsException ) = 0;
296 
303  virtual void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0,
304  double mTranslate = 0.0, double mScale = 1.0 ) = 0;
305 
310  virtual void draw( QPainter &p ) const = 0;
311 
322  virtual int vertexNumberFromVertexId( QgsVertexId id ) const = 0;
323 
331  virtual bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const = 0;
332 
337  virtual void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const = 0;
338 
343  virtual QgsCoordinateSequence coordinateSequence() const = 0;
344 
348  virtual int nCoordinates() const;
349 
353  virtual QgsPoint vertexAt( QgsVertexId id ) const = 0;
354 
367  virtual double closestSegment( const QgsPoint &pt, QgsPoint &segmentPt SIP_OUT,
368  QgsVertexId &vertexAfter SIP_OUT,
369  int *leftOf SIP_OUT = nullptr, double epsilon = 4 * std::numeric_limits<double>::epsilon() ) const = 0;
370 
371  //low-level editing
372 
381  virtual bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) = 0;
382 
391  virtual bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) = 0;
392 
400  virtual bool deleteVertex( QgsVertexId position ) = 0;
401 
407  virtual double length() const;
408 
414  virtual double perimeter() const;
415 
421  virtual double area() const;
422 
427  virtual double segmentLength( QgsVertexId startVertex ) const = 0;
428 
430  virtual QgsPoint centroid() const;
431 
435  virtual bool isEmpty() const;
436 
440  virtual bool hasCurvedSegments() const;
441 
448  virtual QgsAbstractGeometry *segmentize( double tolerance = M_PI / 180., SegmentationToleranceType toleranceType = MaximumAngle ) const SIP_FACTORY;
449 
456  virtual QgsAbstractGeometry *toCurveType() const = 0 SIP_FACTORY;
457 
477  virtual QgsAbstractGeometry *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const = 0 SIP_FACTORY;
478 
499  virtual bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) = 0;
500 
508  virtual double vertexAngle( QgsVertexId vertex ) const = 0;
509 
513  virtual int vertexCount( int part = 0, int ring = 0 ) const = 0;
514 
518  virtual int ringCount( int part = 0 ) const = 0;
519 
525  virtual int partCount() const = 0;
526 
535  virtual bool addZValue( double zValue = 0 ) = 0;
536 
545  virtual bool addMValue( double mValue = 0 ) = 0;
546 
554  virtual bool dropZValue() = 0;
555 
563  virtual bool dropMValue() = 0;
564 
571  virtual void swapXy() = 0;
572 
578  virtual bool convertTo( QgsWkbTypes::Type type );
579 
580 #ifndef SIP_RUN
581 
591  virtual void filterVertices( const std::function< bool( const QgsPoint & ) > &filter );
592 
607  virtual void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform );
608 
614  class CORE_EXPORT part_iterator
615  {
616  private:
617 
618  int mIndex = 0;
619  QgsAbstractGeometry *mGeometry = nullptr;
620 
621  public:
623  part_iterator() = default;
624 
626  part_iterator( QgsAbstractGeometry *g, int index );
627 
632  part_iterator &operator++();
633 
635  part_iterator operator++( int );
636 
639 
641  int partNumber() const;
642 
643  bool operator==( part_iterator other ) const;
644  bool operator!=( part_iterator other ) const { return !( *this == other ); }
645  };
646 
656  {
657  return part_iterator( this, 0 );
658  }
659 
668  part_iterator parts_end();
669 
677  QgsGeometryConstPartIterator parts() const;
678 
684  class CORE_EXPORT const_part_iterator
685  {
686  private:
687 
688  int mIndex = 0;
689  const QgsAbstractGeometry *mGeometry = nullptr;
690 
691  public:
693  const_part_iterator() = default;
694 
696  const_part_iterator( const QgsAbstractGeometry *g, int index );
697 
702  const_part_iterator &operator++();
703 
705  const_part_iterator operator++( int );
706 
708  const QgsAbstractGeometry *operator*() const;
709 
711  int partNumber() const;
712 
713  bool operator==( const_part_iterator other ) const;
714  bool operator!=( const_part_iterator other ) const { return !( *this == other ); }
715  };
716 
725  {
726  return const_part_iterator( this, 0 );
727  }
728 
736  const_part_iterator const_parts_end() const;
737 
738 
744  class CORE_EXPORT vertex_iterator
745  {
746  private:
747 
753  struct Level
754  {
755  const QgsAbstractGeometry *g = nullptr;
756  int index = 0;
757  };
758 
759  Level levels[3];
760  int depth = -1;
761 
762  void digDown();
763 
764  public:
766  vertex_iterator() = default;
767 
769  vertex_iterator( const QgsAbstractGeometry *g, int index );
770 
775  vertex_iterator &operator++();
776 
778  vertex_iterator operator++( int );
779 
781  QgsPoint operator*() const;
782 
784  QgsVertexId vertexId() const;
785 
786  bool operator==( const vertex_iterator &other ) const;
787  bool operator!=( const vertex_iterator &other ) const { return !( *this == other ); }
788  };
789 
799  {
800  return vertex_iterator( this, 0 );
801  }
802 
812  {
813  return vertex_iterator( this, childCount() );
814  }
815 #endif
816 
849  QgsGeometryPartIterator parts();
850 
851 
874  QgsVertexIterator vertices() const;
875 
882  virtual QgsAbstractGeometry *createEmptyWithSameType() const = 0 SIP_FACTORY;
883 
884  protected:
885 
891  virtual bool hasChildGeometries() const;
892 
898  virtual int childCount() const { return 0; }
899 
905  virtual QgsAbstractGeometry *childGeometry( int index ) const { Q_UNUSED( index ); return nullptr; }
906 
912  virtual QgsPoint childPoint( int index ) const;
913 
914  protected:
916 
920  void setZMTypeFromSubGeometry( const QgsAbstractGeometry *subggeom, QgsWkbTypes::Type baseGeomType );
921 
926  virtual QgsRectangle calculateBoundingBox() const;
927 
931  virtual void clearCache() const;
932 
933  friend class TestQgsGeometry;
934 };
935 
936 
943 struct CORE_EXPORT QgsVertexId
944 {
946  {
947  SegmentVertex = 1, //start / endpoint of a segment
948  CurveVertex
949  };
950 
951  explicit QgsVertexId( int _part = -1, int _ring = -1, int _vertex = -1, VertexType _type = SegmentVertex )
952  : part( _part )
953  , ring( _ring )
954  , vertex( _vertex )
955  , type( _type )
956  {}
957 
961  bool isValid() const { return part >= 0 && ring >= 0 && vertex >= 0; }
962 
963  bool operator==( QgsVertexId other ) const
964  {
965  return part == other.part && ring == other.ring && vertex == other.vertex;
966  }
967  bool operator!=( QgsVertexId other ) const
968  {
969  return part != other.part || ring != other.ring || vertex != other.vertex;
970  }
971  bool partEqual( QgsVertexId o ) const
972  {
973  return part >= 0 && o.part == part;
974  }
975  bool ringEqual( QgsVertexId o ) const
976  {
977  return partEqual( o ) && ( ring >= 0 && o.ring == ring );
978  }
979  bool vertexEqual( QgsVertexId o ) const
980  {
981  return ringEqual( o ) && ( vertex >= 0 && o.ring == ring );
982  }
983  bool isValid( const QgsAbstractGeometry *geom ) const
984  {
985  return ( part >= 0 && part < geom->partCount() ) &&
986  ( ring < geom->ringCount( part ) ) &&
987  ( vertex < 0 || vertex < geom->vertexCount( part, ring ) );
988  }
989 
990  int part;
991  int ring;
992  int vertex;
994 };
995 
996 #ifndef SIP_RUN
997 
998 template <class T>
999 inline T qgsgeometry_cast( const QgsAbstractGeometry *geom )
1000 {
1001  return const_cast<T>( reinterpret_cast<T>( 0 )->cast( geom ) );
1002 }
1003 
1004 #endif
1005 
1006 // clazy:excludeall=qstring-allocations
1007 
1013 class CORE_EXPORT QgsVertexIterator
1014 {
1015  public:
1017  QgsVertexIterator() = default;
1018 
1021  : g( geometry )
1022  , i( g->vertices_begin() )
1023  , n( g->vertices_end() )
1024  {
1025  }
1026 
1028  bool hasNext() const
1029  {
1030  return g && g->vertices_end() != i;
1031  }
1032 
1034  QgsPoint next();
1035 
1036 #ifdef SIP_RUN
1037  QgsVertexIterator *__iter__();
1038  % MethodCode
1039  sipRes = sipCpp;
1040  % End
1041 
1042  SIP_PYOBJECT __next__() SIP_TYPEHINT( QgsPoint );
1043  % MethodCode
1044  if ( sipCpp->hasNext() )
1045  sipRes = sipConvertFromType( new QgsPoint( sipCpp->next() ), sipType_QgsPoint, Py_None );
1046  else
1047  PyErr_SetString( PyExc_StopIteration, "" );
1048  % End
1049 #endif
1050 
1051  private:
1052  const QgsAbstractGeometry *g = nullptr;
1054 
1055 };
1056 
1062 class CORE_EXPORT QgsGeometryPartIterator
1063 {
1064  public:
1066  QgsGeometryPartIterator() = default;
1067 
1070  : g( geometry )
1071  , i( g->parts_begin() )
1072  , n( g->parts_end() )
1073  {
1074  }
1075 
1077  bool hasNext() const
1078  {
1079  return g && g->parts_end() != i;
1080  }
1081 
1083  QgsAbstractGeometry *next();
1084 
1085 #ifdef SIP_RUN
1086  QgsGeometryPartIterator *__iter__();
1087  % MethodCode
1088  sipRes = sipCpp;
1089  % End
1090 
1091  SIP_PYOBJECT __next__() SIP_TYPEHINT( QgsAbstractGeometry );
1092  % MethodCode
1093  if ( sipCpp->hasNext() )
1094  sipRes = sipConvertFromType( sipCpp->next(), sipType_QgsAbstractGeometry, NULL );
1095  else
1096  PyErr_SetString( PyExc_StopIteration, "" );
1097  % End
1098 #endif
1099 
1100  private:
1101  QgsAbstractGeometry *g = nullptr;
1103 
1104 };
1105 
1106 
1113 {
1114  public:
1116  QgsGeometryConstPartIterator() = default;
1117 
1120  : g( geometry )
1121  , i( g->const_parts_begin() )
1122  , n( g->const_parts_end() )
1123  {
1124  }
1125 
1127  bool hasNext() const
1128  {
1129  return g && g->const_parts_end() != i;
1130  }
1131 
1133  const QgsAbstractGeometry *next();
1134 
1135 #ifdef SIP_RUN
1136  QgsGeometryConstPartIterator *__iter__();
1137  % MethodCode
1138  sipRes = sipCpp;
1139  % End
1140 
1141  SIP_PYOBJECT __next__() SIP_TYPEHINT( QgsAbstractGeometry );
1142  % MethodCode
1143  if ( sipCpp->hasNext() )
1144  sipRes = sipConvertFromType( const_cast< QgsAbstractGeometry * >( sipCpp->next() ), sipType_QgsAbstractGeometry, NULL );
1145  else
1146  PyErr_SetString( PyExc_StopIteration, "" );
1147  % End
1148 #endif
1149 
1150  private:
1151  const QgsAbstractGeometry *g = nullptr;
1153 
1154 };
1155 
1156 #endif //QGSABSTRACTGEOMETRYV2
bool isMeasure() const
Returns true if the geometry contains m values.
int precision
A rectangle specified with double values.
Definition: qgsrectangle.h:41
Java-style iterator for traversal of parts of a geometry.
QgsVertexId(int _part=-1, int _ring=-1, int _vertex=-1, VertexType _type=SegmentVertex)
virtual int childCount() const
Returns number of child geometries (for geometries with child geometries) or child points (for geomet...
bool operator!=(const_part_iterator other) const
Java-style iterator for traversal of vertices of a geometry.
Multi point geometry collection.
Definition: qgsmultipoint.h:29
bool isValid() const
Returns true if the vertex id is valid.
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
QVector< QgsRingSequence > QgsCoordinateSequence
Java-style iterator for const traversal of parts of a geometry.
bool operator!=(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
TransformDirection
Enum used to indicate the direction (forward or inverse) of the transform.
virtual QgsAbstractGeometry * childGeometry(int index) const
Returns pointer to child geometry (for geometries with child geometries - i.e.
The part_iterator class provides STL-style iterator for const references to geometry parts...
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle...
bool operator!=(const vertex_iterator &other) const
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:206
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:770
bool vertexEqual(QgsVertexId o) const
bool operator!=(QgsVertexId other) const
bool hasNext() const
Find out whether there are more parts.
QgsVertexIterator(const QgsAbstractGeometry *geometry)
Constructs iterator for the given geometry.
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:37
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
QgsGeometryPartIterator(QgsAbstractGeometry *geometry)
Constructs iterator for the given geometry.
Utility class for identifying a unique vertex within a geometry.
The part_iterator class provides STL-style iterator for geometry parts.
vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry...
T qgsgeometry_cast(const QgsAbstractGeometry *geom)
#define SIP_END
Definition: qgis_sip.h:182
Multi curve geometry collection.
Definition: qgsmulticurve.h:29
virtual int ringCount(int part=0) const =0
Returns the number of rings of which this geometry is built.
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
#define SIP_FACTORY
Definition: qgis_sip.h:69
Abstract base class for all geometries.
The vertex_iterator class provides STL-style iterator for vertices.
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
AxisOrder
Axis order for GML generation.
QgsGeometryConstPartIterator(const QgsAbstractGeometry *geometry)
Constructs iterator for the given geometry.
double closestSegment(const QgsPolylineXY &pl, const QgsPointXY &pt, int &vertexAfter, double epsilon)
Definition: qgstracer.cpp:68
QVector< QgsPoint > QgsPointSequence
bool operator==(QgsVertexId other) const
QVector< QgsPointSequence > QgsRingSequence
bool partEqual(QgsVertexId o) const
bool ringEqual(QgsVertexId o) const
const_part_iterator const_parts_begin() const
Returns STL-style iterator pointing to the const first part of the geometry.
#define SIP_OUT
Definition: qgis_sip.h:51
#define SIP_CONVERT_TO_SUBCLASS_CODE(code)
Definition: qgis_sip.h:165
Class for doing transforms between two map coordinate systems.
#define SIP_THROW(name)
Definition: qgis_sip.h:177
static bool hasM(Type type)
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:820
Transform from source to destination CRS.
QgsMargins operator*(const QgsMargins &margins, double factor)
Returns a QgsMargins object that is formed by multiplying each component of the given margins by fact...
Definition: qgsmargins.h:242
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
bool hasNext() const
Find out whether there are more vertices.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
bool operator!=(part_iterator other) const
part_iterator parts_begin()
Returns STL-style iterator pointing to the first part of the geometry.
double ANALYSIS_EXPORT leftOf(const QgsPoint &thepoint, const QgsPoint *p1, const QgsPoint *p2)
Returns whether &#39;thepoint&#39; is left or right of the line from &#39;p1&#39; to &#39;p2&#39;. Negativ values mean left a...
Definition: MathUtils.cpp:292
bool isValid(const QgsAbstractGeometry *geom) const
bool hasNext() const
Find out whether there are more parts.