QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsgeometry.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgeometry.h - Geometry (stored as Open Geospatial Consortium WKB)
3  -------------------------------------------------------------------
4 Date : 02 May 2005
5 Copyright : (C) 2005 by Brendan Morley
6 email : morb at ozemail dot com dot au
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 QGSGEOMETRY_H
17 #define QGSGEOMETRY_H
18 
19 #include <functional>
20 
21 #include <QDomDocument>
22 #include <QJsonObject>
23 #include <QSet>
24 #include <QString>
25 #include <QVector>
26 
27 #include <climits>
28 #include <limits>
29 #include <memory>
30 
31 #include "qgis_core.h"
32 #include "qgis_sip.h"
33 
34 #include "qgsabstractgeometry.h"
35 #include "qgspointxy.h"
36 #include "qgspoint.h"
37 #include "qgsfeatureid.h"
38 
39 #ifndef SIP_RUN
40 #include "json_fwd.hpp"
41 using namespace nlohmann;
42 #endif
43 
44 class QgsGeometryEngine;
45 class QgsVectorLayer;
46 class QgsMapToPixel;
47 class QPainter;
48 class QgsPolygon;
49 class QgsLineString;
50 class QgsCurve;
51 class QgsFeedback;
52 
62 typedef QVector<QgsPointXY> QgsPolylineXY;
63 
72 
74 #ifndef SIP_RUN
75 typedef QVector<QgsPolylineXY> QgsPolygonXY;
76 #else
77 typedef QVector<QVector<QgsPointXY>> QgsPolygonXY;
78 #endif
79 
81 typedef QVector<QgsPointXY> QgsMultiPointXY;
82 
84 #ifndef SIP_RUN
85 typedef QVector<QgsPolylineXY> QgsMultiPolylineXY;
86 #else
87 typedef QVector<QVector<QgsPointXY>> QgsMultiPolylineXY;
88 #endif
89 
91 #ifndef SIP_RUN
92 typedef QVector<QgsPolygonXY> QgsMultiPolygonXY;
93 #else
94 typedef QVector<QVector<QVector<QgsPointXY>>> QgsMultiPolygonXY;
95 #endif
96 
97 class QgsRectangle;
98 
99 class QgsConstWkbPtr;
100 
101 struct QgsGeometryPrivate;
102 
123 class CORE_EXPORT QgsGeometry
124 {
125  Q_GADGET
126  Q_PROPERTY( bool isNull READ isNull )
127  Q_PROPERTY( QgsWkbTypes::GeometryType type READ type )
128 
129  public:
130 
136  {
137  Success = 0,
138  NothingHappened = 1000,
145  /* Add part issues */
148  /* Add ring issues*/
153  /* Split features */
155  };
156  Q_ENUM( OperationResult )
157 
158 
160 
162  QgsGeometry( const QgsGeometry & );
163 
168  QgsGeometry &operator=( QgsGeometry const &rhs ) SIP_SKIP;
169 
175  explicit QgsGeometry( QgsAbstractGeometry *geom SIP_TRANSFER );
176 
182  explicit QgsGeometry( std::unique_ptr< QgsAbstractGeometry > geom ) SIP_SKIP;
183 
184  virtual ~QgsGeometry();
185 
197  const QgsAbstractGeometry *constGet() const SIP_HOLDGIL;
198 
211  QgsAbstractGeometry *get();
212 
225  void set( QgsAbstractGeometry *geometry SIP_TRANSFER ) SIP_DEPRECATED;
226 
234  bool isNull() const SIP_HOLDGIL;
235 
237  static QgsGeometry fromWkt( const QString &wkt );
239  static QgsGeometry fromPointXY( const QgsPointXY &point ) SIP_HOLDGIL;
241  static QgsGeometry fromMultiPointXY( const QgsMultiPointXY &multipoint );
242 
254  static QgsGeometry fromPolylineXY( const QgsPolylineXY &polyline );
255 
265  static QgsGeometry fromPolyline( const QgsPolyline &polyline );
266 
268  static QgsGeometry fromMultiPolylineXY( const QgsMultiPolylineXY &multiline );
270  static QgsGeometry fromPolygonXY( const QgsPolygonXY &polygon );
272  static QgsGeometry fromMultiPolygonXY( const QgsMultiPolygonXY &multipoly );
274  static QgsGeometry fromRect( const QgsRectangle &rect ) SIP_HOLDGIL;
276  static QgsGeometry collectGeometry( const QVector<QgsGeometry> &geometries );
277 
293  static QgsGeometry createWedgeBuffer( const QgsPoint &center, double azimuth, double angularWidth,
294  double outerRadius, double innerRadius = 0 );
295 
301  void fromWkb( unsigned char *wkb, int length ) SIP_SKIP;
302 
307  void fromWkb( const QByteArray &wkb );
308 
313  QgsWkbTypes::Type wkbType() const SIP_HOLDGIL;
314 
319  QgsWkbTypes::GeometryType type() const SIP_HOLDGIL;
320 
327  bool isEmpty() const;
328 
330  bool isMultipart() const SIP_HOLDGIL;
331 
346  bool equals( const QgsGeometry &geometry ) const;
347 
364  bool isGeosEqual( const QgsGeometry & ) const;
365 
368  {
369  FlagAllowSelfTouchingHoles = 1 << 0,
370  };
371  Q_DECLARE_FLAGS( ValidityFlags, ValidityFlag )
372 
373 
380  bool isGeosValid( QgsGeometry::ValidityFlags flags = QgsGeometry::ValidityFlags() ) const;
381 
390  bool isSimple() const;
391 
405  bool isAxisParallelRectangle( double maximumDeviation, bool simpleRectanglesOnly = false ) const;
406 
419  double area() const;
420 
433  double length() const;
434 
442  double distance( const QgsGeometry &geom ) const;
443 
444 #ifndef SIP_RUN
445 
446  // TODO QGIS 4: consider renaming vertices_begin, vertices_end, parts_begin, parts_end, etc
447  // to camelCase
448 
453  QgsAbstractGeometry::vertex_iterator vertices_begin() const;
454 
459  QgsAbstractGeometry::vertex_iterator vertices_end() const;
460 #endif
461 
485  QgsVertexIterator vertices() const;
486 
487 #ifndef SIP_RUN
488 
498 
508 
517  QgsAbstractGeometry::const_part_iterator const_parts_begin() const;
518 
527  QgsAbstractGeometry::const_part_iterator const_parts_end() const;
528 #endif
529 
567  QgsGeometryPartIterator parts();
568 
601  QgsGeometryConstPartIterator constParts() const;
602 
620  double hausdorffDistance( const QgsGeometry &geom ) const;
621 
640  double hausdorffDistanceDensify( const QgsGeometry &geom, double densifyFraction ) const;
641 
656  double frechetDistance( const QgsGeometry &geom ) const SIP_THROW( QgsNotSupportedException );
657 
680  double frechetDistanceDensify( const QgsGeometry &geom, double densifyFraction ) const SIP_THROW( QgsNotSupportedException );
681 
694  QgsPointXY closestVertex( const QgsPointXY &point, int &closestVertexIndex SIP_OUT, int &previousVertexIndex SIP_OUT, int &nextVertexIndex SIP_OUT, double &sqrDist SIP_OUT ) const;
695 
704  double distanceToVertex( int vertex ) const;
705 
713  double angleAtVertex( int vertex ) const;
714 
727  void adjacentVertices( int atVertex, int &beforeVertex SIP_OUT, int &afterVertex SIP_OUT ) const;
728 
741  bool insertVertex( double x, double y, int beforeVertex );
742 
755  bool insertVertex( const QgsPoint &point, int beforeVertex );
756 
764  bool moveVertex( double x, double y, int atVertex );
765 
773  bool moveVertex( const QgsPoint &p, int atVertex );
774 
786  bool deleteVertex( int atVertex );
787 
793  QgsPoint vertexAt( int atVertex ) const;
794 
800  double sqrDistToVertexAt( QgsPointXY &point SIP_IN, int atVertex ) const;
801 
807  QgsGeometry nearestPoint( const QgsGeometry &other ) const;
808 
819  QgsGeometry shortestLine( const QgsGeometry &other ) const;
820 
827  double closestVertexWithContext( const QgsPointXY &point, int &atVertex SIP_OUT ) const;
828 
840  double closestSegmentWithContext( const QgsPointXY &point, QgsPointXY &minDistPoint SIP_OUT, int &nextVertexIndex SIP_OUT, int *leftOrRightOfSegment SIP_OUT = nullptr, double epsilon = DEFAULT_SEGMENT_EPSILON ) const;
841 
847  OperationResult addRing( const QVector<QgsPointXY> &ring );
848 
854  OperationResult addRing( QgsCurve *ring SIP_TRANSFER );
855 
862  OperationResult addPart( const QVector<QgsPointXY> &points, QgsWkbTypes::GeometryType geomType = QgsWkbTypes::UnknownGeometry ) SIP_PYNAME( addPointsXY );
863 
870  OperationResult addPart( const QgsPointSequence &points, QgsWkbTypes::GeometryType geomType = QgsWkbTypes::UnknownGeometry ) SIP_PYNAME( addPoints );
871 
878  OperationResult addPart( QgsAbstractGeometry *part SIP_TRANSFER, QgsWkbTypes::GeometryType geomType = QgsWkbTypes::UnknownGeometry );
879 
885  OperationResult addPart( const QgsGeometry &newPart ) SIP_PYNAME( addPartGeometry );
886 
893  QgsGeometry removeInteriorRings( double minimumAllowedArea = -1 ) const;
894 
899  OperationResult translate( double dx, double dy, double dz = 0.0, double dm = 0.0 );
900 
915  OperationResult transform( const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection direction = QgsCoordinateTransform::ForwardTransform, bool transformZ = false ) SIP_THROW( QgsCsException );
916 
925  OperationResult transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 );
926 
933  OperationResult rotate( double rotation, const QgsPointXY &center );
934 
945  Q_DECL_DEPRECATED OperationResult splitGeometry( const QVector<QgsPointXY> &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QVector<QgsPointXY> &topologyTestPoints SIP_OUT, bool splitFeature = true ) SIP_DEPRECATED;
946 
969  OperationResult splitGeometry( const QgsPointSequence &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QgsPointSequence &topologyTestPoints SIP_OUT, bool splitFeature = true, bool skipIntersectionTest SIP_PYARGREMOVE = false );
970 
982  OperationResult splitGeometry( const QgsCurve *curve, QVector<QgsGeometry> &newGeometries SIP_OUT, bool preserveCircular, bool topological, QgsPointSequence &topologyTestPoints SIP_OUT, bool splitFeature = true );
983 
988  OperationResult reshapeGeometry( const QgsLineString &reshapeLineString );
989 
995  int makeDifferenceInPlace( const QgsGeometry &other ) SIP_SKIP;
996 
1004  QgsGeometry makeDifference( const QgsGeometry &other ) const;
1005 
1010  QgsRectangle boundingBox() const;
1011 
1023  QgsGeometry orientedMinimumBoundingBox( double &area SIP_OUT, double &angle SIP_OUT, double &width SIP_OUT, double &height SIP_OUT ) const;
1024 
1034  QgsGeometry orientedMinimumBoundingBox() const SIP_SKIP;
1035 
1044  QgsGeometry minimalEnclosingCircle( QgsPointXY &center SIP_OUT, double &radius SIP_OUT, unsigned int segments = 36 ) const;
1045 
1051  QgsGeometry minimalEnclosingCircle( unsigned int segments = 36 ) const SIP_SKIP;
1052 
1061  QgsGeometry orthogonalize( double tolerance = 1.0E-8, int maxIterations = 1000, double angleThreshold = 15.0 ) const;
1062 
1075  QgsGeometry snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const;
1076 
1097  bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false );
1098 
1108  bool intersects( const QgsRectangle &rectangle ) const;
1109 
1124  bool intersects( const QgsGeometry &geometry ) const;
1125 
1135  bool boundingBoxIntersects( const QgsRectangle &rectangle ) const;
1136 
1146  bool boundingBoxIntersects( const QgsGeometry &geometry ) const;
1147 
1151  bool contains( const QgsPointXY *p ) const;
1152 
1163  bool contains( const QgsGeometry &geometry ) const;
1164 
1175  bool disjoint( const QgsGeometry &geometry ) const;
1176 
1187  bool touches( const QgsGeometry &geometry ) const;
1188 
1199  bool overlaps( const QgsGeometry &geometry ) const;
1200 
1211  bool within( const QgsGeometry &geometry ) const;
1212 
1223  bool crosses( const QgsGeometry &geometry ) const;
1224 
1227  {
1228  SideLeft = 0,
1230  };
1231  Q_ENUM( BufferSide )
1232 
1233 
1235  {
1236  CapRound = 1,
1239  };
1240  Q_ENUM( EndCapStyle )
1241 
1242 
1244  {
1245  JoinStyleRound = 1,
1248  };
1249  Q_ENUM( JoinStyle )
1250 
1251 
1258  QgsGeometry buffer( double distance, int segments ) const;
1259 
1272  QgsGeometry buffer( double distance, int segments, EndCapStyle endCapStyle, JoinStyle joinStyle, double miterLimit ) const;
1273 
1282  QgsGeometry offsetCurve( double distance, int segments, JoinStyle joinStyle, double miterLimit ) const;
1283 
1299  QgsGeometry singleSidedBuffer( double distance, int segments, BufferSide side,
1300  JoinStyle joinStyle = JoinStyleRound,
1301  double miterLimit = 2.0 ) const;
1302 
1320  QgsGeometry taperedBuffer( double startWidth, double endWidth, int segments ) const;
1321 
1336  QgsGeometry variableWidthBufferByM( int segments ) const;
1337 
1344  QgsGeometry extendLine( double startDistance, double endDistance ) const;
1345 
1347  QgsGeometry simplify( double tolerance ) const;
1348 
1358  QgsGeometry densifyByCount( int extraNodesPerSegment ) const;
1359 
1374  QgsGeometry densifyByDistance( double distance ) const;
1375 
1391  QgsGeometry convertToCurves( double distanceTolerance = 1e-8, double angleTolerance = 1e-8 ) const;
1392 
1406  QgsGeometry centroid() const;
1407 
1421  QgsGeometry pointOnSurface() const;
1422 
1435  QgsGeometry poleOfInaccessibility( double precision, double *distanceToBoundary SIP_OUT = nullptr ) const;
1436 
1460  QgsGeometry largestEmptyCircle( double tolerance, const QgsGeometry &boundary = QgsGeometry() ) const SIP_THROW( QgsNotSupportedException );
1461 
1476  QgsGeometry minimumWidth() const SIP_THROW( QgsNotSupportedException );
1477 
1499  double minimumClearance() const SIP_THROW( QgsNotSupportedException );
1500 
1512  QgsGeometry minimumClearanceLine() const SIP_THROW( QgsNotSupportedException );
1513 
1522  QgsGeometry convexHull() const;
1523 
1539  QgsGeometry voronoiDiagram( const QgsGeometry &extent = QgsGeometry(), double tolerance = 0.0, bool edgesOnly = false ) const;
1540 
1550  QgsGeometry delaunayTriangulation( double tolerance = 0.0, bool edgesOnly = false ) const;
1551 
1562  QgsGeometry node() const;
1563 
1578  QgsGeometry sharedPaths( const QgsGeometry &other ) const;
1579 
1599  QgsGeometry subdivide( int maxNodes = 256 ) const;
1600 
1616  QgsGeometry interpolate( double distance ) const;
1617 
1629  double lineLocatePoint( const QgsGeometry &point ) const;
1630 
1640  double interpolateAngle( double distance ) const;
1641 
1650  QgsGeometry intersection( const QgsGeometry &geometry ) const;
1651 
1659  QgsGeometry clipped( const QgsRectangle &rectangle );
1660 
1672  QgsGeometry combine( const QgsGeometry &geometry ) const;
1673 
1682  QgsGeometry mergeLines() const;
1683 
1692  QgsGeometry difference( const QgsGeometry &geometry ) const;
1693 
1702  QgsGeometry symDifference( const QgsGeometry &geometry ) const;
1703 
1705  QgsGeometry extrude( double x, double y );
1706 
1707 #ifndef SIP_RUN
1708 
1730  QVector< QgsPointXY > randomPointsInPolygon( int count, const std::function< bool( const QgsPointXY & ) > &acceptPoint, unsigned long seed = 0, QgsFeedback *feedback = nullptr, int maxTriesPerPoint = 0 ) const;
1731 
1745  QVector< QgsPointXY > randomPointsInPolygon( int count, unsigned long seed = 0, QgsFeedback *feedback = nullptr ) const;
1747 #else
1748 
1762  SIP_PYOBJECT randomPointsInPolygon( int count, unsigned long seed = 0 ) const SIP_TYPEHINT( QgsPolylineXY );
1763  % MethodCode
1764  const QgsWkbTypes::GeometryType type = sipCpp->type();
1765  if ( sipCpp->isNull() )
1766  {
1767  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Cannot generate points inside a null geometry." ).toUtf8().constData() );
1768  sipIsErr = 1;
1769  }
1770  else if ( type != QgsWkbTypes::PolygonGeometry )
1771  {
1772  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Cannot generate points inside a %1 geometry. Only Polygon types are permitted." ).arg( QgsWkbTypes::displayString( sipCpp->wkbType() ) ).toUtf8().constData() );
1773  sipIsErr = 1;
1774  }
1775  else
1776  {
1777  const sipTypeDef *qvector_type = sipFindType( "QVector<QgsPointXY>" );
1778  sipRes = sipConvertFromNewType( new QVector< QgsPointXY >( sipCpp->randomPointsInPolygon( a0, a1 ) ), qvector_type, Py_None );
1779  }
1780  % End
1781 
1782 
1783 #endif
1785 
1793  int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const;
1794 
1802  QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const;
1803 
1809  QString asWkt( int precision = 17 ) const;
1810 
1811 #ifdef SIP_RUN
1812  SIP_PYOBJECT __repr__();
1813  % MethodCode
1814  QString str;
1815  if ( sipCpp->isNull() )
1816  str = QStringLiteral( "<QgsGeometry: null>" );
1817  else
1818  {
1819  QString wkt = sipCpp->asWkt();
1820  if ( wkt.length() > 1000 )
1821  wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
1822  str = QStringLiteral( "<QgsGeometry: %1>" ).arg( wkt );
1823  }
1824  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
1825  % End
1826 #endif
1827 
1831  QString asJson( int precision = 17 ) const;
1832 
1838  virtual json asJsonObject( int precision = 17 ) const SIP_SKIP;
1839 
1862  QVector< QgsGeometry > coerceToType( QgsWkbTypes::Type type ) const;
1863 
1876  QgsGeometry convertToType( QgsWkbTypes::GeometryType destType, bool destMultipart = false ) const;
1877 
1878  /* Accessor functions for getting geometry data */
1879 
1880 #ifndef SIP_RUN
1881 
1889  QgsPointXY asPoint() const;
1890 #else
1891 
1902  SIP_PYOBJECT asPoint() const SIP_TYPEHINT( QgsPointXY );
1903  % MethodCode
1904  const QgsWkbTypes::Type type = sipCpp->wkbType();
1905  if ( sipCpp->isNull() )
1906  {
1907  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a point." ).toUtf8().constData() );
1908  sipIsErr = 1;
1909  }
1910  else if ( QgsWkbTypes::flatType( type ) != QgsWkbTypes::Point )
1911  {
1912  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1913  sipIsErr = 1;
1914  }
1915  else
1916  {
1917  sipRes = sipConvertFromNewType( new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
1918  }
1919  % End
1920 #endif
1921 
1922 #ifndef SIP_RUN
1923 
1932  QgsPolylineXY asPolyline() const;
1933 #else
1934 
1946  SIP_PYOBJECT asPolyline() const SIP_TYPEHINT( QgsPolylineXY );
1947  % MethodCode
1948  const QgsWkbTypes::Type type = sipCpp->wkbType();
1949  if ( sipCpp->isNull() )
1950  {
1951  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a polyline." ).toUtf8().constData() );
1952  sipIsErr = 1;
1953  }
1955  {
1956  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a polyline. Only single line or curve types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1957  sipIsErr = 1;
1958  }
1959  else
1960  {
1961  const sipTypeDef *qvector_type = sipFindType( "QVector< QgsPointXY >" );
1962  sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asPolyline() ), qvector_type, Py_None );
1963  }
1964  % End
1965 #endif
1966 
1967 #ifndef SIP_RUN
1968 
1977  QgsPolygonXY asPolygon() const;
1978 #else
1979 
1991  SIP_PYOBJECT asPolygon() const SIP_TYPEHINT( QgsPolygonXY );
1992  % MethodCode
1993  const QgsWkbTypes::Type type = sipCpp->wkbType();
1994  if ( sipCpp->isNull() )
1995  {
1996  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a polygon." ).toUtf8().constData() );
1997  sipIsErr = 1;
1998  }
2000  {
2001  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a polygon. Only single polygon or curve polygon types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
2002  sipIsErr = 1;
2003  }
2004  else
2005  {
2006  const sipTypeDef *qvector_type = sipFindType( "QVector<QVector<QgsPointXY>>" );
2007  sipRes = sipConvertFromNewType( new QgsPolygonXY( sipCpp->asPolygon() ), qvector_type, Py_None );
2008  }
2009  % End
2010 #endif
2011 
2012 #ifndef SIP_RUN
2013 
2021  QgsMultiPointXY asMultiPoint() const;
2022 #else
2023 
2034  SIP_PYOBJECT asMultiPoint() const SIP_TYPEHINT( QgsMultiPointXY );
2035  % MethodCode
2036  const QgsWkbTypes::Type type = sipCpp->wkbType();
2037  if ( sipCpp->isNull() )
2038  {
2039  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multipoint." ).toUtf8().constData() );
2040  sipIsErr = 1;
2041  }
2043  {
2044  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a multipoint. Only multipoint types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
2045  sipIsErr = 1;
2046  }
2047  else
2048  {
2049  const sipTypeDef *qvector_type = sipFindType( "QVector< QgsPointXY >" );
2050  sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asMultiPoint() ), qvector_type, Py_None );
2051  }
2052  % End
2053 #endif
2054 
2055 #ifndef SIP_RUN
2056 
2065  QgsMultiPolylineXY asMultiPolyline() const;
2066 #else
2067 
2079  SIP_PYOBJECT asMultiPolyline() const SIP_TYPEHINT( QgsMultiPolylineXY );
2080  % MethodCode
2081  const QgsWkbTypes::Type type = sipCpp->wkbType();
2082  if ( sipCpp->isNull() )
2083  {
2084  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multilinestring." ).toUtf8().constData() );
2085  sipIsErr = 1;
2086  }
2088  {
2089  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a multilinestring. Only multi linestring or curves are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
2090  sipIsErr = 1;
2091  }
2092  else
2093  {
2094  const sipTypeDef *qvector_type = sipFindType( "QVector<QVector<QgsPointXY>>" );
2095  sipRes = sipConvertFromNewType( new QgsMultiPolylineXY( sipCpp->asMultiPolyline() ), qvector_type, Py_None );
2096  }
2097  % End
2098 #endif
2099 
2100 #ifndef SIP_RUN
2101 
2110  QgsMultiPolygonXY asMultiPolygon() const;
2111 #else
2112 
2124  SIP_PYOBJECT asMultiPolygon() const SIP_TYPEHINT( QgsMultiPolygonXY );
2125  % MethodCode
2126  const QgsWkbTypes::Type type = sipCpp->wkbType();
2127  if ( sipCpp->isNull() )
2128  {
2129  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multipolygon." ).toUtf8().constData() );
2130  sipIsErr = 1;
2131  }
2133  {
2134  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a multipolygon. Only multi polygon or curves are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
2135  sipIsErr = 1;
2136  }
2137  else
2138  {
2139  const sipTypeDef *qvector_type = sipFindType( "QVector<QVector<QVector<QgsPointXY>>>" );
2140  sipRes = sipConvertFromNewType( new QgsMultiPolygonXY( sipCpp->asMultiPolygon() ), qvector_type, Py_None );
2141  }
2142  % End
2143 #endif
2144 
2149  QVector<QgsGeometry> asGeometryCollection() const;
2150 
2156  QPointF asQPointF() const SIP_HOLDGIL;
2157 
2170  QPolygonF asQPolygonF() const SIP_HOLDGIL;
2171 
2178  bool deleteRing( int ringNum, int partNum = 0 );
2179 
2185  bool deletePart( int partNum );
2186 
2195  bool convertToMultiType();
2196 
2206  bool convertToSingleType();
2207 
2217  bool convertGeometryCollectionToSubclass( QgsWkbTypes::GeometryType geomType );
2218 
2229  int avoidIntersections( const QList<QgsVectorLayer *> &avoidIntersectionsLayers,
2230  const QHash<QgsVectorLayer *, QSet<QgsFeatureId> > &ignoreFeatures SIP_PYARGREMOVE = ( QHash<QgsVectorLayer *, QSet<QgsFeatureId> >() ) );
2231 
2252  QgsGeometry makeValid() const;
2253 
2261  QgsGeometry forceRHR() const;
2262 
2267  class CORE_EXPORT Error
2268  {
2269  public:
2271  : mMessage( QStringLiteral( "none" ) )
2272  {}
2273 
2274  explicit Error( const QString &m )
2275  : mMessage( m )
2276  {}
2277 
2278  Error( const QString &m, const QgsPointXY &p )
2279  : mMessage( m )
2280  , mLocation( p )
2281  , mHasLocation( true ) {}
2282 
2286  QString what() const;
2287 
2291  QgsPointXY where() const;
2292 
2296  bool hasWhere() const;
2297 
2298 #ifdef SIP_RUN
2299  SIP_PYOBJECT __repr__();
2300  % MethodCode
2301  QString str = QStringLiteral( "<QgsGeometry.Error: %1>" ).arg( sipCpp->what() );
2302  sipRes = PyUnicode_FromString( str.toUtf8().data() );
2303  % End
2304 #endif
2305 
2306  bool operator==( const QgsGeometry::Error &other ) const
2307  {
2308  return other.mMessage == mMessage && other.mHasLocation == mHasLocation && other.mLocation == mLocation;
2309  }
2310 
2311  private:
2312  QString mMessage;
2313  QgsPointXY mLocation;
2314  bool mHasLocation = false;
2315  };
2316 
2322  {
2325  };
2326 
2335  void validateGeometry( QVector<QgsGeometry::Error> &errors SIP_OUT, ValidationMethod method = ValidatorQgisInternal, QgsGeometry::ValidityFlags flags = QgsGeometry::ValidityFlags() ) const;
2336 
2346  void normalize();
2347 
2353  static QgsGeometry unaryUnion( const QVector<QgsGeometry> &geometries );
2354 
2363  static QgsGeometry polygonize( const QVector<QgsGeometry> &geometries );
2364 
2372  void convertToStraightSegment( double tolerance = M_PI / 180., QgsAbstractGeometry::SegmentationToleranceType toleranceType = QgsAbstractGeometry::MaximumAngle );
2373 
2380  bool requiresConversionToStraightSegments() const;
2381 
2387  void mapToPixel( const QgsMapToPixel &mtp );
2388 
2394  void draw( QPainter &p ) const;
2395 
2406  bool vertexIdFromVertexNr( int number, QgsVertexId &id SIP_OUT ) const;
2407 
2419  int vertexNrFromVertexId( QgsVertexId id ) const;
2420 
2428  QString lastError() const SIP_HOLDGIL;
2429 
2439  void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) SIP_SKIP;
2440 
2455  void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) SIP_SKIP;
2456 
2462  static QgsGeometry fromQPointF( QPointF point ) SIP_HOLDGIL;
2463 
2471  static QgsGeometry fromQPolygonF( const QPolygonF &polygon );
2472 
2480  Q_DECL_DEPRECATED static QgsPolylineXY createPolylineFromQPolygonF( const QPolygonF &polygon ) SIP_DEPRECATED;
2481 
2489  Q_DECL_DEPRECATED static QgsPolygonXY createPolygonFromQPolygonF( const QPolygonF &polygon ) SIP_DEPRECATED;
2490 
2491 #ifndef SIP_RUN
2492 
2502  static bool compare( const QgsPolylineXY &p1, const QgsPolylineXY &p2,
2503  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2504 
2514  static bool compare( const QgsPolygonXY &p1, const QgsPolygonXY &p2,
2515  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2516 
2527  static bool compare( const QgsMultiPolygonXY &p1, const QgsMultiPolygonXY &p2,
2528  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2529 #else
2530 
2550  static bool compare( PyObject *obj1, PyObject *obj2, double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2551  % MethodCode
2552  {
2553  sipRes = false;
2554  int state0;
2555  int state1;
2556  int sipIsErr = 0;
2557 
2558  if ( PyList_Check( a0 ) && PyList_Check( a1 ) &&
2559  PyList_GET_SIZE( a0 ) && PyList_GET_SIZE( a1 ) )
2560  {
2561  PyObject *o0 = PyList_GetItem( a0, 0 );
2562  PyObject *o1 = PyList_GetItem( a1, 0 );
2563  if ( o0 && o1 )
2564  {
2565  // compare polyline - polyline
2566  if ( sipCanConvertToType( o0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2567  sipCanConvertToType( o1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2568  sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2569  sipCanConvertToType( a1, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2570  {
2571  QgsPolylineXY *p0;
2572  QgsPolylineXY *p1;
2573  p0 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2574  p1 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a1, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2575  if ( sipIsErr )
2576  {
2577  sipReleaseType( p0, sipType_QVector_0100QgsPointXY, state0 );
2578  sipReleaseType( p1, sipType_QVector_0100QgsPointXY, state1 );
2579  }
2580  else
2581  {
2582  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2583  }
2584  }
2585  else if ( PyList_Check( o0 ) && PyList_Check( o1 ) &&
2586  PyList_GET_SIZE( o0 ) && PyList_GET_SIZE( o1 ) )
2587  {
2588  PyObject *oo0 = PyList_GetItem( o0, 0 );
2589  PyObject *oo1 = PyList_GetItem( o1, 0 );
2590  if ( oo0 && oo1 )
2591  {
2592  // compare polygon - polygon
2593  if ( sipCanConvertToType( oo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2594  sipCanConvertToType( oo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2595  sipCanConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2596  sipCanConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2597  {
2598  QgsPolygonXY *p0;
2599  QgsPolygonXY *p1;
2600  p0 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2601  p1 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2602  if ( sipIsErr )
2603  {
2604  sipReleaseType( p0, sipType_QVector_0600QVector_0100QgsPointXY, state0 );
2605  sipReleaseType( p1, sipType_QVector_0600QVector_0100QgsPointXY, state1 );
2606  }
2607  else
2608  {
2609  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2610  }
2611  }
2612  else if ( PyList_Check( oo0 ) && PyList_Check( oo1 ) &&
2613  PyList_GET_SIZE( oo0 ) && PyList_GET_SIZE( oo1 ) )
2614  {
2615  PyObject *ooo0 = PyList_GetItem( oo0, 0 );
2616  PyObject *ooo1 = PyList_GetItem( oo1, 0 );
2617  if ( ooo0 && ooo1 )
2618  {
2619  // compare multipolygon - multipolygon
2620  if ( sipCanConvertToType( ooo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2621  sipCanConvertToType( ooo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2622  sipCanConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2623  sipCanConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2624  {
2625  QgsMultiPolygonXY *p0;
2626  QgsMultiPolygonXY *p1;
2627  p0 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2628  p1 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2629  if ( sipIsErr )
2630  {
2631  sipReleaseType( p0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state0 );
2632  sipReleaseType( p1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state1 );
2633  }
2634  else
2635  {
2636  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2637  }
2638  }
2639  }
2640  }
2641  }
2642  }
2643  }
2644  }
2645  }
2646  % End
2647 #endif
2648 
2665  QgsGeometry smooth( unsigned int iterations = 1, double offset = 0.25,
2666  double minimumDistance = -1.0, double maxAngle = 180.0 ) const;
2667 
2705  static QgsGeometryEngine *createGeometryEngine( const QgsAbstractGeometry *geometry ) SIP_FACTORY;
2706 
2712  static void convertPointList( const QVector<QgsPointXY> &input, QgsPointSequence &output );
2713 
2719  static void convertPointList( const QgsPointSequence &input, QVector<QgsPointXY> &output );
2720 
2722  operator QVariant() const
2723  {
2724  return QVariant::fromValue( *this );
2725  }
2726 
2727  private:
2728 
2729  QgsGeometryPrivate *d; //implicitly shared data pointer
2730 
2732  mutable QString mLastError;
2733 
2738  void detach();
2739 
2744  void reset( std::unique_ptr< QgsAbstractGeometry > newGeometry );
2745 
2746  static void convertPolygon( const QgsPolygon &input, QgsPolygonXY &output );
2747 
2749  QgsGeometry convertToPoint( bool destMultipart ) const;
2751  QgsGeometry convertToLine( bool destMultipart ) const;
2753  QgsGeometry convertToPolygon( bool destMultipart ) const;
2754 
2766  std::unique_ptr< QgsLineString > smoothLine( const QgsLineString &line, unsigned int iterations = 1, double offset = 0.25,
2767  double minimumDistance = -1, double maxAngle = 180.0 ) const;
2768 
2780  std::unique_ptr< QgsPolygon > smoothPolygon( const QgsPolygon &polygon, unsigned int iterations = 1, double offset = 0.25,
2781  double minimumDistance = -1, double maxAngle = 180.0 ) const;
2782 
2783 
2785 
2786 }; // class QgsGeometry
2787 
2789 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsGeometry::ValidityFlags )
2790 
2791 CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsGeometry &geometry );
2794 CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsGeometry &geometry );
2795 
2796 #endif
The part_iterator class provides STL-style iterator for const references to geometry parts.
The part_iterator class provides STL-style iterator for geometry parts.
The vertex_iterator class provides STL-style iterator for vertices.
Abstract base class for all geometries.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
@ MaximumAngle
Maximum angle between generating radii (lines from arc center to output vertices)
A const WKB pointer.
Definition: qgswkbptr.h:138
Class for doing transforms between two map coordinate systems.
TransformDirection
Enum used to indicate the direction (forward or inverse) of the transform.
@ ForwardTransform
Transform from source to destination CRS.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
Abstract base class for curved geometry type.
Definition: qgscurve.h:36
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
Java-style iterator for const traversal of parts of a geometry.
A geometry engine is a low-level representation of a QgsAbstractGeometry object, optimised for use wi...
Java-style iterator for traversal of parts of a geometry.
A geometry error.
Definition: qgsgeometry.h:2268
Error(const QString &m)
Definition: qgsgeometry.h:2274
Error(const QString &m, const QgsPointXY &p)
Definition: qgsgeometry.h:2278
bool operator==(const QgsGeometry::Error &other) const
Definition: qgsgeometry.h:2306
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QVector< QgsPointXY > randomPointsInPolygon(int count, const std::function< bool(const QgsPointXY &) > &acceptPoint, unsigned long seed=0, QgsFeedback *feedback=nullptr, int maxTriesPerPoint=0) const
Returns a list of count random points generated inside a (multi)polygon geometry (if acceptPoint is s...
JoinStyle
Join styles for buffers.
Definition: qgsgeometry.h:1244
@ JoinStyleMiter
Use mitered joins.
Definition: qgsgeometry.h:1246
@ JoinStyleBevel
Use beveled joins.
Definition: qgsgeometry.h:1247
QVector< QgsPointXY > randomPointsInPolygon(int count, unsigned long seed=0, QgsFeedback *feedback=nullptr) const
Returns a list of count random points generated inside a (multi)polygon geometry.
static bool compare(const QgsPolylineXY &p1, const QgsPolylineXY &p2, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compares two polylines for equality within a specified tolerance.
BufferSide
Side of line to buffer.
Definition: qgsgeometry.h:1227
@ SideRight
Buffer to right of line.
Definition: qgsgeometry.h:1229
EndCapStyle
End cap styles for buffers.
Definition: qgsgeometry.h:1235
@ CapSquare
Square cap (extends past start/end of line by buffer distance)
Definition: qgsgeometry.h:1238
@ CapFlat
Flat cap (in line with start/end of line)
Definition: qgsgeometry.h:1237
OperationResult
Success or failure of a geometry operation.
Definition: qgsgeometry.h:136
@ InvalidBaseGeometry
The base geometry on which the operation is done is invalid or empty.
Definition: qgsgeometry.h:139
@ SplitCannotSplitPoint
Cannot split points.
Definition: qgsgeometry.h:154
@ AddRingNotInExistingFeature
The input ring doesn't have any existing ring to fit into.
Definition: qgsgeometry.h:152
@ AddRingNotClosed
The input ring is not closed.
Definition: qgsgeometry.h:149
@ AddPartSelectedGeometryNotFound
The selected geometry cannot be found.
Definition: qgsgeometry.h:146
@ GeometryEngineError
Geometry engine misses a method implemented or an error occurred in the geometry engine.
Definition: qgsgeometry.h:143
@ AddPartNotMultiGeometry
The source geometry is not multi.
Definition: qgsgeometry.h:147
@ InvalidInputGeometryType
The input geometry (ring, part, split line, etc.) has not the correct geometry type.
Definition: qgsgeometry.h:140
@ SelectionIsEmpty
No features were selected.
Definition: qgsgeometry.h:141
@ AddRingCrossesExistingRings
The input ring crosses existing rings (it is not disjoint)
Definition: qgsgeometry.h:151
@ SelectionIsGreaterThanOne
More than one features were selected.
Definition: qgsgeometry.h:142
@ LayerNotEditable
Cannot edit layer.
Definition: qgsgeometry.h:144
@ AddRingNotValid
The input ring is not valid.
Definition: qgsgeometry.h:150
ValidityFlag
Validity check flags.
Definition: qgsgeometry.h:368
ValidationMethod
Available methods for validating geometries.
Definition: qgsgeometry.h:2322
@ ValidatorQgisInternal
Use internal QgsGeometryValidator method.
Definition: qgsgeometry.h:2323
@ ValidatorGeos
Use GEOS validation methods.
Definition: qgsgeometry.h:2324
This class offers geometry processing methods.
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:44
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:39
Custom exception class which is raised when an operation is not supported.
Definition: qgsexception.h:118
A class to represent a 2D point.
Definition: qgspointxy.h:59
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
Polygon geometry type.
Definition: qgspolygon.h:34
A rectangle specified with double values.
Definition: qgsrectangle.h:42
Represents a vector layer which manages a vector based data sets.
Java-style iterator for traversal of vertices of a geometry.
Handles storage of information regarding WKB types and their properties.
Definition: qgswkbtypes.h:42
static GeometryType geometryType(Type type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:938
static bool isMultiType(Type type) SIP_HOLDGIL
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:832
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:141
static QString displayString(Type type) SIP_HOLDGIL
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:702
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp:786
std::unique_ptr< GEOSGeometry, GeosDeleter > unique_ptr
Scoped GEOS pointer.
Definition: qgsgeos.h:79
#define str(x)
Definition: qgis.cpp:37
const double DEFAULT_SEGMENT_EPSILON
Default snapping tolerance for segments.
Definition: qgis.h:1039
#define SIP_THROW(name)
Definition: qgis_sip.h:189
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:218
#define SIP_IN
Definition: qgis_sip.h:63
#define SIP_DEPRECATED
Definition: qgis_sip.h:106
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_PYNAME(name)
Definition: qgis_sip.h:81
#define SIP_PYARGREMOVE
Definition: qgis_sip.h:146
#define SIP_TRANSFER
Definition: qgis_sip.h:36
#define SIP_OUT
Definition: qgis_sip.h:58
#define SIP_HOLDGIL
Definition: qgis_sip.h:157
#define SIP_FACTORY
Definition: qgis_sip.h:76
QVector< QgsPoint > QgsPointSequence
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Definition: qgsfeatureid.h:28
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsField::ConfigurationFlags) CORE_EXPORT QDataStream &operator<<(QDataStream &out
Writes the field to stream out. QGIS version compatibility is not guaranteed.
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item.
Definition: qgsgeometry.h:75
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
Definition: qgsgeometry.h:85
CORE_EXPORT QDataStream & operator>>(QDataStream &in, QgsGeometry &geometry)
Reads a geometry from stream in into geometry. QGIS version compatibility is not guaranteed.
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
Definition: qgsgeometry.h:81
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
Definition: qgsgeometry.h:51
CORE_EXPORT QDataStream & operator<<(QDataStream &out, const QgsGeometry &geometry)
Writes the geometry to stream out. QGIS version compatibility is not guaranteed.
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
Definition: qgsgeometry.h:92
QgsPointSequence QgsPolyline
Polyline as represented as a vector of points.
Definition: qgsgeometry.h:71
Q_DECLARE_METATYPE(QgsMeshTimeSettings)
int precision
Utility class for identifying a unique vertex within a geometry.