QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
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;
51 
61 typedef QVector<QgsPointXY> QgsPolylineXY;
62 
71 
73 #ifndef SIP_RUN
74 typedef QVector<QgsPolylineXY> QgsPolygonXY;
75 #else
76 typedef QVector<QVector<QgsPointXY>> QgsPolygonXY;
77 #endif
78 
80 typedef QVector<QgsPointXY> QgsMultiPointXY;
81 
83 #ifndef SIP_RUN
84 typedef QVector<QgsPolylineXY> QgsMultiPolylineXY;
85 #else
86 typedef QVector<QVector<QgsPointXY>> QgsMultiPolylineXY;
87 #endif
88 
90 #ifndef SIP_RUN
91 typedef QVector<QgsPolygonXY> QgsMultiPolygonXY;
92 #else
93 typedef QVector<QVector<QVector<QgsPointXY>>> QgsMultiPolygonXY;
94 #endif
95 
96 class QgsRectangle;
97 
98 class QgsConstWkbPtr;
99 
100 struct QgsGeometryPrivate;
101 
122 class CORE_EXPORT QgsGeometry
123 {
124  Q_GADGET
125  Q_PROPERTY( bool isNull READ isNull )
126  Q_PROPERTY( QgsWkbTypes::GeometryType type READ type )
127 
128  public:
129 
135  {
136  Success = 0,
137  NothingHappened = 1000,
144  /* Add part issues */
147  /* Add ring issues*/
152  /* Split features */
154  };
155 
157  QgsGeometry();
158 
160  QgsGeometry( const QgsGeometry & );
161 
166  QgsGeometry &operator=( QgsGeometry const &rhs ) SIP_SKIP;
167 
173  explicit QgsGeometry( QgsAbstractGeometry *geom SIP_TRANSFER );
174 
180  explicit QgsGeometry( std::unique_ptr< QgsAbstractGeometry > geom ) SIP_SKIP;
181 
182  virtual ~QgsGeometry();
183 
195  const QgsAbstractGeometry *constGet() const;
196 
209  QgsAbstractGeometry *get();
210 
223  void set( QgsAbstractGeometry *geometry SIP_TRANSFER ) SIP_DEPRECATED;
224 
232  bool isNull() const;
233 
235  static QgsGeometry fromWkt( const QString &wkt );
237  static QgsGeometry fromPointXY( const QgsPointXY &point );
239  static QgsGeometry fromMultiPointXY( const QgsMultiPointXY &multipoint );
240 
252  static QgsGeometry fromPolylineXY( const QgsPolylineXY &polyline );
253 
263  static QgsGeometry fromPolyline( const QgsPolyline &polyline );
264 
266  static QgsGeometry fromMultiPolylineXY( const QgsMultiPolylineXY &multiline );
268  static QgsGeometry fromPolygonXY( const QgsPolygonXY &polygon );
270  static QgsGeometry fromMultiPolygonXY( const QgsMultiPolygonXY &multipoly );
272  static QgsGeometry fromRect( const QgsRectangle &rect );
274  static QgsGeometry collectGeometry( const QVector<QgsGeometry> &geometries );
275 
291  static QgsGeometry createWedgeBuffer( const QgsPoint &center, double azimuth, double angularWidth,
292  double outerRadius, double innerRadius = 0 );
293 
299  void fromWkb( unsigned char *wkb, int length ) SIP_SKIP;
300 
305  void fromWkb( const QByteArray &wkb );
306 
311  QgsWkbTypes::Type wkbType() const;
312 
317  QgsWkbTypes::GeometryType type() const;
318 
325  bool isEmpty() const;
326 
328  bool isMultipart() const;
329 
344  bool equals( const QgsGeometry &geometry ) const;
345 
362  bool isGeosEqual( const QgsGeometry & ) const;
363 
366  {
367  FlagAllowSelfTouchingHoles = 1 << 0,
368  };
369  Q_DECLARE_FLAGS( ValidityFlags, ValidityFlag )
370 
371 
378  bool isGeosValid( QgsGeometry::ValidityFlags flags = nullptr ) const;
379 
388  bool isSimple() const;
389 
402  double area() const;
403 
416  double length() const;
417 
425  double distance( const QgsGeometry &geom ) const;
426 
427 #ifndef SIP_RUN
428 
429  // TODO QGIS 4: consider renaming vertices_begin, vertices_end, parts_begin, parts_end, etc
430  // to camelCase
431 
436  QgsAbstractGeometry::vertex_iterator vertices_begin() const;
437 
442  QgsAbstractGeometry::vertex_iterator vertices_end() const;
443 #endif
444 
467  QgsVertexIterator vertices() const;
468 
469 #ifndef SIP_RUN
470 
480 
490 
499  QgsAbstractGeometry::const_part_iterator const_parts_begin() const;
500 
509  QgsAbstractGeometry::const_part_iterator const_parts_end() const;
510 #endif
511 
548  QgsGeometryPartIterator parts();
549 
581  QgsGeometryConstPartIterator constParts() const;
582 
600  double hausdorffDistance( const QgsGeometry &geom ) const;
601 
620  double hausdorffDistanceDensify( const QgsGeometry &geom, double densifyFraction ) const;
621 
622  //TODO QGIS 4.0 - rename beforeVertex to previousVertex, afterVertex to nextVertex
623 
636  QgsPointXY closestVertex( const QgsPointXY &point, int &atVertex SIP_OUT, int &beforeVertex SIP_OUT, int &afterVertex SIP_OUT, double &sqrDist SIP_OUT ) const;
637 
646  double distanceToVertex( int vertex ) const;
647 
655  double angleAtVertex( int vertex ) const;
656 
669  void adjacentVertices( int atVertex, int &beforeVertex SIP_OUT, int &afterVertex SIP_OUT ) const;
670 
683  bool insertVertex( double x, double y, int beforeVertex );
684 
697  bool insertVertex( const QgsPoint &point, int beforeVertex );
698 
706  bool moveVertex( double x, double y, int atVertex );
707 
715  bool moveVertex( const QgsPoint &p, int atVertex );
716 
728  bool deleteVertex( int atVertex );
729 
735  QgsPoint vertexAt( int atVertex ) const;
736 
742  double sqrDistToVertexAt( QgsPointXY &point SIP_IN, int atVertex ) const;
743 
749  QgsGeometry nearestPoint( const QgsGeometry &other ) const;
750 
761  QgsGeometry shortestLine( const QgsGeometry &other ) const;
762 
769  double closestVertexWithContext( const QgsPointXY &point, int &atVertex SIP_OUT ) const;
770 
782  double closestSegmentWithContext( const QgsPointXY &point, QgsPointXY &minDistPoint SIP_OUT, int &afterVertex SIP_OUT, int *leftOf SIP_OUT = nullptr, double epsilon = DEFAULT_SEGMENT_EPSILON ) const;
783 
789  OperationResult addRing( const QVector<QgsPointXY> &ring );
790 
796  OperationResult addRing( QgsCurve *ring SIP_TRANSFER );
797 
804  OperationResult addPart( const QVector<QgsPointXY> &points, QgsWkbTypes::GeometryType geomType = QgsWkbTypes::UnknownGeometry ) SIP_PYNAME( addPointsXY );
805 
813 
821 
827  OperationResult addPart( const QgsGeometry &newPart ) SIP_PYNAME( addPartGeometry );
828 
835  QgsGeometry removeInteriorRings( double minimumAllowedArea = -1 ) const;
836 
841  OperationResult translate( double dx, double dy, double dz = 0.0, double dm = 0.0 );
842 
858 
867  OperationResult transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 );
868 
875  OperationResult rotate( double rotation, const QgsPointXY &center );
876 
886  Q_DECL_DEPRECATED OperationResult splitGeometry( const QVector<QgsPointXY> &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QVector<QgsPointXY> &topologyTestPoints SIP_OUT ) SIP_DEPRECATED;
887 
896  OperationResult splitGeometry( const QgsPointSequence &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QgsPointSequence &topologyTestPoints SIP_OUT );
897 
902  OperationResult reshapeGeometry( const QgsLineString &reshapeLineString );
903 
909  int makeDifferenceInPlace( const QgsGeometry &other ) SIP_SKIP;
910 
918  QgsGeometry makeDifference( const QgsGeometry &other ) const;
919 
924  QgsRectangle boundingBox() const;
925 
933  QgsGeometry orientedMinimumBoundingBox( double &area SIP_OUT, double &angle SIP_OUT, double &width SIP_OUT, double &height SIP_OUT ) const;
934 
940  QgsGeometry orientedMinimumBoundingBox() const SIP_SKIP;
941 
950  QgsGeometry minimalEnclosingCircle( QgsPointXY &center SIP_OUT, double &radius SIP_OUT, unsigned int segments = 36 ) const;
951 
957  QgsGeometry minimalEnclosingCircle( unsigned int segments = 36 ) const SIP_SKIP;
958 
967  QgsGeometry orthogonalize( double tolerance = 1.0E-8, int maxIterations = 1000, double angleThreshold = 15.0 ) const;
968 
981  QgsGeometry snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const;
982 
1003  bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false );
1004 
1014  bool intersects( const QgsRectangle &rectangle ) const;
1015 
1025  bool intersects( const QgsGeometry &geometry ) const;
1026 
1036  bool boundingBoxIntersects( const QgsRectangle &rectangle ) const;
1037 
1047  bool boundingBoxIntersects( const QgsGeometry &geometry ) const;
1048 
1052  bool contains( const QgsPointXY *p ) const;
1053 
1058  bool contains( const QgsGeometry &geometry ) const;
1059 
1064  bool disjoint( const QgsGeometry &geometry ) const;
1065 
1070  bool touches( const QgsGeometry &geometry ) const;
1071 
1076  bool overlaps( const QgsGeometry &geometry ) const;
1077 
1082  bool within( const QgsGeometry &geometry ) const;
1083 
1084 
1089  bool crosses( const QgsGeometry &geometry ) const;
1090 
1093  {
1094  SideLeft = 0,
1096  };
1097  Q_ENUM( BufferSide )
1098 
1099 
1101  {
1102  CapRound = 1,
1105  };
1106  Q_ENUM( EndCapStyle )
1107 
1108 
1110  {
1111  JoinStyleRound = 1,
1114  };
1115  Q_ENUM( JoinStyle )
1116 
1117 
1124  QgsGeometry buffer( double distance, int segments ) const;
1125 
1138  QgsGeometry buffer( double distance, int segments, EndCapStyle endCapStyle, JoinStyle joinStyle, double miterLimit ) const;
1139 
1148  QgsGeometry offsetCurve( double distance, int segments, JoinStyle joinStyle, double miterLimit ) const;
1149 
1165  QgsGeometry singleSidedBuffer( double distance, int segments, BufferSide side,
1166  JoinStyle joinStyle = JoinStyleRound,
1167  double miterLimit = 2.0 ) const;
1168 
1186  QgsGeometry taperedBuffer( double startWidth, double endWidth, int segments ) const;
1187 
1202  QgsGeometry variableWidthBufferByM( int segments ) const;
1203 
1210  QgsGeometry extendLine( double startDistance, double endDistance ) const;
1211 
1213  QgsGeometry simplify( double tolerance ) const;
1214 
1224  QgsGeometry densifyByCount( int extraNodesPerSegment ) const;
1225 
1240  QgsGeometry densifyByDistance( double distance ) const;
1241 
1255  QgsGeometry centroid() const;
1256 
1270  QgsGeometry pointOnSurface() const;
1271 
1284  QgsGeometry poleOfInaccessibility( double precision, double *distanceToBoundary SIP_OUT = nullptr ) const;
1285 
1294  QgsGeometry convexHull() const;
1295 
1311  QgsGeometry voronoiDiagram( const QgsGeometry &extent = QgsGeometry(), double tolerance = 0.0, bool edgesOnly = false ) const;
1312 
1322  QgsGeometry delaunayTriangulation( double tolerance = 0.0, bool edgesOnly = false ) const;
1323 
1343  QgsGeometry subdivide( int maxNodes = 256 ) const;
1344 
1360  QgsGeometry interpolate( double distance ) const;
1361 
1373  double lineLocatePoint( const QgsGeometry &point ) const;
1374 
1384  double interpolateAngle( double distance ) const;
1385 
1394  QgsGeometry intersection( const QgsGeometry &geometry ) const;
1395 
1403  QgsGeometry clipped( const QgsRectangle &rectangle );
1404 
1416  QgsGeometry combine( const QgsGeometry &geometry ) const;
1417 
1426  QgsGeometry mergeLines() const;
1427 
1436  QgsGeometry difference( const QgsGeometry &geometry ) const;
1437 
1446  QgsGeometry symDifference( const QgsGeometry &geometry ) const;
1447 
1449  QgsGeometry extrude( double x, double y );
1450 
1451 #ifndef SIP_RUN
1452 
1469  QVector< QgsPointXY > randomPointsInPolygon( int count, const std::function< bool( const QgsPointXY & ) > &acceptPoint, unsigned long seed = 0, QgsFeedback *feedback = nullptr );
1470 
1484  QVector< QgsPointXY > randomPointsInPolygon( int count, unsigned long seed = 0, QgsFeedback *feedback = nullptr );
1486 #else
1487 
1500  SIP_PYOBJECT randomPointsInPolygon( int count, unsigned long seed = 0 ) SIP_TYPEHINT( QgsPolylineXY );
1501  % MethodCode
1502  const QgsWkbTypes::GeometryType type = sipCpp->type();
1503  if ( sipCpp->isNull() )
1504  {
1505  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Cannot generate points inside a null geometry." ).toUtf8().constData() );
1506  sipIsErr = 1;
1507  }
1508  else if ( type != QgsWkbTypes::PolygonGeometry )
1509  {
1510  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Cannot generate points inside a %1 geometry. Only Polygon types are permitted." ).arg( QgsWkbTypes::displayString( sipCpp->wkbType() ) ).toUtf8().constData() );
1511  sipIsErr = 1;
1512  }
1513  else
1514  {
1515  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QgsPointXY>" );
1516  sipRes = sipConvertFromNewType( new QVector< QgsPointXY >( sipCpp->randomPointsInPolygon( a0, a1 ) ), qvector_type, Py_None );
1517  }
1518  % End
1519 
1520 
1521 #endif
1522 
1528  QByteArray asWkb() const;
1529 
1535  QString asWkt( int precision = 17 ) const;
1536 
1537 #ifdef SIP_RUN
1538  SIP_PYOBJECT __repr__();
1539  % MethodCode
1540  QString str;
1541  if ( sipCpp->isNull() )
1542  str = QStringLiteral( "<QgsGeometry: null>" );
1543  else
1544  {
1545  QString wkt = sipCpp->asWkt();
1546  if ( wkt.length() > 1000 )
1547  wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
1548  str = QStringLiteral( "<QgsGeometry: %1>" ).arg( wkt );
1549  }
1550  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
1551  % End
1552 #endif
1553 
1557  QString asJson( int precision = 17 ) const;
1558 
1564  virtual json asJsonObject( int precision = 17 ) const SIP_SKIP;
1565 
1573  QgsGeometry convertToType( QgsWkbTypes::GeometryType destType, bool destMultipart = false ) const SIP_FACTORY;
1574 
1575  /* Accessor functions for getting geometry data */
1576 
1577 #ifndef SIP_RUN
1578 
1586  QgsPointXY asPoint() const;
1587 #else
1588 
1598  SIP_PYOBJECT asPoint() const SIP_TYPEHINT( QgsPointXY );
1599  % MethodCode
1600  const QgsWkbTypes::Type type = sipCpp->wkbType();
1601  if ( sipCpp->isNull() )
1602  {
1603  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a point." ).toUtf8().constData() );
1604  sipIsErr = 1;
1605  }
1606  else if ( QgsWkbTypes::flatType( type ) != QgsWkbTypes::Point )
1607  {
1608  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1609  sipIsErr = 1;
1610  }
1611  else
1612  {
1613  sipRes = sipConvertFromNewType( new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
1614  }
1615  % End
1616 #endif
1617 
1618 #ifndef SIP_RUN
1619 
1628  QgsPolylineXY asPolyline() const;
1629 #else
1630 
1641  SIP_PYOBJECT asPolyline() const SIP_TYPEHINT( QgsPolylineXY );
1642  % MethodCode
1643  const QgsWkbTypes::Type type = sipCpp->wkbType();
1644  if ( sipCpp->isNull() )
1645  {
1646  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a polyline." ).toUtf8().constData() );
1647  sipIsErr = 1;
1648  }
1650  {
1651  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() );
1652  sipIsErr = 1;
1653  }
1654  else
1655  {
1656  const sipMappedType *qvector_type = sipFindMappedType( "QVector< QgsPointXY >" );
1657  sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asPolyline() ), qvector_type, Py_None );
1658  }
1659  % End
1660 #endif
1661 
1662 #ifndef SIP_RUN
1663 
1672  QgsPolygonXY asPolygon() const;
1673 #else
1674 
1685  SIP_PYOBJECT asPolygon() const SIP_TYPEHINT( QgsPolygonXY );
1686  % MethodCode
1687  const QgsWkbTypes::Type type = sipCpp->wkbType();
1688  if ( sipCpp->isNull() )
1689  {
1690  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a polygon." ).toUtf8().constData() );
1691  sipIsErr = 1;
1692  }
1694  {
1695  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() );
1696  sipIsErr = 1;
1697  }
1698  else
1699  {
1700  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QgsPointXY>>" );
1701  sipRes = sipConvertFromNewType( new QgsPolygonXY( sipCpp->asPolygon() ), qvector_type, Py_None );
1702  }
1703  % End
1704 #endif
1705 
1706 #ifndef SIP_RUN
1707 
1715  QgsMultiPointXY asMultiPoint() const;
1716 #else
1717 
1727  SIP_PYOBJECT asMultiPoint() const SIP_TYPEHINT( QgsMultiPointXY );
1728  % MethodCode
1729  const QgsWkbTypes::Type type = sipCpp->wkbType();
1730  if ( sipCpp->isNull() )
1731  {
1732  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multipoint." ).toUtf8().constData() );
1733  sipIsErr = 1;
1734  }
1736  {
1737  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a multipoint. Only multipoint types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1738  sipIsErr = 1;
1739  }
1740  else
1741  {
1742  const sipMappedType *qvector_type = sipFindMappedType( "QVector< QgsPointXY >" );
1743  sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asMultiPoint() ), qvector_type, Py_None );
1744  }
1745  % End
1746 #endif
1747 
1748 #ifndef SIP_RUN
1749 
1758  QgsMultiPolylineXY asMultiPolyline() const;
1759 #else
1760 
1771  SIP_PYOBJECT asMultiPolyline() const SIP_TYPEHINT( QgsMultiPolylineXY );
1772  % MethodCode
1773  const QgsWkbTypes::Type type = sipCpp->wkbType();
1774  if ( sipCpp->isNull() )
1775  {
1776  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multilinestring." ).toUtf8().constData() );
1777  sipIsErr = 1;
1778  }
1780  {
1781  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() );
1782  sipIsErr = 1;
1783  }
1784  else
1785  {
1786  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QgsPointXY>>" );
1787  sipRes = sipConvertFromNewType( new QgsMultiPolylineXY( sipCpp->asMultiPolyline() ), qvector_type, Py_None );
1788  }
1789  % End
1790 #endif
1791 
1792 #ifndef SIP_RUN
1793 
1802  QgsMultiPolygonXY asMultiPolygon() const;
1803 #else
1804 
1815  SIP_PYOBJECT asMultiPolygon() const SIP_TYPEHINT( QgsMultiPolygonXY );
1816  % MethodCode
1817  const QgsWkbTypes::Type type = sipCpp->wkbType();
1818  if ( sipCpp->isNull() )
1819  {
1820  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multipolygon." ).toUtf8().constData() );
1821  sipIsErr = 1;
1822  }
1824  {
1825  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() );
1826  sipIsErr = 1;
1827  }
1828  else
1829  {
1830  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QVector<QgsPointXY>>>" );
1831  sipRes = sipConvertFromNewType( new QgsMultiPolygonXY( sipCpp->asMultiPolygon() ), qvector_type, Py_None );
1832  }
1833  % End
1834 #endif
1835 
1840  QVector<QgsGeometry> asGeometryCollection() const;
1841 
1847  QPointF asQPointF() const;
1848 
1855  QPolygonF asQPolygonF() const;
1856 
1863  bool deleteRing( int ringNum, int partNum = 0 );
1864 
1870  bool deletePart( int partNum );
1871 
1880  bool convertToMultiType();
1881 
1891  bool convertToSingleType();
1892 
1902  bool convertGeometryCollectionToSubclass( QgsWkbTypes::GeometryType geomType );
1903 
1914  int avoidIntersections( const QList<QgsVectorLayer *> &avoidIntersectionsLayers,
1915  const QHash<QgsVectorLayer *, QSet<QgsFeatureId> > &ignoreFeatures SIP_PYARGREMOVE = ( QHash<QgsVectorLayer *, QSet<QgsFeatureId> >() ) );
1916 
1935  QgsGeometry makeValid() const;
1936 
1944  QgsGeometry forceRHR() const;
1945 
1949  class CORE_EXPORT Error
1950  {
1951  public:
1953  : mMessage( QStringLiteral( "none" ) )
1954  {}
1955 
1956  explicit Error( const QString &m )
1957  : mMessage( m )
1958  {}
1959 
1960  Error( const QString &m, const QgsPointXY &p )
1961  : mMessage( m )
1962  , mLocation( p )
1963  , mHasLocation( true ) {}
1964 
1968  QString what() const;
1969 
1973  QgsPointXY where() const;
1974 
1978  bool hasWhere() const;
1979 
1980 #ifdef SIP_RUN
1981  SIP_PYOBJECT __repr__();
1982  % MethodCode
1983  QString str = QStringLiteral( "<QgsGeometry.Error: %1>" ).arg( sipCpp->what() );
1984  sipRes = PyUnicode_FromString( str.toUtf8().data() );
1985  % End
1986 #endif
1987 
1988  bool operator==( const QgsGeometry::Error &other ) const
1989  {
1990  return other.mMessage == mMessage && other.mHasLocation == mHasLocation && other.mLocation == mLocation;
1991  }
1992 
1993  private:
1994  QString mMessage;
1995  QgsPointXY mLocation;
1996  bool mHasLocation = false;
1997  };
1998 
2004  {
2007  };
2008 
2017  void validateGeometry( QVector<QgsGeometry::Error> &errors SIP_OUT, ValidationMethod method = ValidatorQgisInternal, QgsGeometry::ValidityFlags flags = nullptr ) const;
2018 
2024  static QgsGeometry unaryUnion( const QVector<QgsGeometry> &geometries );
2025 
2034  static QgsGeometry polygonize( const QVector<QgsGeometry> &geometries );
2035 
2043  void convertToStraightSegment( double tolerance = M_PI / 180., QgsAbstractGeometry::SegmentationToleranceType toleranceType = QgsAbstractGeometry::MaximumAngle );
2044 
2051  bool requiresConversionToStraightSegments() const;
2052 
2058  void mapToPixel( const QgsMapToPixel &mtp );
2059 
2065  void draw( QPainter &p ) const;
2066 
2077  bool vertexIdFromVertexNr( int number, QgsVertexId &id SIP_OUT ) const;
2078 
2090  int vertexNrFromVertexId( QgsVertexId id ) const;
2091 
2099  QString lastError() const;
2100 
2110  void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) SIP_SKIP;
2111 
2126  void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) SIP_SKIP;
2127 
2133  static QgsGeometry fromQPointF( QPointF point );
2134 
2142  static QgsGeometry fromQPolygonF( const QPolygonF &polygon );
2143 
2151  Q_DECL_DEPRECATED static QgsPolylineXY createPolylineFromQPolygonF( const QPolygonF &polygon ) SIP_DEPRECATED;
2152 
2160  Q_DECL_DEPRECATED static QgsPolygonXY createPolygonFromQPolygonF( const QPolygonF &polygon ) SIP_DEPRECATED;
2161 
2162 #ifndef SIP_RUN
2163 
2173  static bool compare( const QgsPolylineXY &p1, const QgsPolylineXY &p2,
2174  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2175 
2185  static bool compare( const QgsPolygonXY &p1, const QgsPolygonXY &p2,
2186  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2187 
2198  static bool compare( const QgsMultiPolygonXY &p1, const QgsMultiPolygonXY &p2,
2199  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2200 #else
2201 
2220  static bool compare( PyObject *obj1, PyObject *obj2, double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2221  % MethodCode
2222  {
2223  sipRes = false;
2224  int state0;
2225  int state1;
2226  int sipIsErr = 0;
2227 
2228  if ( PyList_Check( a0 ) && PyList_Check( a1 ) &&
2229  PyList_GET_SIZE( a0 ) && PyList_GET_SIZE( a1 ) )
2230  {
2231  PyObject *o0 = PyList_GetItem( a0, 0 );
2232  PyObject *o1 = PyList_GetItem( a1, 0 );
2233  if ( o0 && o1 )
2234  {
2235  // compare polyline - polyline
2236  if ( sipCanConvertToType( o0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2237  sipCanConvertToType( o1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2238  sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2239  sipCanConvertToType( a1, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2240  {
2241  QgsPolylineXY *p0;
2242  QgsPolylineXY *p1;
2243  p0 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2244  p1 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a1, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2245  if ( sipIsErr )
2246  {
2247  sipReleaseType( p0, sipType_QVector_0100QgsPointXY, state0 );
2248  sipReleaseType( p1, sipType_QVector_0100QgsPointXY, state1 );
2249  }
2250  else
2251  {
2252  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2253  }
2254  }
2255  else if ( PyList_Check( o0 ) && PyList_Check( o1 ) &&
2256  PyList_GET_SIZE( o0 ) && PyList_GET_SIZE( o1 ) )
2257  {
2258  PyObject *oo0 = PyList_GetItem( o0, 0 );
2259  PyObject *oo1 = PyList_GetItem( o1, 0 );
2260  if ( oo0 && oo1 )
2261  {
2262  // compare polygon - polygon
2263  if ( sipCanConvertToType( oo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2264  sipCanConvertToType( oo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2265  sipCanConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2266  sipCanConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2267  {
2268  QgsPolygonXY *p0;
2269  QgsPolygonXY *p1;
2270  p0 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2271  p1 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2272  if ( sipIsErr )
2273  {
2274  sipReleaseType( p0, sipType_QVector_0600QVector_0100QgsPointXY, state0 );
2275  sipReleaseType( p1, sipType_QVector_0600QVector_0100QgsPointXY, state1 );
2276  }
2277  else
2278  {
2279  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2280  }
2281  }
2282  else if ( PyList_Check( oo0 ) && PyList_Check( oo1 ) &&
2283  PyList_GET_SIZE( oo0 ) && PyList_GET_SIZE( oo1 ) )
2284  {
2285  PyObject *ooo0 = PyList_GetItem( oo0, 0 );
2286  PyObject *ooo1 = PyList_GetItem( oo1, 0 );
2287  if ( ooo0 && ooo1 )
2288  {
2289  // compare multipolygon - multipolygon
2290  if ( sipCanConvertToType( ooo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2291  sipCanConvertToType( ooo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2292  sipCanConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2293  sipCanConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2294  {
2295  QgsMultiPolygonXY *p0;
2296  QgsMultiPolygonXY *p1;
2297  p0 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2298  p1 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2299  if ( sipIsErr )
2300  {
2301  sipReleaseType( p0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state0 );
2302  sipReleaseType( p1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state1 );
2303  }
2304  else
2305  {
2306  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2307  }
2308  }
2309  }
2310  }
2311  }
2312  }
2313  }
2314  }
2315  }
2316  % End
2317 #endif
2318 
2335  QgsGeometry smooth( unsigned int iterations = 1, double offset = 0.25,
2336  double minimumDistance = -1.0, double maxAngle = 180.0 ) const;
2337 
2341  static QgsGeometryEngine *createGeometryEngine( const QgsAbstractGeometry *geometry ) SIP_FACTORY;
2342 
2348  static void convertPointList( const QVector<QgsPointXY> &input, QgsPointSequence &output );
2349 
2355  static void convertPointList( const QgsPointSequence &input, QVector<QgsPointXY> &output );
2356 
2358  operator QVariant() const
2359  {
2360  return QVariant::fromValue( *this );
2361  }
2362 
2363  private:
2364 
2365  QgsGeometryPrivate *d; //implicitly shared data pointer
2366 
2368  mutable QString mLastError;
2369 
2374  void detach();
2375 
2380  void reset( std::unique_ptr< QgsAbstractGeometry > newGeometry );
2381 
2382  static void convertToPolyline( const QgsPointSequence &input, QgsPolylineXY &output );
2383  static void convertPolygon( const QgsPolygon &input, QgsPolygonXY &output );
2384 
2386  QgsGeometry convertToPoint( bool destMultipart ) const;
2388  QgsGeometry convertToLine( bool destMultipart ) const;
2390  QgsGeometry convertToPolygon( bool destMultipart ) const;
2391 
2403  std::unique_ptr< QgsLineString > smoothLine( const QgsLineString &line, unsigned int iterations = 1, double offset = 0.25,
2404  double minimumDistance = -1, double maxAngle = 180.0 ) const;
2405 
2417  std::unique_ptr< QgsPolygon > smoothPolygon( const QgsPolygon &polygon, unsigned int iterations = 1, double offset = 0.25,
2418  double minimumDistance = -1, double maxAngle = 180.0 ) const;
2419 
2420 
2422 
2423 }; // class QgsGeometry
2424 
2426 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsGeometry::ValidityFlags )
2427 
2428 CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsGeometry &geometry );
2431 CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsGeometry &geometry );
2432 
2433 #endif
Geometry engine misses a method implemented or an error occurred in the geometry engine.
Definition: qgsgeometry.h:142
int precision
QgsPointSequence QgsPolyline
Polyline as represented as a vector of points.
Definition: qgsgeometry.h:70
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:151
Java-style iterator for traversal of vertices of a geometry.
static bool isMultiType(Type type)
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:706
The source geometry is not multi.
Definition: qgsgeometry.h:146
Maximum angle between generating radii (lines from arc center to output vertices) ...
Use GEOS validation methods.
Definition: qgsgeometry.h:2006
Error(const QString &m)
Definition: qgsgeometry.h:1956
bool operator==(const QgsGeometry::Error &other) const
Definition: qgsgeometry.h:1988
Java-style iterator for const traversal of parts of a geometry.
Handles storage of information regarding WKB types and their properties.
Definition: qgswkbtypes.h:40
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:74
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:122
Use mitered joins.
Definition: qgsgeometry.h:1112
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
Definition: qgsgeometry.h:80
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:1100
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:213
OperationResult
Success or failure of a geometry operation.
Definition: qgsgeometry.h:134
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:91
Error(const QString &m, const QgsPointXY &p)
Definition: qgsgeometry.h:1960
#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:84
Base class for feedback objects to be used for cancellation of something running in a worker thread...
Definition: qgsfeedback.h:44
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:143
The selected geometry cannot be found.
Definition: qgsgeometry.h:145
No features were selected.
Definition: qgsgeometry.h:140
More than one features were selected.
Definition: qgsgeometry.h:141
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
Utility class for identifying a unique vertex within a geometry.
const double DEFAULT_SEGMENT_EPSILON
Default snapping tolerance for segments.
Definition: qgis.h:598
The input ring crosses existing rings (it is not disjoint)
Definition: qgsgeometry.h:150
#define SIP_SKIP
Definition: qgis_sip.h:126
The part_iterator class provides STL-style iterator for geometry parts.
static GeometryType geometryType(Type type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:812
Use internal QgsGeometryValidator method.
Definition: qgsgeometry.h:2005
#define SIP_TRANSFER
Definition: qgis_sip.h:36
Q_DECLARE_METATYPE(QgsMeshTimeSettings)
The input ring is not closed.
Definition: qgsgeometry.h:148
Square cap (extends past start/end of line by buffer distance)
Definition: qgsgeometry.h:1104
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:1092
QVector< QgsPoint > QgsPointSequence
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:139
#define SIP_PYARGREMOVE
Definition: qgis_sip.h:146
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
Definition: qgsgeometry.h:50
The base geometry on which the operation is done is invalid or empty.
Definition: qgsgeometry.h:138
The input geometry (ring, part, split line, etc.) has not the correct geometry type.
Definition: qgsgeometry.h:139
#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:2003
Buffer to right of line.
Definition: qgsgeometry.h:1095
Class for doing transforms between two map coordinate systems.
ValidityFlag
Validity check flags.
Definition: qgsgeometry.h:365
static QString displayString(Type type)
Returns a display string type for a WKB type, e.g., the geometry name used in WKT geometry representa...
The input ring is not valid.
Definition: qgsgeometry.h:149
#define SIP_THROW(name)
Definition: qgis_sip.h:184
Contains geometry relation and modification algorithms.
Use beveled joins.
Definition: qgsgeometry.h:1113
Transform from source to destination CRS.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
Polygon geometry type.
Definition: qgspolygon.h:31
JoinStyle
Join styles for buffers.
Definition: qgsgeometry.h:1109
Flat cap (in line with start/end of line)
Definition: qgsgeometry.h:1103
Represents a vector layer which manages a vector based data sets.
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:576
double ANALYSIS_EXPORT leftOf(const QgsPoint &thepoint, const QgsPoint *p1, const QgsPoint *p2)
Returns whether &#39;thepoint&#39; is left or right of the line from &#39;p1&#39; to &#39;p2&#39;. Negativ values mean left a...
Definition: MathUtils.cpp:292
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