QGIS API Documentation  3.9.0-Master (224899f119)
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 <nlohmann/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;
50 
60 typedef QVector<QgsPointXY> QgsPolylineXY;
61 
69 typedef QVector<QgsPoint> QgsPolyline;
70 
72 #ifndef SIP_RUN
73 typedef QVector<QgsPolylineXY> QgsPolygonXY;
74 #else
75 typedef QVector<QVector<QgsPointXY>> QgsPolygonXY;
76 #endif
77 
79 typedef QVector<QgsPointXY> QgsMultiPointXY;
80 
82 #ifndef SIP_RUN
83 typedef QVector<QgsPolylineXY> QgsMultiPolylineXY;
84 #else
85 typedef QVector<QVector<QgsPointXY>> QgsMultiPolylineXY;
86 #endif
87 
89 #ifndef SIP_RUN
90 typedef QVector<QgsPolygonXY> QgsMultiPolygonXY;
91 #else
92 typedef QVector<QVector<QVector<QgsPointXY>>> QgsMultiPolygonXY;
93 #endif
94 
95 class QgsRectangle;
96 
97 class QgsConstWkbPtr;
98 
99 struct QgsGeometryPrivate;
100 
121 class CORE_EXPORT QgsGeometry
122 {
123  Q_GADGET
124  Q_PROPERTY( bool isNull READ isNull )
125  Q_PROPERTY( QgsWkbTypes::GeometryType type READ type )
126 
127  public:
128 
134  {
135  Success = 0,
136  NothingHappened = 1000,
143  /* Add part issues */
146  /* Add ring issues*/
151  /* Split features */
153  };
154 
156  QgsGeometry();
157 
159  QgsGeometry( const QgsGeometry & );
160 
165  QgsGeometry &operator=( QgsGeometry const &rhs ) SIP_SKIP;
166 
172  explicit QgsGeometry( QgsAbstractGeometry *geom SIP_TRANSFER );
173 
179  explicit QgsGeometry( std::unique_ptr< QgsAbstractGeometry > geom ) SIP_SKIP;
180 
181  virtual ~QgsGeometry();
182 
194  const QgsAbstractGeometry *constGet() const;
195 
208  QgsAbstractGeometry *get();
209 
222  void set( QgsAbstractGeometry *geometry SIP_TRANSFER ) SIP_DEPRECATED;
223 
231  bool isNull() const;
232 
234  static QgsGeometry fromWkt( const QString &wkt );
236  static QgsGeometry fromPointXY( const QgsPointXY &point );
238  static QgsGeometry fromMultiPointXY( const QgsMultiPointXY &multipoint );
239 
251  static QgsGeometry fromPolylineXY( const QgsPolylineXY &polyline );
252 
262  static QgsGeometry fromPolyline( const QgsPolyline &polyline );
263 
265  static QgsGeometry fromMultiPolylineXY( const QgsMultiPolylineXY &multiline );
267  static QgsGeometry fromPolygonXY( const QgsPolygonXY &polygon );
269  static QgsGeometry fromMultiPolygonXY( const QgsMultiPolygonXY &multipoly );
271  static QgsGeometry fromRect( const QgsRectangle &rect );
273  static QgsGeometry collectGeometry( const QVector<QgsGeometry> &geometries );
274 
290  static QgsGeometry createWedgeBuffer( const QgsPoint &center, double azimuth, double angularWidth,
291  double outerRadius, double innerRadius = 0 );
292 
298  void fromWkb( unsigned char *wkb, int length ) SIP_SKIP;
299 
304  void fromWkb( const QByteArray &wkb );
305 
310  QgsWkbTypes::Type wkbType() const;
311 
316  QgsWkbTypes::GeometryType type() const;
317 
324  bool isEmpty() const;
325 
327  bool isMultipart() const;
328 
343  bool equals( const QgsGeometry &geometry ) const;
344 
361  bool isGeosEqual( const QgsGeometry & ) const;
362 
365  {
366  FlagAllowSelfTouchingHoles = 1 << 0,
367  };
368  Q_DECLARE_FLAGS( ValidityFlags, ValidityFlag )
369 
370 
377  bool isGeosValid( QgsGeometry::ValidityFlags flags = nullptr ) const;
378 
387  bool isSimple() const;
388 
401  double area() const;
402 
415  double length() const;
416 
424  double distance( const QgsGeometry &geom ) const;
425 
426 #ifndef SIP_RUN
427 
428  // TODO QGIS 4: consider renaming vertices_begin, vertices_end, parts_begin, parts_end, etc
429  // to camelCase
430 
435  QgsAbstractGeometry::vertex_iterator vertices_begin() const;
436 
441  QgsAbstractGeometry::vertex_iterator vertices_end() const;
442 #endif
443 
466  QgsVertexIterator vertices() const;
467 
468 #ifndef SIP_RUN
469 
479 
489 
498  QgsAbstractGeometry::const_part_iterator const_parts_begin() const;
499 
508  QgsAbstractGeometry::const_part_iterator const_parts_end() const;
509 #endif
510 
547  QgsGeometryPartIterator parts();
548 
580  QgsGeometryConstPartIterator constParts() const;
581 
599  double hausdorffDistance( const QgsGeometry &geom ) const;
600 
619  double hausdorffDistanceDensify( const QgsGeometry &geom, double densifyFraction ) const;
620 
621  //TODO QGIS 4.0 - rename beforeVertex to previousVertex, afterVertex to nextVertex
622 
635  QgsPointXY closestVertex( const QgsPointXY &point, int &atVertex SIP_OUT, int &beforeVertex SIP_OUT, int &afterVertex SIP_OUT, double &sqrDist SIP_OUT ) const;
636 
645  double distanceToVertex( int vertex ) const;
646 
654  double angleAtVertex( int vertex ) const;
655 
668  void adjacentVertices( int atVertex, int &beforeVertex SIP_OUT, int &afterVertex SIP_OUT ) const;
669 
682  bool insertVertex( double x, double y, int beforeVertex );
683 
696  bool insertVertex( const QgsPoint &point, int beforeVertex );
697 
705  bool moveVertex( double x, double y, int atVertex );
706 
714  bool moveVertex( const QgsPoint &p, int atVertex );
715 
727  bool deleteVertex( int atVertex );
728 
734  QgsPoint vertexAt( int atVertex ) const;
735 
741  double sqrDistToVertexAt( QgsPointXY &point SIP_IN, int atVertex ) const;
742 
748  QgsGeometry nearestPoint( const QgsGeometry &other ) const;
749 
760  QgsGeometry shortestLine( const QgsGeometry &other ) const;
761 
768  double closestVertexWithContext( const QgsPointXY &point, int &atVertex SIP_OUT ) const;
769 
781  double closestSegmentWithContext( const QgsPointXY &point, QgsPointXY &minDistPoint SIP_OUT, int &afterVertex SIP_OUT, int *leftOf SIP_OUT = nullptr, double epsilon = DEFAULT_SEGMENT_EPSILON ) const;
782 
788  OperationResult addRing( const QVector<QgsPointXY> &ring );
789 
795  OperationResult addRing( QgsCurve *ring SIP_TRANSFER );
796 
803  OperationResult addPart( const QVector<QgsPointXY> &points, QgsWkbTypes::GeometryType geomType = QgsWkbTypes::UnknownGeometry ) SIP_PYNAME( addPointsXY );
804 
812 
820 
826  OperationResult addPart( const QgsGeometry &newPart ) SIP_PYNAME( addPartGeometry );
827 
834  QgsGeometry removeInteriorRings( double minimumAllowedArea = -1 ) const;
835 
840  OperationResult translate( double dx, double dy, double dz = 0.0, double dm = 0.0 );
841 
857 
866  OperationResult transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 );
867 
874  OperationResult rotate( double rotation, const QgsPointXY &center );
875 
884  OperationResult splitGeometry( const QVector<QgsPointXY> &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QVector<QgsPointXY> &topologyTestPoints SIP_OUT );
885 
890  OperationResult reshapeGeometry( const QgsLineString &reshapeLineString );
891 
897  int makeDifferenceInPlace( const QgsGeometry &other ) SIP_SKIP;
898 
906  QgsGeometry makeDifference( const QgsGeometry &other ) const;
907 
912  QgsRectangle boundingBox() const;
913 
921  QgsGeometry orientedMinimumBoundingBox( double &area SIP_OUT, double &angle SIP_OUT, double &width SIP_OUT, double &height SIP_OUT ) const;
922 
928  QgsGeometry orientedMinimumBoundingBox() const SIP_SKIP;
929 
938  QgsGeometry minimalEnclosingCircle( QgsPointXY &center SIP_OUT, double &radius SIP_OUT, unsigned int segments = 36 ) const;
939 
945  QgsGeometry minimalEnclosingCircle( unsigned int segments = 36 ) const SIP_SKIP;
946 
955  QgsGeometry orthogonalize( double tolerance = 1.0E-8, int maxIterations = 1000, double angleThreshold = 15.0 ) const;
956 
969  QgsGeometry snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const;
970 
991  bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false );
992 
1002  bool intersects( const QgsRectangle &rectangle ) const;
1003 
1013  bool intersects( const QgsGeometry &geometry ) const;
1014 
1024  bool boundingBoxIntersects( const QgsRectangle &rectangle ) const;
1025 
1035  bool boundingBoxIntersects( const QgsGeometry &geometry ) const;
1036 
1040  bool contains( const QgsPointXY *p ) const;
1041 
1046  bool contains( const QgsGeometry &geometry ) const;
1047 
1052  bool disjoint( const QgsGeometry &geometry ) const;
1053 
1058  bool touches( const QgsGeometry &geometry ) const;
1059 
1064  bool overlaps( const QgsGeometry &geometry ) const;
1065 
1070  bool within( const QgsGeometry &geometry ) const;
1071 
1072 
1077  bool crosses( const QgsGeometry &geometry ) const;
1078 
1081  {
1082  SideLeft = 0,
1084  };
1085  Q_ENUM( BufferSide )
1086 
1087 
1089  {
1090  CapRound = 1,
1093  };
1094  Q_ENUM( EndCapStyle )
1095 
1096 
1098  {
1099  JoinStyleRound = 1,
1102  };
1103  Q_ENUM( JoinStyle )
1104 
1105 
1112  QgsGeometry buffer( double distance, int segments ) const;
1113 
1126  QgsGeometry buffer( double distance, int segments, EndCapStyle endCapStyle, JoinStyle joinStyle, double miterLimit ) const;
1127 
1136  QgsGeometry offsetCurve( double distance, int segments, JoinStyle joinStyle, double miterLimit ) const;
1137 
1153  QgsGeometry singleSidedBuffer( double distance, int segments, BufferSide side,
1154  JoinStyle joinStyle = JoinStyleRound,
1155  double miterLimit = 2.0 ) const;
1156 
1174  QgsGeometry taperedBuffer( double startWidth, double endWidth, int segments ) const;
1175 
1190  QgsGeometry variableWidthBufferByM( int segments ) const;
1191 
1198  QgsGeometry extendLine( double startDistance, double endDistance ) const;
1199 
1201  QgsGeometry simplify( double tolerance ) const;
1202 
1212  QgsGeometry densifyByCount( int extraNodesPerSegment ) const;
1213 
1228  QgsGeometry densifyByDistance( double distance ) const;
1229 
1243  QgsGeometry centroid() const;
1244 
1258  QgsGeometry pointOnSurface() const;
1259 
1272  QgsGeometry poleOfInaccessibility( double precision, double *distanceToBoundary SIP_OUT = nullptr ) const;
1273 
1282  QgsGeometry convexHull() const;
1283 
1299  QgsGeometry voronoiDiagram( const QgsGeometry &extent = QgsGeometry(), double tolerance = 0.0, bool edgesOnly = false ) const;
1300 
1310  QgsGeometry delaunayTriangulation( double tolerance = 0.0, bool edgesOnly = false ) const;
1311 
1331  QgsGeometry subdivide( int maxNodes = 256 ) const;
1332 
1348  QgsGeometry interpolate( double distance ) const;
1349 
1361  double lineLocatePoint( const QgsGeometry &point ) const;
1362 
1372  double interpolateAngle( double distance ) const;
1373 
1382  QgsGeometry intersection( const QgsGeometry &geometry ) const;
1383 
1391  QgsGeometry clipped( const QgsRectangle &rectangle );
1392 
1404  QgsGeometry combine( const QgsGeometry &geometry ) const;
1405 
1414  QgsGeometry mergeLines() const;
1415 
1424  QgsGeometry difference( const QgsGeometry &geometry ) const;
1425 
1434  QgsGeometry symDifference( const QgsGeometry &geometry ) const;
1435 
1437  QgsGeometry extrude( double x, double y );
1438 
1443  QByteArray asWkb() const;
1444 
1450  QString asWkt( int precision = 17 ) const;
1451 
1452 #ifdef SIP_RUN
1453  SIP_PYOBJECT __repr__();
1454  % MethodCode
1455  QString str;
1456  if ( sipCpp->isNull() )
1457  str = QStringLiteral( "<QgsGeometry: null>" );
1458  else
1459  {
1460  QString wkt = sipCpp->asWkt();
1461  if ( wkt.length() > 1000 )
1462  wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
1463  str = QStringLiteral( "<QgsGeometry: %1>" ).arg( wkt );
1464  }
1465  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
1466  % End
1467 #endif
1468 
1472  QString asJson( int precision = 17 ) const;
1473 
1479  virtual json asJsonObject( int precision = 17 ) const SIP_SKIP;
1480 
1488  QgsGeometry convertToType( QgsWkbTypes::GeometryType destType, bool destMultipart = false ) const SIP_FACTORY;
1489 
1490  /* Accessor functions for getting geometry data */
1491 
1492 #ifndef SIP_RUN
1493 
1501  QgsPointXY asPoint() const;
1502 #else
1503 
1513  SIP_PYOBJECT asPoint() const SIP_TYPEHINT( QgsPointXY );
1514  % MethodCode
1515  const QgsWkbTypes::Type type = sipCpp->wkbType();
1516  if ( sipCpp->isNull() )
1517  {
1518  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a point." ).toUtf8().constData() );
1519  sipIsErr = 1;
1520  }
1521  else if ( QgsWkbTypes::flatType( type ) != QgsWkbTypes::Point )
1522  {
1523  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1524  sipIsErr = 1;
1525  }
1526  else
1527  {
1528  sipRes = sipConvertFromNewType( new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
1529  }
1530  % End
1531 #endif
1532 
1533 #ifndef SIP_RUN
1534 
1543  QgsPolylineXY asPolyline() const;
1544 #else
1545 
1556  SIP_PYOBJECT asPolyline() const SIP_TYPEHINT( QgsPolylineXY );
1557  % MethodCode
1558  const QgsWkbTypes::Type type = sipCpp->wkbType();
1559  if ( sipCpp->isNull() )
1560  {
1561  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a polyline." ).toUtf8().constData() );
1562  sipIsErr = 1;
1563  }
1565  {
1566  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() );
1567  sipIsErr = 1;
1568  }
1569  else
1570  {
1571  const sipMappedType *qvector_type = sipFindMappedType( "QVector< QgsPointXY >" );
1572  sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asPolyline() ), qvector_type, Py_None );
1573  }
1574  % End
1575 #endif
1576 
1577 #ifndef SIP_RUN
1578 
1587  QgsPolygonXY asPolygon() const;
1588 #else
1589 
1600  SIP_PYOBJECT asPolygon() const SIP_TYPEHINT( QgsPolygonXY );
1601  % MethodCode
1602  const QgsWkbTypes::Type type = sipCpp->wkbType();
1603  if ( sipCpp->isNull() )
1604  {
1605  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a polygon." ).toUtf8().constData() );
1606  sipIsErr = 1;
1607  }
1609  {
1610  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() );
1611  sipIsErr = 1;
1612  }
1613  else
1614  {
1615  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QgsPointXY>>" );
1616  sipRes = sipConvertFromNewType( new QgsPolygonXY( sipCpp->asPolygon() ), qvector_type, Py_None );
1617  }
1618  % End
1619 #endif
1620 
1621 #ifndef SIP_RUN
1622 
1630  QgsMultiPointXY asMultiPoint() const;
1631 #else
1632 
1642  SIP_PYOBJECT asMultiPoint() const SIP_TYPEHINT( QgsMultiPointXY );
1643  % MethodCode
1644  const QgsWkbTypes::Type type = sipCpp->wkbType();
1645  if ( sipCpp->isNull() )
1646  {
1647  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multipoint." ).toUtf8().constData() );
1648  sipIsErr = 1;
1649  }
1651  {
1652  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a multipoint. Only multipoint types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1653  sipIsErr = 1;
1654  }
1655  else
1656  {
1657  const sipMappedType *qvector_type = sipFindMappedType( "QVector< QgsPointXY >" );
1658  sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asMultiPoint() ), qvector_type, Py_None );
1659  }
1660  % End
1661 #endif
1662 
1663 #ifndef SIP_RUN
1664 
1673  QgsMultiPolylineXY asMultiPolyline() const;
1674 #else
1675 
1686  SIP_PYOBJECT asMultiPolyline() const SIP_TYPEHINT( QgsMultiPolylineXY );
1687  % MethodCode
1688  const QgsWkbTypes::Type type = sipCpp->wkbType();
1689  if ( sipCpp->isNull() )
1690  {
1691  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multilinestring." ).toUtf8().constData() );
1692  sipIsErr = 1;
1693  }
1695  {
1696  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() );
1697  sipIsErr = 1;
1698  }
1699  else
1700  {
1701  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QgsPointXY>>" );
1702  sipRes = sipConvertFromNewType( new QgsMultiPolylineXY( sipCpp->asMultiPolyline() ), qvector_type, Py_None );
1703  }
1704  % End
1705 #endif
1706 
1707 #ifndef SIP_RUN
1708 
1717  QgsMultiPolygonXY asMultiPolygon() const;
1718 #else
1719 
1730  SIP_PYOBJECT asMultiPolygon() const SIP_TYPEHINT( QgsMultiPolygonXY );
1731  % MethodCode
1732  const QgsWkbTypes::Type type = sipCpp->wkbType();
1733  if ( sipCpp->isNull() )
1734  {
1735  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multipolygon." ).toUtf8().constData() );
1736  sipIsErr = 1;
1737  }
1739  {
1740  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() );
1741  sipIsErr = 1;
1742  }
1743  else
1744  {
1745  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QVector<QgsPointXY>>>" );
1746  sipRes = sipConvertFromNewType( new QgsMultiPolygonXY( sipCpp->asMultiPolygon() ), qvector_type, Py_None );
1747  }
1748  % End
1749 #endif
1750 
1755  QVector<QgsGeometry> asGeometryCollection() const;
1756 
1762  QPointF asQPointF() const;
1763 
1770  QPolygonF asQPolygonF() const;
1771 
1778  bool deleteRing( int ringNum, int partNum = 0 );
1779 
1785  bool deletePart( int partNum );
1786 
1795  bool convertToMultiType();
1796 
1806  bool convertToSingleType();
1807 
1817  bool convertGeometryCollectionToSubclass( QgsWkbTypes::GeometryType geomType );
1818 
1829  int avoidIntersections( const QList<QgsVectorLayer *> &avoidIntersectionsLayers,
1830  const QHash<QgsVectorLayer *, QSet<QgsFeatureId> > &ignoreFeatures SIP_PYARGREMOVE = ( QHash<QgsVectorLayer *, QSet<QgsFeatureId> >() ) );
1831 
1850  QgsGeometry makeValid() const;
1851 
1859  QgsGeometry forceRHR() const;
1860 
1864  class CORE_EXPORT Error
1865  {
1866  public:
1868  : mMessage( QStringLiteral( "none" ) )
1869  {}
1870 
1871  explicit Error( const QString &m )
1872  : mMessage( m )
1873  {}
1874 
1875  Error( const QString &m, const QgsPointXY &p )
1876  : mMessage( m )
1877  , mLocation( p )
1878  , mHasLocation( true ) {}
1879 
1883  QString what() const;
1884 
1888  QgsPointXY where() const;
1889 
1893  bool hasWhere() const;
1894 
1895 #ifdef SIP_RUN
1896  SIP_PYOBJECT __repr__();
1897  % MethodCode
1898  QString str = QStringLiteral( "<QgsGeometry.Error: %1>" ).arg( sipCpp->what() );
1899  sipRes = PyUnicode_FromString( str.toUtf8().data() );
1900  % End
1901 #endif
1902 
1903  bool operator==( const QgsGeometry::Error &other ) const
1904  {
1905  return other.mMessage == mMessage && other.mHasLocation == mHasLocation && other.mLocation == mLocation;
1906  }
1907 
1908  private:
1909  QString mMessage;
1910  QgsPointXY mLocation;
1911  bool mHasLocation = false;
1912  };
1913 
1919  {
1922  };
1923 
1932  void validateGeometry( QVector<QgsGeometry::Error> &errors SIP_OUT, ValidationMethod method = ValidatorQgisInternal, QgsGeometry::ValidityFlags flags = nullptr ) const;
1933 
1939  static QgsGeometry unaryUnion( const QVector<QgsGeometry> &geometries );
1940 
1949  static QgsGeometry polygonize( const QVector<QgsGeometry> &geometries );
1950 
1958  void convertToStraightSegment( double tolerance = M_PI / 180., QgsAbstractGeometry::SegmentationToleranceType toleranceType = QgsAbstractGeometry::MaximumAngle );
1959 
1966  bool requiresConversionToStraightSegments() const;
1967 
1973  void mapToPixel( const QgsMapToPixel &mtp );
1974 
1980  void draw( QPainter &p ) const;
1981 
1992  bool vertexIdFromVertexNr( int number, QgsVertexId &id SIP_OUT ) const;
1993 
2005  int vertexNrFromVertexId( QgsVertexId id ) const;
2006 
2014  QString lastError() const;
2015 
2025  void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) SIP_SKIP;
2026 
2041  void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) SIP_SKIP;
2042 
2048  static QgsGeometry fromQPointF( QPointF point );
2049 
2057  static QgsGeometry fromQPolygonF( const QPolygonF &polygon );
2058 
2065  static QgsPolylineXY createPolylineFromQPolygonF( const QPolygonF &polygon ) SIP_FACTORY;
2066 
2073  static QgsPolygonXY createPolygonFromQPolygonF( const QPolygonF &polygon ) SIP_FACTORY;
2074 
2075 #ifndef SIP_RUN
2076 
2086  static bool compare( const QgsPolylineXY &p1, const QgsPolylineXY &p2,
2087  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2088 
2098  static bool compare( const QgsPolygonXY &p1, const QgsPolygonXY &p2,
2099  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2100 
2111  static bool compare( const QgsMultiPolygonXY &p1, const QgsMultiPolygonXY &p2,
2112  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2113 #else
2114 
2133  static bool compare( PyObject *obj1, PyObject *obj2, double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2134  % MethodCode
2135  {
2136  sipRes = false;
2137  int state0;
2138  int state1;
2139  int sipIsErr = 0;
2140 
2141  if ( PyList_Check( a0 ) && PyList_Check( a1 ) &&
2142  PyList_GET_SIZE( a0 ) && PyList_GET_SIZE( a1 ) )
2143  {
2144  PyObject *o0 = PyList_GetItem( a0, 0 );
2145  PyObject *o1 = PyList_GetItem( a1, 0 );
2146  if ( o0 && o1 )
2147  {
2148  // compare polyline - polyline
2149  if ( sipCanConvertToType( o0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2150  sipCanConvertToType( o1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2151  sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2152  sipCanConvertToType( a1, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2153  {
2154  QgsPolylineXY *p0;
2155  QgsPolylineXY *p1;
2156  p0 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2157  p1 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a1, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2158  if ( sipIsErr )
2159  {
2160  sipReleaseType( p0, sipType_QVector_0100QgsPointXY, state0 );
2161  sipReleaseType( p1, sipType_QVector_0100QgsPointXY, state1 );
2162  }
2163  else
2164  {
2165  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2166  }
2167  }
2168  else if ( PyList_Check( o0 ) && PyList_Check( o1 ) &&
2169  PyList_GET_SIZE( o0 ) && PyList_GET_SIZE( o1 ) )
2170  {
2171  PyObject *oo0 = PyList_GetItem( o0, 0 );
2172  PyObject *oo1 = PyList_GetItem( o1, 0 );
2173  if ( oo0 && oo1 )
2174  {
2175  // compare polygon - polygon
2176  if ( sipCanConvertToType( oo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2177  sipCanConvertToType( oo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2178  sipCanConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2179  sipCanConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2180  {
2181  QgsPolygonXY *p0;
2182  QgsPolygonXY *p1;
2183  p0 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2184  p1 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2185  if ( sipIsErr )
2186  {
2187  sipReleaseType( p0, sipType_QVector_0600QVector_0100QgsPointXY, state0 );
2188  sipReleaseType( p1, sipType_QVector_0600QVector_0100QgsPointXY, state1 );
2189  }
2190  else
2191  {
2192  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2193  }
2194  }
2195  else if ( PyList_Check( oo0 ) && PyList_Check( oo1 ) &&
2196  PyList_GET_SIZE( oo0 ) && PyList_GET_SIZE( oo1 ) )
2197  {
2198  PyObject *ooo0 = PyList_GetItem( oo0, 0 );
2199  PyObject *ooo1 = PyList_GetItem( oo1, 0 );
2200  if ( ooo0 && ooo1 )
2201  {
2202  // compare multipolygon - multipolygon
2203  if ( sipCanConvertToType( ooo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2204  sipCanConvertToType( ooo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2205  sipCanConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2206  sipCanConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2207  {
2208  QgsMultiPolygonXY *p0;
2209  QgsMultiPolygonXY *p1;
2210  p0 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2211  p1 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2212  if ( sipIsErr )
2213  {
2214  sipReleaseType( p0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state0 );
2215  sipReleaseType( p1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state1 );
2216  }
2217  else
2218  {
2219  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2220  }
2221  }
2222  }
2223  }
2224  }
2225  }
2226  }
2227  }
2228  }
2229  % End
2230 #endif
2231 
2248  QgsGeometry smooth( unsigned int iterations = 1, double offset = 0.25,
2249  double minimumDistance = -1.0, double maxAngle = 180.0 ) const;
2250 
2254  static QgsGeometryEngine *createGeometryEngine( const QgsAbstractGeometry *geometry ) SIP_FACTORY;
2255 
2261  static void convertPointList( const QVector<QgsPointXY> &input, QgsPointSequence &output );
2262 
2268  static void convertPointList( const QgsPointSequence &input, QVector<QgsPointXY> &output );
2269 
2271  operator QVariant() const
2272  {
2273  return QVariant::fromValue( *this );
2274  }
2275 
2276  private:
2277 
2278  QgsGeometryPrivate *d; //implicitly shared data pointer
2279 
2281  mutable QString mLastError;
2282 
2287  void detach();
2288 
2293  void reset( std::unique_ptr< QgsAbstractGeometry > newGeometry );
2294 
2295  static void convertToPolyline( const QgsPointSequence &input, QgsPolylineXY &output );
2296  static void convertPolygon( const QgsPolygon &input, QgsPolygonXY &output );
2297 
2299  QgsGeometry convertToPoint( bool destMultipart ) const;
2301  QgsGeometry convertToLine( bool destMultipart ) const;
2303  QgsGeometry convertToPolygon( bool destMultipart ) const;
2304 
2316  std::unique_ptr< QgsLineString > smoothLine( const QgsLineString &line, unsigned int iterations = 1, double offset = 0.25,
2317  double minimumDistance = -1, double maxAngle = 180.0 ) const;
2318 
2330  std::unique_ptr< QgsPolygon > smoothPolygon( const QgsPolygon &polygon, unsigned int iterations = 1, double offset = 0.25,
2331  double minimumDistance = -1, double maxAngle = 180.0 ) const;
2332 
2333 
2335 
2336 }; // class QgsGeometry
2337 
2339 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsGeometry::ValidityFlags )
2340 
2341 CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsGeometry &geometry );
2344 CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsGeometry &geometry );
2345 
2346 #endif
Geometry engine misses a method implemented or an error occurred in the geometry engine.
Definition: qgsgeometry.h:141
int precision
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:150
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:145
Maximum angle between generating radii (lines from arc center to output vertices) ...
Use GEOS validation methods.
Definition: qgsgeometry.h:1921
Error(const QString &m)
Definition: qgsgeometry.h:1871
bool operator==(const QgsGeometry::Error &other) const
Definition: qgsgeometry.h:1903
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
QVector< QgsPoint > QgsPolyline
Polyline as represented as a vector of points.
Definition: qgsgeometry.h:69
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:73
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:121
Use mitered joins.
Definition: qgsgeometry.h:1100
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
Definition: qgsgeometry.h:79
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:1088
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:213
OperationResult
Success or failure of a geometry operation.
Definition: qgsgeometry.h:133
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:90
Error(const QString &m, const QgsPointXY &p)
Definition: qgsgeometry.h:1875
#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:83
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:142
The selected geometry cannot be found.
Definition: qgsgeometry.h:144
No features were selected.
Definition: qgsgeometry.h:139
More than one features were selected.
Definition: qgsgeometry.h:140
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:583
The input ring crosses existing rings (it is not disjoint)
Definition: qgsgeometry.h:149
#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:1920
#define SIP_TRANSFER
Definition: qgis_sip.h:36
Q_DECLARE_METATYPE(QgsMeshTimeSettings)
The input ring is not closed.
Definition: qgsgeometry.h:147
Square cap (extends past start/end of line by buffer distance)
Definition: qgsgeometry.h:1092
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:1080
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:49
The base geometry on which the operation is done is invalid or empty.
Definition: qgsgeometry.h:137
The input geometry (ring, part, split line, etc.) has not the correct geometry type.
Definition: qgsgeometry.h:138
#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:1918
Buffer to right of line.
Definition: qgsgeometry.h:1083
Class for doing transforms between two map coordinate systems.
ValidityFlag
Validity check flags.
Definition: qgsgeometry.h:364
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:148
#define SIP_THROW(name)
Definition: qgis_sip.h:184
Contains geometry relation and modification algorithms.
Use beveled joins.
Definition: qgsgeometry.h:1101
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:1097
Flat cap (in line with start/end of line)
Definition: qgsgeometry.h:1091
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