QGIS API Documentation 3.41.0-Master (fda2aa46e9a)
Loading...
Searching...
No Matches
qgsabstractgeometry.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsabstractgeometry.h
3 -------------------------------------------------------------------
4Date : 04 Sept 2014
5Copyright : (C) 2014 by Marco Hugentobler
6email : 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 <array>
20#include <functional>
21#include <type_traits>
22#include <QString>
23
24#include "qgis_core.h"
25#include "qgis.h"
26#include "qgswkbtypes.h"
27#include "qgswkbptr.h"
28
29#ifndef SIP_RUN
30#include <nlohmann/json_fwd.hpp>
31using namespace nlohmann;
32#endif
33
34class QgsMapToPixel;
35class QgsCurve;
36class QgsMultiCurve;
37class QgsMultiPoint;
38
39struct QgsVertexId;
41class QPainter;
42class QDomDocument;
43class QDomElement;
46class QgsConstWkbPtr;
47class QPainterPath;
49class QgsFeedback;
51class QgsPoint;
52class QgsRectangle;
53class QgsBox3D;
54
55typedef QVector< QgsPoint > QgsPointSequence;
56#ifndef SIP_RUN
57typedef QVector< QgsPointSequence > QgsRingSequence;
58typedef QVector< QgsRingSequence > QgsCoordinateSequence;
59#else
60typedef QVector< QVector< QgsPoint > > QgsRingSequence;
61typedef QVector< QVector< QVector< QgsPoint > > > QgsCoordinateSequence;
62#endif
63
64
79class CORE_EXPORT QgsAbstractGeometry
80{
81
82#ifdef SIP_RUN
84 if ( qgsgeometry_cast<QgsPoint *>( sipCpp ) != nullptr )
85 sipType = sipType_QgsPoint;
86 else if ( qgsgeometry_cast<QgsLineString *>( sipCpp ) != nullptr )
87 sipType = sipType_QgsLineString;
88 else if ( qgsgeometry_cast<QgsCircularString *>( sipCpp ) != nullptr )
89 sipType = sipType_QgsCircularString;
90 else if ( qgsgeometry_cast<QgsCompoundCurve *>( sipCpp ) != nullptr )
91 sipType = sipType_QgsCompoundCurve;
92 else if ( qgsgeometry_cast<QgsTriangle *>( sipCpp ) != nullptr )
93 sipType = sipType_QgsTriangle;
94 else if ( qgsgeometry_cast<QgsPolygon *>( sipCpp ) != nullptr )
95 sipType = sipType_QgsPolygon;
96 else if ( qgsgeometry_cast<QgsCurvePolygon *>( sipCpp ) != nullptr )
97 sipType = sipType_QgsCurvePolygon;
98 else if ( qgsgeometry_cast<QgsMultiPoint *>( sipCpp ) != nullptr )
99 sipType = sipType_QgsMultiPoint;
100 else if ( qgsgeometry_cast<QgsMultiLineString *>( sipCpp ) != nullptr )
101 sipType = sipType_QgsMultiLineString;
102 else if ( qgsgeometry_cast<QgsMultiPolygon *>( sipCpp ) != nullptr )
103 sipType = sipType_QgsMultiPolygon;
104 else if ( qgsgeometry_cast<QgsMultiSurface *>( sipCpp ) != nullptr )
105 sipType = sipType_QgsMultiSurface;
106 else if ( qgsgeometry_cast<QgsMultiCurve *>( sipCpp ) != nullptr )
107 sipType = sipType_QgsMultiCurve;
108 else if ( qgsgeometry_cast<QgsGeometryCollection *>( sipCpp ) != nullptr )
109 sipType = sipType_QgsGeometryCollection;
110 else
111 sipType = 0;
112 SIP_END
113#endif
114
115 Q_GADGET
116
117 public:
118
121 {
122
127 MaximumAngle = 0,
128
133 MaximumDifference
134 };
135 Q_ENUM( SegmentationToleranceType )
136
137
139 {
140
144 XY = 0,
145
149 YX
150 };
152
154 virtual ~QgsAbstractGeometry() = default;
156 QgsAbstractGeometry &operator=( const QgsAbstractGeometry &geom );
157
158 virtual bool operator==( const QgsAbstractGeometry &other ) const = 0;
159 virtual bool operator!=( const QgsAbstractGeometry &other ) const = 0;
160
171 virtual bool fuzzyEqual( const QgsAbstractGeometry &other, double epsilon = 1e-8 ) const = 0;
172
186 virtual bool fuzzyDistanceEqual( const QgsAbstractGeometry &other, double epsilon = 1e-8 ) const = 0;
187
191 virtual QgsAbstractGeometry *clone() const = 0 SIP_FACTORY;
192
198 virtual int compareTo( const QgsAbstractGeometry *other ) const;
199
203 virtual void clear() = 0;
204
208 virtual QgsRectangle boundingBox() const;
209
215 virtual QgsBox3D boundingBox3D() const = 0;
216
217 //mm-sql interface
218
223 virtual int dimension() const = 0;
224
230 virtual QString geometryType() const = 0;
231
237 inline Qgis::WkbType wkbType() const SIP_HOLDGIL { return mWkbType; }
238
244 QString wktTypeStr() const;
245
250 bool is3D() const SIP_HOLDGIL
251 {
252 return QgsWkbTypes::hasZ( mWkbType );
253 }
254
260 {
261 return QgsWkbTypes::hasM( mWkbType );
262 }
263
270
280 virtual void normalize() = 0;
281
282 //import
283
289 virtual bool fromWkb( QgsConstWkbPtr &wkb ) = 0;
290
295 virtual bool fromWkt( const QString &wkt ) = 0;
296
297 //export
298
304 {
305 FlagExportTrianglesAsPolygons = 1 << 0,
306 FlagExportNanAsDoubleMin = 1 << 1,
307 };
308 Q_DECLARE_FLAGS( WkbFlags, WkbFlag )
309
310
317 virtual int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const = 0;
318
329 virtual QByteArray asWkb( WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const = 0;
330
339 virtual QString asWkt( int precision = 17 ) const = 0;
340
352 virtual QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const = 0;
353
365 virtual QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const = 0;
366
376 QString asJson( int precision = 17 );
377
388 virtual json asJsonObject( int precision = 17 ) SIP_SKIP const;
389
394 virtual QString asKml( int precision = 17 ) const = 0;
395
396
397 //render pipeline
398
409 virtual void transform( const QgsCoordinateTransform &ct, Qgis::TransformDirection d = Qgis::TransformDirection::Forward, bool transformZ = false ) SIP_THROW( QgsCsException ) = 0;
410
417 virtual void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0,
418 double mTranslate = 0.0, double mScale = 1.0 ) = 0;
419
424 virtual void draw( QPainter &p ) const = 0;
425
434 virtual QPainterPath asQPainterPath() const = 0;
435
445 virtual int vertexNumberFromVertexId( QgsVertexId id ) const = 0;
446
454 virtual bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const = 0;
455
459 virtual void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const = 0;
460
465 virtual QgsCoordinateSequence coordinateSequence() const = 0;
466
470 virtual int nCoordinates() const;
471
475 virtual QgsPoint vertexAt( QgsVertexId id ) const = 0;
476
489 virtual double closestSegment( const QgsPoint &pt, QgsPoint &segmentPt SIP_OUT,
490 QgsVertexId &vertexAfter SIP_OUT,
491 int *leftOf SIP_OUT = nullptr, double epsilon = 4 * std::numeric_limits<double>::epsilon() ) const = 0;
492
493 //low-level editing
494
503 virtual bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) = 0;
504
513 virtual bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) = 0;
514
522 virtual bool deleteVertex( QgsVertexId position ) = 0;
523
536 virtual double length() const;
537
550 virtual double perimeter() const;
551
564 virtual double area() const;
565
573 virtual double segmentLength( QgsVertexId startVertex ) const = 0;
574
576 virtual QgsPoint centroid() const;
577
581 virtual bool isEmpty() const;
582
586 virtual bool hasCurvedSegments() const;
587
596 virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const SIP_HOLDGIL;
597
606 virtual bool boundingBoxIntersects( const QgsBox3D &box3d ) const SIP_HOLDGIL;
607
614 virtual QgsAbstractGeometry *segmentize( double tolerance = M_PI / 180., SegmentationToleranceType toleranceType = MaximumAngle ) const SIP_FACTORY;
615
622 virtual QgsAbstractGeometry *toCurveType() const = 0 SIP_FACTORY;
623
646 virtual QgsAbstractGeometry *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const = 0 SIP_FACTORY;
647
660 virtual QgsAbstractGeometry *simplifyByDistance( double tolerance ) const = 0 SIP_FACTORY;
661
681 virtual bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) = 0;
682
690 virtual double vertexAngle( QgsVertexId vertex ) const = 0;
691
695 virtual int vertexCount( int part = 0, int ring = 0 ) const = 0;
696
700 virtual int ringCount( int part = 0 ) const = 0;
701
707 virtual int partCount() const = 0;
708
716 virtual bool addZValue( double zValue = 0 ) = 0;
717
725 virtual bool addMValue( double mValue = 0 ) = 0;
726
733 virtual bool dropZValue() = 0;
734
741 virtual bool dropMValue() = 0;
742
749 virtual void swapXy() = 0;
750
755 virtual bool convertTo( Qgis::WkbType type );
756
775 virtual const QgsAbstractGeometry *simplifiedTypeRef() const SIP_HOLDGIL;
776
788 virtual bool isValid( QString &error SIP_OUT, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const = 0;
789
803 virtual bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) = 0;
804
805#ifndef SIP_RUN
806
816 virtual void filterVertices( const std::function< bool( const QgsPoint & ) > &filter );
817
832 virtual void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform );
833
839 class CORE_EXPORT part_iterator
840 {
841 private:
842
843 int mIndex = 0;
844 QgsAbstractGeometry *mGeometry = nullptr;
845
846 public:
848 part_iterator() = default;
849
851 part_iterator( QgsAbstractGeometry *g, int index );
852
857 part_iterator &operator++();
858
860 part_iterator operator++( int );
861
864
866 int partNumber() const;
867
868 bool operator==( part_iterator other ) const;
869 bool operator!=( part_iterator other ) const { return !( *this == other ); }
870 };
871
881 {
882 return part_iterator( this, 0 );
883 }
884
893 part_iterator parts_end();
894
902 QgsGeometryConstPartIterator parts() const;
903
909 class CORE_EXPORT const_part_iterator
910 {
911 private:
912
913 int mIndex = 0;
914 const QgsAbstractGeometry *mGeometry = nullptr;
915
916 public:
919
921 const_part_iterator( const QgsAbstractGeometry *g, int index );
922
927 const_part_iterator &operator++();
928
930 const_part_iterator operator++( int );
931
933 const QgsAbstractGeometry *operator*() const;
934
936 int partNumber() const;
937
938 bool operator==( const_part_iterator other ) const;
939 bool operator!=( const_part_iterator other ) const { return !( *this == other ); }
940 };
941
950 {
951 return const_part_iterator( this, 0 );
952 }
953
961 const_part_iterator const_parts_end() const;
962
963
968 class CORE_EXPORT vertex_iterator
969 {
970 private:
971
977 struct Level
978 {
979 const QgsAbstractGeometry *g = nullptr;
980 int index = 0;
981
982 bool operator==( const Level &other ) const;
983 };
984
985 std::array<Level, 3> levels;
986 int depth = -1;
987
988 void digDown();
989
990 public:
992 vertex_iterator() = default;
993
995 vertex_iterator( const QgsAbstractGeometry *g, int index );
996
1001 vertex_iterator &operator++();
1002
1004 vertex_iterator operator++( int );
1005
1007 QgsPoint operator*() const;
1008
1010 QgsVertexId vertexId() const;
1011
1012 bool operator==( const vertex_iterator &other ) const;
1013 bool operator!=( const vertex_iterator &other ) const { return !( *this == other ); }
1014 };
1015
1024 {
1025 return vertex_iterator( this, 0 );
1026 }
1027
1036 {
1037 return vertex_iterator( this, childCount() );
1038 }
1039#endif
1040
1075
1076
1099 QgsVertexIterator vertices() const;
1100
1107
1108 protected:
1109
1116 int sortIndex() const;
1117
1128 virtual int compareToSameClass( const QgsAbstractGeometry *other ) const = 0;
1129
1134 virtual bool hasChildGeometries() const;
1135
1140 virtual int childCount() const { return 0; }
1141
1146 virtual QgsAbstractGeometry *childGeometry( int index ) const { Q_UNUSED( index ) return nullptr; }
1147
1152 virtual QgsPoint childPoint( int index ) const;
1153
1154 protected:
1156
1160 void setZMTypeFromSubGeometry( const QgsAbstractGeometry *subggeom, Qgis::WkbType baseGeomType );
1161
1166 virtual QgsRectangle calculateBoundingBox() const;
1167
1174 virtual QgsBox3D calculateBoundingBox3D() const;
1175
1179 virtual void clearCache() const;
1180
1181 friend class TestQgsGeometry;
1182};
1183
1184
1185#ifndef SIP_RUN
1186
1187template <class T>
1189{
1190 return const_cast<T>( std::remove_pointer<T>::type::cast( geom ) );
1191}
1192
1193#endif
1194
1195// clazy:excludeall=qstring-allocations
1196
1201class CORE_EXPORT QgsVertexIterator
1202{
1203 public:
1204
1206
1209 : g( geometry )
1210 , i( g->vertices_begin() )
1211 , n( g->vertices_end() )
1212 {
1213 }
1214
1216 bool hasNext() const
1217 {
1218 return g && g->vertices_end() != i;
1219 }
1220
1222 QgsPoint next();
1223
1224#ifdef SIP_RUN
1225 QgsVertexIterator *__iter__();
1226 % MethodCode
1227 sipRes = sipCpp;
1228 % End
1229
1230 SIP_PYOBJECT __next__() SIP_TYPEHINT( QgsPoint );
1231 % MethodCode
1232 if ( sipCpp->hasNext() )
1233 sipRes = sipConvertFromType( new QgsPoint( sipCpp->next() ), sipType_QgsPoint, Py_None );
1234 else
1235 PyErr_SetString( PyExc_StopIteration, "" );
1236 % End
1237#endif
1238
1239 private:
1240 const QgsAbstractGeometry *g = nullptr;
1242
1243};
1244
1251{
1252 public:
1253
1255
1258 : g( geometry )
1259 , i( g->parts_begin() )
1260 , n( g->parts_end() )
1261 {
1262 }
1263
1266 {
1267 return g && g->parts_end() != i;
1268 }
1269
1271 QgsAbstractGeometry *next();
1272
1273#ifdef SIP_RUN
1274 QgsGeometryPartIterator *__iter__();
1275 % MethodCode
1276 sipRes = sipCpp;
1277 % End
1278
1279 SIP_PYOBJECT __next__() SIP_TYPEHINT( QgsAbstractGeometry );
1280 % MethodCode
1281 if ( sipCpp->hasNext() )
1282 sipRes = sipConvertFromType( sipCpp->next(), sipType_QgsAbstractGeometry, NULL );
1283 else
1284 PyErr_SetString( PyExc_StopIteration, "" );
1285 % End
1286#endif
1287
1288 private:
1289 QgsAbstractGeometry *g = nullptr;
1291
1292};
1293
1294
1301{
1302 public:
1303
1305
1308 : g( geometry )
1309 , i( g->const_parts_begin() )
1310 , n( g->const_parts_end() )
1311 {
1312 }
1313
1316 {
1317 return g && g->const_parts_end() != i;
1318 }
1319
1321 const QgsAbstractGeometry *next();
1322
1323#ifdef SIP_RUN
1324 QgsGeometryConstPartIterator *__iter__();
1325 % MethodCode
1326 sipRes = sipCpp;
1327 % End
1328
1329 SIP_PYOBJECT __next__() SIP_TYPEHINT( QgsAbstractGeometry );
1330 % MethodCode
1331 if ( sipCpp->hasNext() )
1332 sipRes = sipConvertFromType( const_cast< QgsAbstractGeometry * >( sipCpp->next() ), sipType_QgsAbstractGeometry, NULL );
1333 else
1334 PyErr_SetString( PyExc_StopIteration, "" );
1335 % End
1336#endif
1337
1338 private:
1339 const QgsAbstractGeometry *g = nullptr;
1341
1342};
1343
1345
1346#endif //QGSABSTRACTGEOMETRYV2
The Qgis class provides global constants for use throughout the application.
Definition qgis.h:54
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:256
@ Unknown
Unknown.
An abstract base class for classes which transform geometries by transforming input points to output ...
The part_iterator class provides STL-style iterator for const references to geometry parts.
bool operator!=(const_part_iterator other) const
const_part_iterator()=default
Create invalid iterator.
The part_iterator class provides STL-style iterator for geometry parts.
part_iterator()=default
Create invalid iterator.
bool operator!=(part_iterator other) const
The vertex_iterator class provides STL-style iterator for vertices.
vertex_iterator()=default
Create invalid iterator.
bool operator!=(const vertex_iterator &other) const
Abstract base class for all geometries.
virtual bool fromWkb(QgsConstWkbPtr &wkb)=0
Sets the geometry from a WKB string.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
virtual QgsAbstractGeometry * boundary() const =0
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
bool isMeasure() const
Returns true if the geometry contains m values.
QFlags< WkbFlag > WkbFlags
virtual int childCount() const
Returns number of child geometries (for geometries with child geometries) or child points (for geomet...
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
AxisOrder
Axis order for GML generation.
virtual QgsAbstractGeometry * createEmptyWithSameType() const =0
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
virtual bool fromWkt(const QString &wkt)=0
Sets the geometry from a WKT string.
virtual void normalize()=0
Reorganizes the geometry into a normalized form (or "canonical" form).
vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
virtual QgsAbstractGeometry * childGeometry(int index) const
Returns pointer to child geometry (for geometries with child geometries - i.e.
const_part_iterator const_parts_begin() const
Returns STL-style iterator pointing to the const first part of the geometry.
virtual int compareToSameClass(const QgsAbstractGeometry *other) const =0
Compares to an other geometry of the same class, and returns a integer for sorting of the two geometr...
part_iterator parts_begin()
Returns STL-style iterator pointing to the first part of the geometry.
A 3-dimensional box composed of x, y, z coordinates.
Definition qgsbox3d.h:43
A const WKB pointer.
Definition qgswkbptr.h:138
Class for doing transforms between two map coordinate systems.
Custom exception class for Coordinate Reference System related exceptions.
Abstract base class for curved geometry type.
Definition qgscurve.h:35
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
Java-style iterator for const traversal of parts of a geometry.
QgsGeometryConstPartIterator(const QgsAbstractGeometry *geometry)
Constructs iterator for the given geometry.
bool hasNext() const
Find out whether there are more parts.
Java-style iterator for traversal of parts of a geometry.
QgsGeometryPartIterator()=default
bool hasNext() const
Find out whether there are more parts.
QgsGeometryPartIterator(QgsAbstractGeometry *geometry)
Constructs iterator for the given geometry.
Perform transforms between map coordinates and device coordinates.
Multi curve geometry collection.
Multi point geometry collection.
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:49
A rectangle specified with double values.
Java-style iterator for traversal of vertices of a geometry.
bool hasNext() const
Find out whether there are more vertices.
QgsVertexIterator()=default
QgsVertexIterator(const QgsAbstractGeometry *geometry)
Constructs iterator for the given geometry.
static bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
#define SIP_TYPEHINT(type)
Definition qgis_sip.h:232
#define SIP_CONVERT_TO_SUBCLASS_CODE(code)
Definition qgis_sip.h:191
#define SIP_ENUM_BASETYPE(type)
Definition qgis_sip.h:278
#define SIP_SKIP
Definition qgis_sip.h:126
#define SIP_OUT
Definition qgis_sip.h:58
#define SIP_HOLDGIL
Definition qgis_sip.h:171
#define SIP_FACTORY
Definition qgis_sip.h:76
#define SIP_THROW(name,...)
Definition qgis_sip.h:203
#define SIP_END
Definition qgis_sip.h:208
T qgsgeometry_cast(const QgsAbstractGeometry *geom)
QVector< QgsRingSequence > QgsCoordinateSequence
QVector< QgsPointSequence > QgsRingSequence
QVector< QgsPoint > QgsPointSequence
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
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:249
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsTextRendererUtils::CurvedTextFlags)
double closestSegment(const QgsPolylineXY &pl, const QgsPointXY &pt, int &vertexAfter, double epsilon)
Definition qgstracer.cpp:70
int precision
Utility class for identifying a unique vertex within a geometry.
Definition qgsvertexid.h:30