QGIS API Documentation  3.15.0-Master (ecc6bfcd7a)
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;
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 
404  double area() const;
405 
418  double length() const;
419 
427  double distance( const QgsGeometry &geom ) const;
428 
429 #ifndef SIP_RUN
430 
431  // TODO QGIS 4: consider renaming vertices_begin, vertices_end, parts_begin, parts_end, etc
432  // to camelCase
433 
438  QgsAbstractGeometry::vertex_iterator vertices_begin() const;
439 
444  QgsAbstractGeometry::vertex_iterator vertices_end() const;
445 #endif
446 
470  QgsVertexIterator vertices() const;
471 
472 #ifndef SIP_RUN
473 
483 
493 
502  QgsAbstractGeometry::const_part_iterator const_parts_begin() const;
503 
512  QgsAbstractGeometry::const_part_iterator const_parts_end() const;
513 #endif
514 
552  QgsGeometryPartIterator parts();
553 
586  QgsGeometryConstPartIterator constParts() const;
587 
605  double hausdorffDistance( const QgsGeometry &geom ) const;
606 
625  double hausdorffDistanceDensify( const QgsGeometry &geom, double densifyFraction ) const;
626 
627  //TODO QGIS 4.0 - rename beforeVertex to previousVertex, afterVertex to nextVertex
628 
641  QgsPointXY closestVertex( const QgsPointXY &point, int &atVertex SIP_OUT, int &beforeVertex SIP_OUT, int &afterVertex SIP_OUT, double &sqrDist SIP_OUT ) const;
642 
651  double distanceToVertex( int vertex ) const;
652 
660  double angleAtVertex( int vertex ) const;
661 
674  void adjacentVertices( int atVertex, int &beforeVertex SIP_OUT, int &afterVertex SIP_OUT ) const;
675 
688  bool insertVertex( double x, double y, int beforeVertex );
689 
702  bool insertVertex( const QgsPoint &point, int beforeVertex );
703 
711  bool moveVertex( double x, double y, int atVertex );
712 
720  bool moveVertex( const QgsPoint &p, int atVertex );
721 
733  bool deleteVertex( int atVertex );
734 
740  QgsPoint vertexAt( int atVertex ) const;
741 
747  double sqrDistToVertexAt( QgsPointXY &point SIP_IN, int atVertex ) const;
748 
754  QgsGeometry nearestPoint( const QgsGeometry &other ) const;
755 
766  QgsGeometry shortestLine( const QgsGeometry &other ) const;
767 
774  double closestVertexWithContext( const QgsPointXY &point, int &atVertex SIP_OUT ) const;
775 
787  double closestSegmentWithContext( const QgsPointXY &point, QgsPointXY &minDistPoint SIP_OUT, int &afterVertex SIP_OUT, int *leftOf SIP_OUT = nullptr, double epsilon = DEFAULT_SEGMENT_EPSILON ) const;
788 
794  OperationResult addRing( const QVector<QgsPointXY> &ring );
795 
801  OperationResult addRing( QgsCurve *ring SIP_TRANSFER );
802 
809  OperationResult addPart( const QVector<QgsPointXY> &points, QgsWkbTypes::GeometryType geomType = QgsWkbTypes::UnknownGeometry ) SIP_PYNAME( addPointsXY );
810 
818 
826 
832  OperationResult addPart( const QgsGeometry &newPart ) SIP_PYNAME( addPartGeometry );
833 
840  QgsGeometry removeInteriorRings( double minimumAllowedArea = -1 ) const;
841 
846  OperationResult translate( double dx, double dy, double dz = 0.0, double dm = 0.0 );
847 
863 
872  OperationResult transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 );
873 
880  OperationResult rotate( double rotation, const QgsPointXY &center );
881 
892  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;
893 
915  OperationResult splitGeometry( const QgsPointSequence &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QgsPointSequence &topologyTestPoints SIP_OUT, bool splitFeature = true, bool skipIntersectionTest SIP_PYARGREMOVE = false );
916 
928  OperationResult splitGeometry( const QgsCurve *curve, QVector<QgsGeometry> &newGeometries SIP_OUT, bool preserveCircular, bool topological, QgsPointSequence &topologyTestPoints SIP_OUT, bool splitFeature = true );
929 
934  OperationResult reshapeGeometry( const QgsLineString &reshapeLineString );
935 
941  int makeDifferenceInPlace( const QgsGeometry &other ) SIP_SKIP;
942 
950  QgsGeometry makeDifference( const QgsGeometry &other ) const;
951 
956  QgsRectangle boundingBox() const;
957 
969  QgsGeometry orientedMinimumBoundingBox( double &area SIP_OUT, double &angle SIP_OUT, double &width SIP_OUT, double &height SIP_OUT ) const;
970 
980  QgsGeometry orientedMinimumBoundingBox() const SIP_SKIP;
981 
990  QgsGeometry minimalEnclosingCircle( QgsPointXY &center SIP_OUT, double &radius SIP_OUT, unsigned int segments = 36 ) const;
991 
997  QgsGeometry minimalEnclosingCircle( unsigned int segments = 36 ) const SIP_SKIP;
998 
1007  QgsGeometry orthogonalize( double tolerance = 1.0E-8, int maxIterations = 1000, double angleThreshold = 15.0 ) const;
1008 
1021  QgsGeometry snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const;
1022 
1043  bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false );
1044 
1054  bool intersects( const QgsRectangle &rectangle ) const;
1055 
1065  bool intersects( const QgsGeometry &geometry ) const;
1066 
1076  bool boundingBoxIntersects( const QgsRectangle &rectangle ) const;
1077 
1087  bool boundingBoxIntersects( const QgsGeometry &geometry ) const;
1088 
1092  bool contains( const QgsPointXY *p ) const;
1093 
1098  bool contains( const QgsGeometry &geometry ) const;
1099 
1104  bool disjoint( const QgsGeometry &geometry ) const;
1105 
1110  bool touches( const QgsGeometry &geometry ) const;
1111 
1116  bool overlaps( const QgsGeometry &geometry ) const;
1117 
1122  bool within( const QgsGeometry &geometry ) const;
1123 
1124 
1129  bool crosses( const QgsGeometry &geometry ) const;
1130 
1133  {
1134  SideLeft = 0,
1136  };
1137  Q_ENUM( BufferSide )
1138 
1139 
1141  {
1142  CapRound = 1,
1145  };
1146  Q_ENUM( EndCapStyle )
1147 
1148 
1150  {
1151  JoinStyleRound = 1,
1154  };
1155  Q_ENUM( JoinStyle )
1156 
1157 
1164  QgsGeometry buffer( double distance, int segments ) const;
1165 
1178  QgsGeometry buffer( double distance, int segments, EndCapStyle endCapStyle, JoinStyle joinStyle, double miterLimit ) const;
1179 
1188  QgsGeometry offsetCurve( double distance, int segments, JoinStyle joinStyle, double miterLimit ) const;
1189 
1205  QgsGeometry singleSidedBuffer( double distance, int segments, BufferSide side,
1206  JoinStyle joinStyle = JoinStyleRound,
1207  double miterLimit = 2.0 ) const;
1208 
1226  QgsGeometry taperedBuffer( double startWidth, double endWidth, int segments ) const;
1227 
1242  QgsGeometry variableWidthBufferByM( int segments ) const;
1243 
1250  QgsGeometry extendLine( double startDistance, double endDistance ) const;
1251 
1253  QgsGeometry simplify( double tolerance ) const;
1254 
1264  QgsGeometry densifyByCount( int extraNodesPerSegment ) const;
1265 
1280  QgsGeometry densifyByDistance( double distance ) const;
1281 
1297  QgsGeometry convertToCurves( double distanceTolerance = 1e-8, double angleTolerance = 1e-8 ) const;
1298 
1312  QgsGeometry centroid() const;
1313 
1327  QgsGeometry pointOnSurface() const;
1328 
1341  QgsGeometry poleOfInaccessibility( double precision, double *distanceToBoundary SIP_OUT = nullptr ) const;
1342 
1351  QgsGeometry convexHull() const;
1352 
1368  QgsGeometry voronoiDiagram( const QgsGeometry &extent = QgsGeometry(), double tolerance = 0.0, bool edgesOnly = false ) const;
1369 
1379  QgsGeometry delaunayTriangulation( double tolerance = 0.0, bool edgesOnly = false ) const;
1380 
1400  QgsGeometry subdivide( int maxNodes = 256 ) const;
1401 
1417  QgsGeometry interpolate( double distance ) const;
1418 
1430  double lineLocatePoint( const QgsGeometry &point ) const;
1431 
1441  double interpolateAngle( double distance ) const;
1442 
1451  QgsGeometry intersection( const QgsGeometry &geometry ) const;
1452 
1460  QgsGeometry clipped( const QgsRectangle &rectangle );
1461 
1473  QgsGeometry combine( const QgsGeometry &geometry ) const;
1474 
1483  QgsGeometry mergeLines() const;
1484 
1493  QgsGeometry difference( const QgsGeometry &geometry ) const;
1494 
1503  QgsGeometry symDifference( const QgsGeometry &geometry ) const;
1504 
1506  QgsGeometry extrude( double x, double y );
1507 
1508 #ifndef SIP_RUN
1509 
1531  QVector< QgsPointXY > randomPointsInPolygon( int count, const std::function< bool( const QgsPointXY & ) > &acceptPoint, unsigned long seed = 0, QgsFeedback *feedback = nullptr, int maxTriesPerPoint = 0 ) const;
1532 
1546  QVector< QgsPointXY > randomPointsInPolygon( int count, unsigned long seed = 0, QgsFeedback *feedback = nullptr ) const;
1548 #else
1549 
1562  SIP_PYOBJECT randomPointsInPolygon( int count, unsigned long seed = 0 ) const SIP_TYPEHINT( QgsPolylineXY );
1563  % MethodCode
1564  const QgsWkbTypes::GeometryType type = sipCpp->type();
1565  if ( sipCpp->isNull() )
1566  {
1567  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Cannot generate points inside a null geometry." ).toUtf8().constData() );
1568  sipIsErr = 1;
1569  }
1570  else if ( type != QgsWkbTypes::PolygonGeometry )
1571  {
1572  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Cannot generate points inside a %1 geometry. Only Polygon types are permitted." ).arg( QgsWkbTypes::displayString( sipCpp->wkbType() ) ).toUtf8().constData() );
1573  sipIsErr = 1;
1574  }
1575  else
1576  {
1577  const sipTypeDef *qvector_type = sipFindType( "QVector<QgsPointXY>" );
1578  sipRes = sipConvertFromNewType( new QVector< QgsPointXY >( sipCpp->randomPointsInPolygon( a0, a1 ) ), qvector_type, Py_None );
1579  }
1580  % End
1581 
1582 
1583 #endif
1584 
1593  int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const;
1594 
1602  QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const;
1603 
1609  QString asWkt( int precision = 17 ) const;
1610 
1611 #ifdef SIP_RUN
1612  SIP_PYOBJECT __repr__();
1613  % MethodCode
1614  QString str;
1615  if ( sipCpp->isNull() )
1616  str = QStringLiteral( "<QgsGeometry: null>" );
1617  else
1618  {
1619  QString wkt = sipCpp->asWkt();
1620  if ( wkt.length() > 1000 )
1621  wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
1622  str = QStringLiteral( "<QgsGeometry: %1>" ).arg( wkt );
1623  }
1624  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
1625  % End
1626 #endif
1627 
1631  QString asJson( int precision = 17 ) const;
1632 
1638  virtual json asJsonObject( int precision = 17 ) const SIP_SKIP;
1639 
1662  QVector< QgsGeometry > coerceToType( QgsWkbTypes::Type type ) const;
1663 
1676  QgsGeometry convertToType( QgsWkbTypes::GeometryType destType, bool destMultipart = false ) const;
1677 
1678  /* Accessor functions for getting geometry data */
1679 
1680 #ifndef SIP_RUN
1681 
1689  QgsPointXY asPoint() const;
1690 #else
1691 
1701  SIP_PYOBJECT asPoint() const SIP_TYPEHINT( QgsPointXY );
1702  % MethodCode
1703  const QgsWkbTypes::Type type = sipCpp->wkbType();
1704  if ( sipCpp->isNull() )
1705  {
1706  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a point." ).toUtf8().constData() );
1707  sipIsErr = 1;
1708  }
1709  else if ( QgsWkbTypes::flatType( type ) != QgsWkbTypes::Point )
1710  {
1711  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1712  sipIsErr = 1;
1713  }
1714  else
1715  {
1716  sipRes = sipConvertFromNewType( new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
1717  }
1718  % End
1719 #endif
1720 
1721 #ifndef SIP_RUN
1722 
1731  QgsPolylineXY asPolyline() const;
1732 #else
1733 
1744  SIP_PYOBJECT asPolyline() const SIP_TYPEHINT( QgsPolylineXY );
1745  % MethodCode
1746  const QgsWkbTypes::Type type = sipCpp->wkbType();
1747  if ( sipCpp->isNull() )
1748  {
1749  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a polyline." ).toUtf8().constData() );
1750  sipIsErr = 1;
1751  }
1753  {
1754  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() );
1755  sipIsErr = 1;
1756  }
1757  else
1758  {
1759  const sipTypeDef *qvector_type = sipFindType( "QVector< QgsPointXY >" );
1760  sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asPolyline() ), qvector_type, Py_None );
1761  }
1762  % End
1763 #endif
1764 
1765 #ifndef SIP_RUN
1766 
1775  QgsPolygonXY asPolygon() const;
1776 #else
1777 
1788  SIP_PYOBJECT asPolygon() const SIP_TYPEHINT( QgsPolygonXY );
1789  % MethodCode
1790  const QgsWkbTypes::Type type = sipCpp->wkbType();
1791  if ( sipCpp->isNull() )
1792  {
1793  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a polygon." ).toUtf8().constData() );
1794  sipIsErr = 1;
1795  }
1797  {
1798  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() );
1799  sipIsErr = 1;
1800  }
1801  else
1802  {
1803  const sipTypeDef *qvector_type = sipFindType( "QVector<QVector<QgsPointXY>>" );
1804  sipRes = sipConvertFromNewType( new QgsPolygonXY( sipCpp->asPolygon() ), qvector_type, Py_None );
1805  }
1806  % End
1807 #endif
1808 
1809 #ifndef SIP_RUN
1810 
1818  QgsMultiPointXY asMultiPoint() const;
1819 #else
1820 
1830  SIP_PYOBJECT asMultiPoint() const SIP_TYPEHINT( QgsMultiPointXY );
1831  % MethodCode
1832  const QgsWkbTypes::Type type = sipCpp->wkbType();
1833  if ( sipCpp->isNull() )
1834  {
1835  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multipoint." ).toUtf8().constData() );
1836  sipIsErr = 1;
1837  }
1839  {
1840  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a multipoint. Only multipoint types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1841  sipIsErr = 1;
1842  }
1843  else
1844  {
1845  const sipTypeDef *qvector_type = sipFindType( "QVector< QgsPointXY >" );
1846  sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asMultiPoint() ), qvector_type, Py_None );
1847  }
1848  % End
1849 #endif
1850 
1851 #ifndef SIP_RUN
1852 
1861  QgsMultiPolylineXY asMultiPolyline() const;
1862 #else
1863 
1874  SIP_PYOBJECT asMultiPolyline() const SIP_TYPEHINT( QgsMultiPolylineXY );
1875  % MethodCode
1876  const QgsWkbTypes::Type type = sipCpp->wkbType();
1877  if ( sipCpp->isNull() )
1878  {
1879  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multilinestring." ).toUtf8().constData() );
1880  sipIsErr = 1;
1881  }
1883  {
1884  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() );
1885  sipIsErr = 1;
1886  }
1887  else
1888  {
1889  const sipTypeDef *qvector_type = sipFindType( "QVector<QVector<QgsPointXY>>" );
1890  sipRes = sipConvertFromNewType( new QgsMultiPolylineXY( sipCpp->asMultiPolyline() ), qvector_type, Py_None );
1891  }
1892  % End
1893 #endif
1894 
1895 #ifndef SIP_RUN
1896 
1905  QgsMultiPolygonXY asMultiPolygon() const;
1906 #else
1907 
1918  SIP_PYOBJECT asMultiPolygon() const SIP_TYPEHINT( QgsMultiPolygonXY );
1919  % MethodCode
1920  const QgsWkbTypes::Type type = sipCpp->wkbType();
1921  if ( sipCpp->isNull() )
1922  {
1923  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multipolygon." ).toUtf8().constData() );
1924  sipIsErr = 1;
1925  }
1927  {
1928  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() );
1929  sipIsErr = 1;
1930  }
1931  else
1932  {
1933  const sipTypeDef *qvector_type = sipFindType( "QVector<QVector<QVector<QgsPointXY>>>" );
1934  sipRes = sipConvertFromNewType( new QgsMultiPolygonXY( sipCpp->asMultiPolygon() ), qvector_type, Py_None );
1935  }
1936  % End
1937 #endif
1938 
1943  QVector<QgsGeometry> asGeometryCollection() const;
1944 
1950  QPointF asQPointF() const SIP_HOLDGIL;
1951 
1964  QPolygonF asQPolygonF() const SIP_HOLDGIL;
1965 
1972  bool deleteRing( int ringNum, int partNum = 0 );
1973 
1979  bool deletePart( int partNum );
1980 
1989  bool convertToMultiType();
1990 
2000  bool convertToSingleType();
2001 
2011  bool convertGeometryCollectionToSubclass( QgsWkbTypes::GeometryType geomType );
2012 
2023  int avoidIntersections( const QList<QgsVectorLayer *> &avoidIntersectionsLayers,
2024  const QHash<QgsVectorLayer *, QSet<QgsFeatureId> > &ignoreFeatures SIP_PYARGREMOVE = ( QHash<QgsVectorLayer *, QSet<QgsFeatureId> >() ) );
2025 
2044  QgsGeometry makeValid() const;
2045 
2053  QgsGeometry forceRHR() const;
2054 
2058  class CORE_EXPORT Error
2059  {
2060  public:
2062  : mMessage( QStringLiteral( "none" ) )
2063  {}
2064 
2065  explicit Error( const QString &m )
2066  : mMessage( m )
2067  {}
2068 
2069  Error( const QString &m, const QgsPointXY &p )
2070  : mMessage( m )
2071  , mLocation( p )
2072  , mHasLocation( true ) {}
2073 
2077  QString what() const;
2078 
2082  QgsPointXY where() const;
2083 
2087  bool hasWhere() const;
2088 
2089 #ifdef SIP_RUN
2090  SIP_PYOBJECT __repr__();
2091  % MethodCode
2092  QString str = QStringLiteral( "<QgsGeometry.Error: %1>" ).arg( sipCpp->what() );
2093  sipRes = PyUnicode_FromString( str.toUtf8().data() );
2094  % End
2095 #endif
2096 
2097  bool operator==( const QgsGeometry::Error &other ) const
2098  {
2099  return other.mMessage == mMessage && other.mHasLocation == mHasLocation && other.mLocation == mLocation;
2100  }
2101 
2102  private:
2103  QString mMessage;
2104  QgsPointXY mLocation;
2105  bool mHasLocation = false;
2106  };
2107 
2113  {
2116  };
2117 
2126  void validateGeometry( QVector<QgsGeometry::Error> &errors SIP_OUT, ValidationMethod method = ValidatorQgisInternal, QgsGeometry::ValidityFlags flags = QgsGeometry::ValidityFlags() ) const;
2127 
2133  static QgsGeometry unaryUnion( const QVector<QgsGeometry> &geometries );
2134 
2143  static QgsGeometry polygonize( const QVector<QgsGeometry> &geometries );
2144 
2152  void convertToStraightSegment( double tolerance = M_PI / 180., QgsAbstractGeometry::SegmentationToleranceType toleranceType = QgsAbstractGeometry::MaximumAngle );
2153 
2160  bool requiresConversionToStraightSegments() const;
2161 
2167  void mapToPixel( const QgsMapToPixel &mtp );
2168 
2174  void draw( QPainter &p ) const;
2175 
2186  bool vertexIdFromVertexNr( int number, QgsVertexId &id SIP_OUT ) const;
2187 
2199  int vertexNrFromVertexId( QgsVertexId id ) const;
2200 
2208  QString lastError() const SIP_HOLDGIL;
2209 
2219  void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) SIP_SKIP;
2220 
2235  void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) SIP_SKIP;
2236 
2242  static QgsGeometry fromQPointF( QPointF point ) SIP_HOLDGIL;
2243 
2251  static QgsGeometry fromQPolygonF( const QPolygonF &polygon );
2252 
2260  Q_DECL_DEPRECATED static QgsPolylineXY createPolylineFromQPolygonF( const QPolygonF &polygon ) SIP_DEPRECATED;
2261 
2269  Q_DECL_DEPRECATED static QgsPolygonXY createPolygonFromQPolygonF( const QPolygonF &polygon ) SIP_DEPRECATED;
2270 
2271 #ifndef SIP_RUN
2272 
2282  static bool compare( const QgsPolylineXY &p1, const QgsPolylineXY &p2,
2283  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2284 
2294  static bool compare( const QgsPolygonXY &p1, const QgsPolygonXY &p2,
2295  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2296 
2307  static bool compare( const QgsMultiPolygonXY &p1, const QgsMultiPolygonXY &p2,
2308  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2309 #else
2310 
2330  static bool compare( PyObject *obj1, PyObject *obj2, double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2331  % MethodCode
2332  {
2333  sipRes = false;
2334  int state0;
2335  int state1;
2336  int sipIsErr = 0;
2337 
2338  if ( PyList_Check( a0 ) && PyList_Check( a1 ) &&
2339  PyList_GET_SIZE( a0 ) && PyList_GET_SIZE( a1 ) )
2340  {
2341  PyObject *o0 = PyList_GetItem( a0, 0 );
2342  PyObject *o1 = PyList_GetItem( a1, 0 );
2343  if ( o0 && o1 )
2344  {
2345  // compare polyline - polyline
2346  if ( sipCanConvertToType( o0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2347  sipCanConvertToType( o1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2348  sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2349  sipCanConvertToType( a1, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2350  {
2351  QgsPolylineXY *p0;
2352  QgsPolylineXY *p1;
2353  p0 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2354  p1 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a1, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2355  if ( sipIsErr )
2356  {
2357  sipReleaseType( p0, sipType_QVector_0100QgsPointXY, state0 );
2358  sipReleaseType( p1, sipType_QVector_0100QgsPointXY, state1 );
2359  }
2360  else
2361  {
2362  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2363  }
2364  }
2365  else if ( PyList_Check( o0 ) && PyList_Check( o1 ) &&
2366  PyList_GET_SIZE( o0 ) && PyList_GET_SIZE( o1 ) )
2367  {
2368  PyObject *oo0 = PyList_GetItem( o0, 0 );
2369  PyObject *oo1 = PyList_GetItem( o1, 0 );
2370  if ( oo0 && oo1 )
2371  {
2372  // compare polygon - polygon
2373  if ( sipCanConvertToType( oo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2374  sipCanConvertToType( oo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2375  sipCanConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2376  sipCanConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2377  {
2378  QgsPolygonXY *p0;
2379  QgsPolygonXY *p1;
2380  p0 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2381  p1 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2382  if ( sipIsErr )
2383  {
2384  sipReleaseType( p0, sipType_QVector_0600QVector_0100QgsPointXY, state0 );
2385  sipReleaseType( p1, sipType_QVector_0600QVector_0100QgsPointXY, state1 );
2386  }
2387  else
2388  {
2389  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2390  }
2391  }
2392  else if ( PyList_Check( oo0 ) && PyList_Check( oo1 ) &&
2393  PyList_GET_SIZE( oo0 ) && PyList_GET_SIZE( oo1 ) )
2394  {
2395  PyObject *ooo0 = PyList_GetItem( oo0, 0 );
2396  PyObject *ooo1 = PyList_GetItem( oo1, 0 );
2397  if ( ooo0 && ooo1 )
2398  {
2399  // compare multipolygon - multipolygon
2400  if ( sipCanConvertToType( ooo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2401  sipCanConvertToType( ooo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2402  sipCanConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2403  sipCanConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2404  {
2405  QgsMultiPolygonXY *p0;
2406  QgsMultiPolygonXY *p1;
2407  p0 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2408  p1 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2409  if ( sipIsErr )
2410  {
2411  sipReleaseType( p0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state0 );
2412  sipReleaseType( p1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state1 );
2413  }
2414  else
2415  {
2416  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2417  }
2418  }
2419  }
2420  }
2421  }
2422  }
2423  }
2424  }
2425  }
2426  % End
2427 #endif
2428 
2445  QgsGeometry smooth( unsigned int iterations = 1, double offset = 0.25,
2446  double minimumDistance = -1.0, double maxAngle = 180.0 ) const;
2447 
2451  static QgsGeometryEngine *createGeometryEngine( const QgsAbstractGeometry *geometry ) SIP_FACTORY;
2452 
2458  static void convertPointList( const QVector<QgsPointXY> &input, QgsPointSequence &output );
2459 
2465  static void convertPointList( const QgsPointSequence &input, QVector<QgsPointXY> &output );
2466 
2468  operator QVariant() const
2469  {
2470  return QVariant::fromValue( *this );
2471  }
2472 
2473  private:
2474 
2475  QgsGeometryPrivate *d; //implicitly shared data pointer
2476 
2478  mutable QString mLastError;
2479 
2484  void detach();
2485 
2490  void reset( std::unique_ptr< QgsAbstractGeometry > newGeometry );
2491 
2492  static void convertToPolyline( const QgsPointSequence &input, QgsPolylineXY &output );
2493  static void convertPolygon( const QgsPolygon &input, QgsPolygonXY &output );
2494 
2496  QgsGeometry convertToPoint( bool destMultipart ) const;
2498  QgsGeometry convertToLine( bool destMultipart ) const;
2500  QgsGeometry convertToPolygon( bool destMultipart ) const;
2501 
2513  std::unique_ptr< QgsLineString > smoothLine( const QgsLineString &line, unsigned int iterations = 1, double offset = 0.25,
2514  double minimumDistance = -1, double maxAngle = 180.0 ) const;
2515 
2527  std::unique_ptr< QgsPolygon > smoothPolygon( const QgsPolygon &polygon, unsigned int iterations = 1, double offset = 0.25,
2528  double minimumDistance = -1, double maxAngle = 180.0 ) const;
2529 
2530 
2532 
2533 }; // class QgsGeometry
2534 
2536 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsGeometry::ValidityFlags )
2537 
2538 CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsGeometry &geometry );
2541 CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsGeometry &geometry );
2542 
2543 #endif
Geometry engine misses a method implemented or an error occurred in the geometry engine.
Definition: qgsgeometry.h:143
int precision
QgsPointSequence QgsPolyline
Polyline as represented as a vector of points.
Definition: qgsgeometry.h:71
A rectangle specified with double values.
Definition: qgsrectangle.h:41
Java-style iterator for traversal of parts of a geometry.
The input ring doesn&#39;t have any existing ring to fit into.
Definition: qgsgeometry.h:152
Java-style iterator for traversal of vertices of a geometry.
The source geometry is not multi.
Definition: qgsgeometry.h:147
Maximum angle between generating radii (lines from arc center to output vertices) ...
Use GEOS validation methods.
Definition: qgsgeometry.h:2115
Error(const QString &m)
Definition: qgsgeometry.h:2065
bool operator==(const QgsGeometry::Error &other) const
Definition: qgsgeometry.h:2097
Java-style iterator for const traversal of parts of a geometry.
Handles storage of information regarding WKB types and their properties.
Definition: qgswkbtypes.h:41
A class to represent a 2D point.
Definition: qgspointxy.h:43
TransformDirection
Enum used to indicate the direction (forward or inverse) of the transform.
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item...
Definition: qgsgeometry.h:75
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features ...
Definition: qgsfeatureid.h:28
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:702
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.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:123
Use mitered joins.
Definition: qgsgeometry.h:1152
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
Definition: qgsgeometry.h:81
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...
EndCapStyle
End cap styles for buffers.
Definition: qgsgeometry.h:1140
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:218
OperationResult
Success or failure of a geometry operation.
Definition: qgsgeometry.h:135
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
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
Definition: qgsgeometry.h:92
Error(const QString &m, const QgsPointXY &p)
Definition: qgsgeometry.h:2069
#define SIP_IN
Definition: qgis_sip.h:63
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
Definition: qgsgeometry.h:85
Base class for feedback objects to be used for cancellation of something running in a worker thread...
Definition: qgsfeedback.h:43
CORE_EXPORT QDataStream & operator<<(QDataStream &out, const QgsGeometry &geometry)
Writes the geometry to stream out. QGIS version compatibility is not guaranteed.
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:37
Cannot edit layer.
Definition: qgsgeometry.h:144
The selected geometry cannot be found.
Definition: qgsgeometry.h:146
No features were selected.
Definition: qgsgeometry.h:141
More than one features were selected.
Definition: qgsgeometry.h:142
Utility class for identifying a unique vertex within a geometry.
#define SIP_HOLDGIL
Definition: qgis_sip.h:157
const double DEFAULT_SEGMENT_EPSILON
Default snapping tolerance for segments.
Definition: qgis.h:756
The input ring crosses existing rings (it is not disjoint)
Definition: qgsgeometry.h:151
#define SIP_SKIP
Definition: qgis_sip.h:126
The part_iterator class provides STL-style iterator for geometry parts.
std::unique_ptr< GEOSGeometry, GeosDeleter > unique_ptr
Scoped GEOS pointer.
Definition: qgsgeos.h:79
Use internal QgsGeometryValidator method.
Definition: qgsgeometry.h:2114
#define SIP_TRANSFER
Definition: qgis_sip.h:36
Q_DECLARE_METATYPE(QgsMeshTimeSettings)
The input ring is not closed.
Definition: qgsgeometry.h:149
Square cap (extends past start/end of line by buffer distance)
Definition: qgsgeometry.h:1144
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
#define SIP_FACTORY
Definition: qgis_sip.h:76
Abstract base class for all geometries.
The vertex_iterator class provides STL-style iterator for vertices.
#define SIP_DEPRECATED
Definition: qgis_sip.h:106
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
This class offers geometry processing methods.
CORE_EXPORT QDataStream & operator>>(QDataStream &in, QgsGeometry &geometry)
Reads a geometry from stream in into geometry. QGIS version compatibility is not guaranteed.
BufferSide
Side of line to buffer.
Definition: qgsgeometry.h:1132
QVector< QgsPoint > QgsPointSequence
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:140
#define SIP_PYARGREMOVE
Definition: qgis_sip.h:146
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
Definition: qgsgeometry.h:51
The base geometry on which the operation is done is invalid or empty.
Definition: qgsgeometry.h:139
The input geometry (ring, part, split line, etc.) has not the correct geometry type.
Definition: qgsgeometry.h:140
#define SIP_OUT
Definition: qgis_sip.h:58
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:43
ValidationMethod
Available methods for validating geometries.
Definition: qgsgeometry.h:2112
Buffer to right of line.
Definition: qgsgeometry.h:1135
Class for doing transforms between two map coordinate systems.
ValidityFlag
Validity check flags.
Definition: qgsgeometry.h:367
The input ring is not valid.
Definition: qgsgeometry.h:150
#define SIP_THROW(name)
Definition: qgis_sip.h:189
Contains geometry relation and modification algorithms.
Use beveled joins.
Definition: qgsgeometry.h:1153
Transform from source to destination CRS.
static bool isMultiType(Type type) SIP_HOLDGIL
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:832
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
Polygon geometry type.
Definition: qgspolygon.h:33
JoinStyle
Join styles for buffers.
Definition: qgsgeometry.h:1149
Flat cap (in line with start/end of line)
Definition: qgsgeometry.h:1143
Represents a vector layer which manages a vector based data sets.
static QString displayString(Type type) SIP_HOLDGIL
Returns a display string type for a WKB type, e.g., the geometry name used in WKT geometry representa...
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;. Negative values mean left ...
Definition: MathUtils.cpp:292
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 compare(const QgsPolylineXY &p1, const QgsPolylineXY &p2, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compares two polylines for equality within a specified tolerance.
#define SIP_PYNAME(name)
Definition: qgis_sip.h:81