QGIS API Documentation  3.2.0-Bonn (bc43194)
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 <QString>
20 
21 #include "qgis_core.h"
22 #include "qgis.h"
23 #include "qgscoordinatetransform.h"
24 #include "qgswkbtypes.h"
25 #include "qgswkbptr.h"
26 
27 class QgsMapToPixel;
28 class QgsCurve;
29 class QgsMultiCurve;
30 class QgsMultiPoint;
31 class QgsPoint;
32 struct QgsVertexId;
33 class QgsVertexIterator;
34 class QPainter;
35 class QDomDocument;
36 class QDomElement;
37 
38 typedef QVector< QgsPoint > QgsPointSequence;
39 #ifndef SIP_RUN
40 typedef QVector< QgsPointSequence > QgsRingSequence;
41 typedef QVector< QgsRingSequence > QgsCoordinateSequence;
42 #else
43 typedef QVector< QVector< QgsPoint > > QgsRingSequence;
44 typedef QVector< QVector< QVector< QgsPoint > > > QgsCoordinateSequence;
45 #endif
46 
53 class CORE_EXPORT QgsAbstractGeometry
54 {
55 
56 #ifdef SIP_RUN
58  if ( qgsgeometry_cast<QgsPoint *>( sipCpp ) != nullptr )
59  sipType = sipType_QgsPoint;
60  else if ( qgsgeometry_cast<QgsLineString *>( sipCpp ) != nullptr )
61  sipType = sipType_QgsLineString;
62  else if ( qgsgeometry_cast<QgsCircularString *>( sipCpp ) != nullptr )
63  sipType = sipType_QgsCircularString;
64  else if ( qgsgeometry_cast<QgsCompoundCurve *>( sipCpp ) != nullptr )
65  sipType = sipType_QgsCompoundCurve;
66  else if ( qgsgeometry_cast<QgsTriangle *>( sipCpp ) != nullptr )
67  sipType = sipType_QgsTriangle;
68  else if ( qgsgeometry_cast<QgsPolygon *>( sipCpp ) != nullptr )
69  sipType = sipType_QgsPolygon;
70  else if ( qgsgeometry_cast<QgsCurvePolygon *>( sipCpp ) != nullptr )
71  sipType = sipType_QgsCurvePolygon;
72  else if ( qgsgeometry_cast<QgsMultiPoint *>( sipCpp ) != nullptr )
73  sipType = sipType_QgsMultiPoint;
74  else if ( qgsgeometry_cast<QgsMultiLineString *>( sipCpp ) != nullptr )
75  sipType = sipType_QgsMultiLineString;
76  else if ( qgsgeometry_cast<QgsMultiPolygon *>( sipCpp ) != nullptr )
77  sipType = sipType_QgsMultiPolygon;
78  else if ( qgsgeometry_cast<QgsMultiSurface *>( sipCpp ) != nullptr )
79  sipType = sipType_QgsMultiSurface;
80  else if ( qgsgeometry_cast<QgsMultiCurve *>( sipCpp ) != nullptr )
81  sipType = sipType_QgsMultiCurve;
82  else if ( qgsgeometry_cast<QgsGeometryCollection *>( sipCpp ) != nullptr )
83  sipType = sipType_QgsGeometryCollection;
84  else
85  sipType = 0;
86  SIP_END
87 #endif
88 
89  Q_GADGET
90 
91  public:
92 
95  {
96 
100  MaximumAngle = 0,
101 
105  MaximumDifference
106  };
107  Q_ENUM( SegmentationToleranceType )
108 
109 
111  {
112 
116  XY = 0,
117 
121  YX
122  };
124 
125 
128  QgsAbstractGeometry() = default;
129  virtual ~QgsAbstractGeometry() = default;
131  QgsAbstractGeometry &operator=( const QgsAbstractGeometry &geom );
132 
133  virtual bool operator==( const QgsAbstractGeometry &other ) const = 0;
134  virtual bool operator!=( const QgsAbstractGeometry &other ) const = 0;
135 
139  virtual QgsAbstractGeometry *clone() const = 0 SIP_FACTORY;
140 
144  virtual void clear() = 0;
145 
149  virtual QgsRectangle boundingBox() const = 0;
150 
151  //mm-sql interface
152 
157  virtual int dimension() const = 0;
158 
164  virtual QString geometryType() const = 0;
165 
171  inline QgsWkbTypes::Type wkbType() const { return mWkbType; }
172 
178  QString wktTypeStr() const;
179 
184  bool is3D() const
185  {
186  return QgsWkbTypes::hasZ( mWkbType );
187  }
188 
193  bool isMeasure() const
194  {
195  return QgsWkbTypes::hasM( mWkbType );
196  }
197 
204  virtual QgsAbstractGeometry *boundary() const = 0 SIP_FACTORY;
205 
206  //import
207 
213  virtual bool fromWkb( QgsConstWkbPtr &wkb ) = 0;
214 
219  virtual bool fromWkt( const QString &wkt ) = 0;
220 
221  //export
222 
231  virtual QByteArray asWkb() const = 0;
232 
241  virtual QString asWkt( int precision = 17 ) const = 0;
242 
254  virtual QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const = 0;
255 
267  virtual QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const = 0;
268 
277  virtual QString asJson( int precision = 17 ) const = 0;
278 
279  //render pipeline
280 
291  virtual void transform( const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform, bool transformZ = false ) SIP_THROW( QgsCsException ) = 0;
292 
299  virtual void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0,
300  double mTranslate = 0.0, double mScale = 1.0 ) = 0;
301 
306  virtual void draw( QPainter &p ) const = 0;
307 
318  virtual int vertexNumberFromVertexId( QgsVertexId id ) const = 0;
319 
327  virtual bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const = 0;
328 
333  virtual void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const = 0;
334 
339  virtual QgsCoordinateSequence coordinateSequence() const = 0;
340 
344  virtual int nCoordinates() const;
345 
349  virtual QgsPoint vertexAt( QgsVertexId id ) const = 0;
350 
363  virtual double closestSegment( const QgsPoint &pt, QgsPoint &segmentPt SIP_OUT,
364  QgsVertexId &vertexAfter SIP_OUT,
365  int *leftOf SIP_OUT = nullptr, double epsilon = 4 * std::numeric_limits<double>::epsilon() ) const = 0;
366 
367  //low-level editing
368 
377  virtual bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) = 0;
378 
387  virtual bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) = 0;
388 
396  virtual bool deleteVertex( QgsVertexId position ) = 0;
397 
403  virtual double length() const;
404 
410  virtual double perimeter() const;
411 
417  virtual double area() const;
418 
423  virtual double segmentLength( QgsVertexId startVertex ) const = 0;
424 
426  virtual QgsPoint centroid() const;
427 
431  virtual bool isEmpty() const;
432 
436  virtual bool hasCurvedSegments() const;
437 
444  virtual QgsAbstractGeometry *segmentize( double tolerance = M_PI / 180., SegmentationToleranceType toleranceType = MaximumAngle ) const SIP_FACTORY;
445 
452  virtual QgsAbstractGeometry *toCurveType() const = 0 SIP_FACTORY;
453 
473  virtual QgsAbstractGeometry *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const = 0 SIP_FACTORY;
474 
495  virtual bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) = 0;
496 
504  virtual double vertexAngle( QgsVertexId vertex ) const = 0;
505 
509  virtual int vertexCount( int part = 0, int ring = 0 ) const = 0;
510 
514  virtual int ringCount( int part = 0 ) const = 0;
515 
521  virtual int partCount() const = 0;
522 
531  virtual bool addZValue( double zValue = 0 ) = 0;
532 
541  virtual bool addMValue( double mValue = 0 ) = 0;
542 
550  virtual bool dropZValue() = 0;
551 
559  virtual bool dropMValue() = 0;
560 
567  virtual void swapXy() = 0;
568 
574  virtual bool convertTo( QgsWkbTypes::Type type );
575 
576 #ifndef SIP_RUN
577 
587  virtual void filterVertices( const std::function< bool( const QgsPoint & ) > &filter );
588 
594  class CORE_EXPORT vertex_iterator
595  {
596  private:
597 
603  struct Level
604  {
605  const QgsAbstractGeometry *g = nullptr;
606  int index = 0;
607  };
608 
609  Level levels[3];
610  int depth = -1;
611 
612  void digDown();
613 
614  public:
616  vertex_iterator() = default;
617 
619  vertex_iterator( const QgsAbstractGeometry *g, int index );
620 
625  vertex_iterator &operator++();
626 
628  vertex_iterator operator++( int );
629 
631  QgsPoint operator*() const;
632 
634  QgsVertexId vertexId() const;
635 
636  bool operator==( const vertex_iterator &other ) const;
637  bool operator!=( const vertex_iterator &other ) const { return !( *this == other ); }
638  };
639 
645  {
646  return vertex_iterator( this, 0 );
647  }
648 
654  {
655  return vertex_iterator( this, childCount() );
656  }
657 #endif
658 
663  QgsVertexIterator vertices() const;
664 
671  virtual QgsAbstractGeometry *createEmptyWithSameType() const = 0 SIP_FACTORY;
672 
673  protected:
674 
680  virtual bool hasChildGeometries() const;
681 
687  virtual int childCount() const { return 0; }
688 
694  virtual QgsAbstractGeometry *childGeometry( int index ) const { Q_UNUSED( index ); return nullptr; }
695 
701  virtual QgsPoint childPoint( int index ) const;
702 
703  protected:
705 
709  void setZMTypeFromSubGeometry( const QgsAbstractGeometry *subggeom, QgsWkbTypes::Type baseGeomType );
710 
715  virtual QgsRectangle calculateBoundingBox() const;
716 
720  virtual void clearCache() const;
721 
722  friend class TestQgsGeometry;
723 };
724 
725 
732 struct CORE_EXPORT QgsVertexId
733 {
735  {
736  SegmentVertex = 1, //start / endpoint of a segment
737  CurveVertex
738  };
739 
740  explicit QgsVertexId( int _part = -1, int _ring = -1, int _vertex = -1, VertexType _type = SegmentVertex )
741  : part( _part )
742  , ring( _ring )
743  , vertex( _vertex )
744  , type( _type )
745  {}
746 
750  bool isValid() const { return part >= 0 && ring >= 0 && vertex >= 0; }
751 
752  bool operator==( QgsVertexId other ) const
753  {
754  return part == other.part && ring == other.ring && vertex == other.vertex;
755  }
756  bool operator!=( QgsVertexId other ) const
757  {
758  return part != other.part || ring != other.ring || vertex != other.vertex;
759  }
760  bool partEqual( QgsVertexId o ) const
761  {
762  return part >= 0 && o.part == part;
763  }
764  bool ringEqual( QgsVertexId o ) const
765  {
766  return partEqual( o ) && ( ring >= 0 && o.ring == ring );
767  }
768  bool vertexEqual( QgsVertexId o ) const
769  {
770  return ringEqual( o ) && ( vertex >= 0 && o.ring == ring );
771  }
772  bool isValid( const QgsAbstractGeometry *geom ) const
773  {
774  return ( part >= 0 && part < geom->partCount() ) &&
775  ( ring < geom->ringCount( part ) ) &&
776  ( vertex < 0 || vertex < geom->vertexCount( part, ring ) );
777  }
778 
779  int part;
780  int ring;
781  int vertex;
783 };
784 
785 #ifndef SIP_RUN
786 
787 template <class T>
788 inline T qgsgeometry_cast( const QgsAbstractGeometry *geom )
789 {
790  return const_cast<T>( reinterpret_cast<T>( 0 )->cast( geom ) );
791 }
792 
793 #endif
794 
795 // clazy:excludeall=qstring-allocations
796 
802 class CORE_EXPORT QgsVertexIterator
803 {
804  public:
806  QgsVertexIterator() = default;
807 
810  : g( geometry )
811  , i( g->vertices_begin() )
812  , n( g->vertices_end() )
813  {
814  }
815 
817  bool hasNext() const
818  {
819  return g && g->vertices_end() != i;
820  }
821 
823  QgsPoint next();
824 
825 #ifdef SIP_RUN
826  QgsVertexIterator *__iter__();
827  % MethodCode
828  sipRes = sipCpp;
829  % End
830 
831  SIP_PYOBJECT __next__();
832  % MethodCode
833  if ( sipCpp->hasNext() )
834  sipRes = sipConvertFromType( new QgsPoint( sipCpp->next() ), sipType_QgsPoint, Py_None );
835  else
836  PyErr_SetString( PyExc_StopIteration, "" );
837  % End
838 #endif
839 
840  private:
841  const QgsAbstractGeometry *g = nullptr;
843 
844 };
845 
846 #endif //QGSABSTRACTGEOMETRYV2
bool isMeasure() const
Returns true if the geometry contains m values.
A rectangle specified with double values.
Definition: qgsrectangle.h:40
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...
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
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.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle...
bool operator!=(const vertex_iterator &other) const
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:768
bool vertexEqual(QgsVertexId o) const
bool operator!=(QgsVertexId other) const
QgsVertexIterator(const QgsAbstractGeometry *geometry)
Constructs iterator for the given geometry.
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:36
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:67
Utility class for identifying a unique vertex within a geometry.
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.
double closestSegment(const QgsPolylineXY &pl, const QgsPointXY &pt, int &vertexAfter, double epsilon)
Definition: qgstracer.cpp:65
QVector< QgsPoint > QgsPointSequence
bool operator==(QgsVertexId other) const
QVector< QgsPointSequence > QgsRingSequence
bool partEqual(QgsVertexId o) const
bool ringEqual(QgsVertexId o) const
#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:818
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.
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