QGIS API Documentation  3.12.1-BucureČ™ti (121cc00ff0)
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  Q_ENUM( OperationResult )
156 
157 
158  QgsGeometry();
159 
161  QgsGeometry( const QgsGeometry & );
162 
167  QgsGeometry &operator=( QgsGeometry const &rhs ) SIP_SKIP;
168 
174  explicit QgsGeometry( QgsAbstractGeometry *geom SIP_TRANSFER );
175 
181  explicit QgsGeometry( std::unique_ptr< QgsAbstractGeometry > geom ) SIP_SKIP;
182 
183  virtual ~QgsGeometry();
184 
196  const QgsAbstractGeometry *constGet() const;
197 
210  QgsAbstractGeometry *get();
211 
224  void set( QgsAbstractGeometry *geometry SIP_TRANSFER ) SIP_DEPRECATED;
225 
233  bool isNull() const;
234 
236  static QgsGeometry fromWkt( const QString &wkt );
238  static QgsGeometry fromPointXY( const QgsPointXY &point );
240  static QgsGeometry fromMultiPointXY( const QgsMultiPointXY &multipoint );
241 
253  static QgsGeometry fromPolylineXY( const QgsPolylineXY &polyline );
254 
264  static QgsGeometry fromPolyline( const QgsPolyline &polyline );
265 
267  static QgsGeometry fromMultiPolylineXY( const QgsMultiPolylineXY &multiline );
269  static QgsGeometry fromPolygonXY( const QgsPolygonXY &polygon );
271  static QgsGeometry fromMultiPolygonXY( const QgsMultiPolygonXY &multipoly );
273  static QgsGeometry fromRect( const QgsRectangle &rect );
275  static QgsGeometry collectGeometry( const QVector<QgsGeometry> &geometries );
276 
292  static QgsGeometry createWedgeBuffer( const QgsPoint &center, double azimuth, double angularWidth,
293  double outerRadius, double innerRadius = 0 );
294 
300  void fromWkb( unsigned char *wkb, int length ) SIP_SKIP;
301 
306  void fromWkb( const QByteArray &wkb );
307 
312  QgsWkbTypes::Type wkbType() const;
313 
318  QgsWkbTypes::GeometryType type() const;
319 
326  bool isEmpty() const;
327 
329  bool isMultipart() const;
330 
345  bool equals( const QgsGeometry &geometry ) const;
346 
363  bool isGeosEqual( const QgsGeometry & ) const;
364 
367  {
368  FlagAllowSelfTouchingHoles = 1 << 0,
369  };
370  Q_DECLARE_FLAGS( ValidityFlags, ValidityFlag )
371 
372 
379  bool isGeosValid( QgsGeometry::ValidityFlags flags = nullptr ) const;
380 
389  bool isSimple() const;
390 
403  double area() const;
404 
417  double length() const;
418 
426  double distance( const QgsGeometry &geom ) const;
427 
428 #ifndef SIP_RUN
429 
430  // TODO QGIS 4: consider renaming vertices_begin, vertices_end, parts_begin, parts_end, etc
431  // to camelCase
432 
437  QgsAbstractGeometry::vertex_iterator vertices_begin() const;
438 
443  QgsAbstractGeometry::vertex_iterator vertices_end() const;
444 #endif
445 
468  QgsVertexIterator vertices() const;
469 
470 #ifndef SIP_RUN
471 
481 
491 
500  QgsAbstractGeometry::const_part_iterator const_parts_begin() const;
501 
510  QgsAbstractGeometry::const_part_iterator const_parts_end() const;
511 #endif
512 
549  QgsGeometryPartIterator parts();
550 
582  QgsGeometryConstPartIterator constParts() const;
583 
601  double hausdorffDistance( const QgsGeometry &geom ) const;
602 
621  double hausdorffDistanceDensify( const QgsGeometry &geom, double densifyFraction ) const;
622 
623  //TODO QGIS 4.0 - rename beforeVertex to previousVertex, afterVertex to nextVertex
624 
637  QgsPointXY closestVertex( const QgsPointXY &point, int &atVertex SIP_OUT, int &beforeVertex SIP_OUT, int &afterVertex SIP_OUT, double &sqrDist SIP_OUT ) const;
638 
647  double distanceToVertex( int vertex ) const;
648 
656  double angleAtVertex( int vertex ) const;
657 
670  void adjacentVertices( int atVertex, int &beforeVertex SIP_OUT, int &afterVertex SIP_OUT ) const;
671 
684  bool insertVertex( double x, double y, int beforeVertex );
685 
698  bool insertVertex( const QgsPoint &point, int beforeVertex );
699 
707  bool moveVertex( double x, double y, int atVertex );
708 
716  bool moveVertex( const QgsPoint &p, int atVertex );
717 
729  bool deleteVertex( int atVertex );
730 
736  QgsPoint vertexAt( int atVertex ) const;
737 
743  double sqrDistToVertexAt( QgsPointXY &point SIP_IN, int atVertex ) const;
744 
750  QgsGeometry nearestPoint( const QgsGeometry &other ) const;
751 
762  QgsGeometry shortestLine( const QgsGeometry &other ) const;
763 
770  double closestVertexWithContext( const QgsPointXY &point, int &atVertex SIP_OUT ) const;
771 
783  double closestSegmentWithContext( const QgsPointXY &point, QgsPointXY &minDistPoint SIP_OUT, int &afterVertex SIP_OUT, int *leftOf SIP_OUT = nullptr, double epsilon = DEFAULT_SEGMENT_EPSILON ) const;
784 
790  OperationResult addRing( const QVector<QgsPointXY> &ring );
791 
797  OperationResult addRing( QgsCurve *ring SIP_TRANSFER );
798 
805  OperationResult addPart( const QVector<QgsPointXY> &points, QgsWkbTypes::GeometryType geomType = QgsWkbTypes::UnknownGeometry ) SIP_PYNAME( addPointsXY );
806 
814 
822 
828  OperationResult addPart( const QgsGeometry &newPart ) SIP_PYNAME( addPartGeometry );
829 
836  QgsGeometry removeInteriorRings( double minimumAllowedArea = -1 ) const;
837 
842  OperationResult translate( double dx, double dy, double dz = 0.0, double dm = 0.0 );
843 
859 
868  OperationResult transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 );
869 
876  OperationResult rotate( double rotation, const QgsPointXY &center );
877 
887  Q_DECL_DEPRECATED OperationResult splitGeometry( const QVector<QgsPointXY> &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QVector<QgsPointXY> &topologyTestPoints SIP_OUT ) SIP_DEPRECATED;
888 
897  OperationResult splitGeometry( const QgsPointSequence &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QgsPointSequence &topologyTestPoints SIP_OUT );
898 
903  OperationResult reshapeGeometry( const QgsLineString &reshapeLineString );
904 
910  int makeDifferenceInPlace( const QgsGeometry &other ) SIP_SKIP;
911 
919  QgsGeometry makeDifference( const QgsGeometry &other ) const;
920 
925  QgsRectangle boundingBox() const;
926 
934  QgsGeometry orientedMinimumBoundingBox( double &area SIP_OUT, double &angle SIP_OUT, double &width SIP_OUT, double &height SIP_OUT ) const;
935 
941  QgsGeometry orientedMinimumBoundingBox() const SIP_SKIP;
942 
951  QgsGeometry minimalEnclosingCircle( QgsPointXY &center SIP_OUT, double &radius SIP_OUT, unsigned int segments = 36 ) const;
952 
958  QgsGeometry minimalEnclosingCircle( unsigned int segments = 36 ) const SIP_SKIP;
959 
968  QgsGeometry orthogonalize( double tolerance = 1.0E-8, int maxIterations = 1000, double angleThreshold = 15.0 ) const;
969 
982  QgsGeometry snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const;
983 
1004  bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false );
1005 
1015  bool intersects( const QgsRectangle &rectangle ) const;
1016 
1026  bool intersects( const QgsGeometry &geometry ) const;
1027 
1037  bool boundingBoxIntersects( const QgsRectangle &rectangle ) const;
1038 
1048  bool boundingBoxIntersects( const QgsGeometry &geometry ) const;
1049 
1053  bool contains( const QgsPointXY *p ) const;
1054 
1059  bool contains( const QgsGeometry &geometry ) const;
1060 
1065  bool disjoint( const QgsGeometry &geometry ) const;
1066 
1071  bool touches( const QgsGeometry &geometry ) const;
1072 
1077  bool overlaps( const QgsGeometry &geometry ) const;
1078 
1083  bool within( const QgsGeometry &geometry ) const;
1084 
1085 
1090  bool crosses( const QgsGeometry &geometry ) const;
1091 
1094  {
1095  SideLeft = 0,
1097  };
1098  Q_ENUM( BufferSide )
1099 
1100 
1102  {
1103  CapRound = 1,
1106  };
1107  Q_ENUM( EndCapStyle )
1108 
1109 
1111  {
1112  JoinStyleRound = 1,
1115  };
1116  Q_ENUM( JoinStyle )
1117 
1118 
1125  QgsGeometry buffer( double distance, int segments ) const;
1126 
1139  QgsGeometry buffer( double distance, int segments, EndCapStyle endCapStyle, JoinStyle joinStyle, double miterLimit ) const;
1140 
1149  QgsGeometry offsetCurve( double distance, int segments, JoinStyle joinStyle, double miterLimit ) const;
1150 
1166  QgsGeometry singleSidedBuffer( double distance, int segments, BufferSide side,
1167  JoinStyle joinStyle = JoinStyleRound,
1168  double miterLimit = 2.0 ) const;
1169 
1187  QgsGeometry taperedBuffer( double startWidth, double endWidth, int segments ) const;
1188 
1203  QgsGeometry variableWidthBufferByM( int segments ) const;
1204 
1211  QgsGeometry extendLine( double startDistance, double endDistance ) const;
1212 
1214  QgsGeometry simplify( double tolerance ) const;
1215 
1225  QgsGeometry densifyByCount( int extraNodesPerSegment ) const;
1226 
1241  QgsGeometry densifyByDistance( double distance ) const;
1242 
1256  QgsGeometry centroid() const;
1257 
1271  QgsGeometry pointOnSurface() const;
1272 
1285  QgsGeometry poleOfInaccessibility( double precision, double *distanceToBoundary SIP_OUT = nullptr ) const;
1286 
1295  QgsGeometry convexHull() const;
1296 
1312  QgsGeometry voronoiDiagram( const QgsGeometry &extent = QgsGeometry(), double tolerance = 0.0, bool edgesOnly = false ) const;
1313 
1323  QgsGeometry delaunayTriangulation( double tolerance = 0.0, bool edgesOnly = false ) const;
1324 
1344  QgsGeometry subdivide( int maxNodes = 256 ) const;
1345 
1361  QgsGeometry interpolate( double distance ) const;
1362 
1374  double lineLocatePoint( const QgsGeometry &point ) const;
1375 
1385  double interpolateAngle( double distance ) const;
1386 
1395  QgsGeometry intersection( const QgsGeometry &geometry ) const;
1396 
1404  QgsGeometry clipped( const QgsRectangle &rectangle );
1405 
1417  QgsGeometry combine( const QgsGeometry &geometry ) const;
1418 
1427  QgsGeometry mergeLines() const;
1428 
1437  QgsGeometry difference( const QgsGeometry &geometry ) const;
1438 
1447  QgsGeometry symDifference( const QgsGeometry &geometry ) const;
1448 
1450  QgsGeometry extrude( double x, double y );
1451 
1452 #ifndef SIP_RUN
1453 
1470  QVector< QgsPointXY > randomPointsInPolygon( int count, const std::function< bool( const QgsPointXY & ) > &acceptPoint, unsigned long seed = 0, QgsFeedback *feedback = nullptr ) const;
1471 
1485  QVector< QgsPointXY > randomPointsInPolygon( int count, unsigned long seed = 0, QgsFeedback *feedback = nullptr ) const;
1487 #else
1488 
1501  SIP_PYOBJECT randomPointsInPolygon( int count, unsigned long seed = 0 ) const SIP_TYPEHINT( QgsPolylineXY );
1502  % MethodCode
1503  const QgsWkbTypes::GeometryType type = sipCpp->type();
1504  if ( sipCpp->isNull() )
1505  {
1506  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Cannot generate points inside a null geometry." ).toUtf8().constData() );
1507  sipIsErr = 1;
1508  }
1509  else if ( type != QgsWkbTypes::PolygonGeometry )
1510  {
1511  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Cannot generate points inside a %1 geometry. Only Polygon types are permitted." ).arg( QgsWkbTypes::displayString( sipCpp->wkbType() ) ).toUtf8().constData() );
1512  sipIsErr = 1;
1513  }
1514  else
1515  {
1516  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QgsPointXY>" );
1517  sipRes = sipConvertFromNewType( new QVector< QgsPointXY >( sipCpp->randomPointsInPolygon( a0, a1 ) ), qvector_type, Py_None );
1518  }
1519  % End
1520 
1521 
1522 #endif
1523 
1529  QByteArray asWkb() const;
1530 
1536  QString asWkt( int precision = 17 ) const;
1537 
1538 #ifdef SIP_RUN
1539  SIP_PYOBJECT __repr__();
1540  % MethodCode
1541  QString str;
1542  if ( sipCpp->isNull() )
1543  str = QStringLiteral( "<QgsGeometry: null>" );
1544  else
1545  {
1546  QString wkt = sipCpp->asWkt();
1547  if ( wkt.length() > 1000 )
1548  wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
1549  str = QStringLiteral( "<QgsGeometry: %1>" ).arg( wkt );
1550  }
1551  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
1552  % End
1553 #endif
1554 
1558  QString asJson( int precision = 17 ) const;
1559 
1565  virtual json asJsonObject( int precision = 17 ) const SIP_SKIP;
1566 
1574  QgsGeometry convertToType( QgsWkbTypes::GeometryType destType, bool destMultipart = false ) const SIP_FACTORY;
1575 
1576  /* Accessor functions for getting geometry data */
1577 
1578 #ifndef SIP_RUN
1579 
1587  QgsPointXY asPoint() const;
1588 #else
1589 
1599  SIP_PYOBJECT asPoint() const SIP_TYPEHINT( QgsPointXY );
1600  % MethodCode
1601  const QgsWkbTypes::Type type = sipCpp->wkbType();
1602  if ( sipCpp->isNull() )
1603  {
1604  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a point." ).toUtf8().constData() );
1605  sipIsErr = 1;
1606  }
1607  else if ( QgsWkbTypes::flatType( type ) != QgsWkbTypes::Point )
1608  {
1609  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1610  sipIsErr = 1;
1611  }
1612  else
1613  {
1614  sipRes = sipConvertFromNewType( new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
1615  }
1616  % End
1617 #endif
1618 
1619 #ifndef SIP_RUN
1620 
1629  QgsPolylineXY asPolyline() const;
1630 #else
1631 
1642  SIP_PYOBJECT asPolyline() const SIP_TYPEHINT( QgsPolylineXY );
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 polyline." ).toUtf8().constData() );
1648  sipIsErr = 1;
1649  }
1651  {
1652  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() );
1653  sipIsErr = 1;
1654  }
1655  else
1656  {
1657  const sipMappedType *qvector_type = sipFindMappedType( "QVector< QgsPointXY >" );
1658  sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asPolyline() ), qvector_type, Py_None );
1659  }
1660  % End
1661 #endif
1662 
1663 #ifndef SIP_RUN
1664 
1673  QgsPolygonXY asPolygon() const;
1674 #else
1675 
1686  SIP_PYOBJECT asPolygon() const SIP_TYPEHINT( QgsPolygonXY );
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 polygon." ).toUtf8().constData() );
1692  sipIsErr = 1;
1693  }
1695  {
1696  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() );
1697  sipIsErr = 1;
1698  }
1699  else
1700  {
1701  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QgsPointXY>>" );
1702  sipRes = sipConvertFromNewType( new QgsPolygonXY( sipCpp->asPolygon() ), qvector_type, Py_None );
1703  }
1704  % End
1705 #endif
1706 
1707 #ifndef SIP_RUN
1708 
1716  QgsMultiPointXY asMultiPoint() const;
1717 #else
1718 
1728  SIP_PYOBJECT asMultiPoint() const SIP_TYPEHINT( QgsMultiPointXY );
1729  % MethodCode
1730  const QgsWkbTypes::Type type = sipCpp->wkbType();
1731  if ( sipCpp->isNull() )
1732  {
1733  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multipoint." ).toUtf8().constData() );
1734  sipIsErr = 1;
1735  }
1737  {
1738  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a multipoint. Only multipoint types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1739  sipIsErr = 1;
1740  }
1741  else
1742  {
1743  const sipMappedType *qvector_type = sipFindMappedType( "QVector< QgsPointXY >" );
1744  sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asMultiPoint() ), qvector_type, Py_None );
1745  }
1746  % End
1747 #endif
1748 
1749 #ifndef SIP_RUN
1750 
1759  QgsMultiPolylineXY asMultiPolyline() const;
1760 #else
1761 
1772  SIP_PYOBJECT asMultiPolyline() const SIP_TYPEHINT( QgsMultiPolylineXY );
1773  % MethodCode
1774  const QgsWkbTypes::Type type = sipCpp->wkbType();
1775  if ( sipCpp->isNull() )
1776  {
1777  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multilinestring." ).toUtf8().constData() );
1778  sipIsErr = 1;
1779  }
1781  {
1782  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() );
1783  sipIsErr = 1;
1784  }
1785  else
1786  {
1787  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QgsPointXY>>" );
1788  sipRes = sipConvertFromNewType( new QgsMultiPolylineXY( sipCpp->asMultiPolyline() ), qvector_type, Py_None );
1789  }
1790  % End
1791 #endif
1792 
1793 #ifndef SIP_RUN
1794 
1803  QgsMultiPolygonXY asMultiPolygon() const;
1804 #else
1805 
1816  SIP_PYOBJECT asMultiPolygon() const SIP_TYPEHINT( QgsMultiPolygonXY );
1817  % MethodCode
1818  const QgsWkbTypes::Type type = sipCpp->wkbType();
1819  if ( sipCpp->isNull() )
1820  {
1821  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multipolygon." ).toUtf8().constData() );
1822  sipIsErr = 1;
1823  }
1825  {
1826  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() );
1827  sipIsErr = 1;
1828  }
1829  else
1830  {
1831  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QVector<QgsPointXY>>>" );
1832  sipRes = sipConvertFromNewType( new QgsMultiPolygonXY( sipCpp->asMultiPolygon() ), qvector_type, Py_None );
1833  }
1834  % End
1835 #endif
1836 
1841  QVector<QgsGeometry> asGeometryCollection() const;
1842 
1848  QPointF asQPointF() const;
1849 
1856  QPolygonF asQPolygonF() const;
1857 
1864  bool deleteRing( int ringNum, int partNum = 0 );
1865 
1871  bool deletePart( int partNum );
1872 
1881  bool convertToMultiType();
1882 
1892  bool convertToSingleType();
1893 
1903  bool convertGeometryCollectionToSubclass( QgsWkbTypes::GeometryType geomType );
1904 
1915  int avoidIntersections( const QList<QgsVectorLayer *> &avoidIntersectionsLayers,
1916  const QHash<QgsVectorLayer *, QSet<QgsFeatureId> > &ignoreFeatures SIP_PYARGREMOVE = ( QHash<QgsVectorLayer *, QSet<QgsFeatureId> >() ) );
1917 
1936  QgsGeometry makeValid() const;
1937 
1945  QgsGeometry forceRHR() const;
1946 
1950  class CORE_EXPORT Error
1951  {
1952  public:
1954  : mMessage( QStringLiteral( "none" ) )
1955  {}
1956 
1957  explicit Error( const QString &m )
1958  : mMessage( m )
1959  {}
1960 
1961  Error( const QString &m, const QgsPointXY &p )
1962  : mMessage( m )
1963  , mLocation( p )
1964  , mHasLocation( true ) {}
1965 
1969  QString what() const;
1970 
1974  QgsPointXY where() const;
1975 
1979  bool hasWhere() const;
1980 
1981 #ifdef SIP_RUN
1982  SIP_PYOBJECT __repr__();
1983  % MethodCode
1984  QString str = QStringLiteral( "<QgsGeometry.Error: %1>" ).arg( sipCpp->what() );
1985  sipRes = PyUnicode_FromString( str.toUtf8().data() );
1986  % End
1987 #endif
1988 
1989  bool operator==( const QgsGeometry::Error &other ) const
1990  {
1991  return other.mMessage == mMessage && other.mHasLocation == mHasLocation && other.mLocation == mLocation;
1992  }
1993 
1994  private:
1995  QString mMessage;
1996  QgsPointXY mLocation;
1997  bool mHasLocation = false;
1998  };
1999 
2005  {
2008  };
2009 
2018  void validateGeometry( QVector<QgsGeometry::Error> &errors SIP_OUT, ValidationMethod method = ValidatorQgisInternal, QgsGeometry::ValidityFlags flags = nullptr ) const;
2019 
2025  static QgsGeometry unaryUnion( const QVector<QgsGeometry> &geometries );
2026 
2035  static QgsGeometry polygonize( const QVector<QgsGeometry> &geometries );
2036 
2044  void convertToStraightSegment( double tolerance = M_PI / 180., QgsAbstractGeometry::SegmentationToleranceType toleranceType = QgsAbstractGeometry::MaximumAngle );
2045 
2052  bool requiresConversionToStraightSegments() const;
2053 
2059  void mapToPixel( const QgsMapToPixel &mtp );
2060 
2066  void draw( QPainter &p ) const;
2067 
2078  bool vertexIdFromVertexNr( int number, QgsVertexId &id SIP_OUT ) const;
2079 
2091  int vertexNrFromVertexId( QgsVertexId id ) const;
2092 
2100  QString lastError() const;
2101 
2111  void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) SIP_SKIP;
2112 
2127  void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) SIP_SKIP;
2128 
2134  static QgsGeometry fromQPointF( QPointF point );
2135 
2143  static QgsGeometry fromQPolygonF( const QPolygonF &polygon );
2144 
2152  Q_DECL_DEPRECATED static QgsPolylineXY createPolylineFromQPolygonF( const QPolygonF &polygon ) SIP_DEPRECATED;
2153 
2161  Q_DECL_DEPRECATED static QgsPolygonXY createPolygonFromQPolygonF( const QPolygonF &polygon ) SIP_DEPRECATED;
2162 
2163 #ifndef SIP_RUN
2164 
2174  static bool compare( const QgsPolylineXY &p1, const QgsPolylineXY &p2,
2175  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2176 
2186  static bool compare( const QgsPolygonXY &p1, const QgsPolygonXY &p2,
2187  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2188 
2199  static bool compare( const QgsMultiPolygonXY &p1, const QgsMultiPolygonXY &p2,
2200  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2201 #else
2202 
2221  static bool compare( PyObject *obj1, PyObject *obj2, double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2222  % MethodCode
2223  {
2224  sipRes = false;
2225  int state0;
2226  int state1;
2227  int sipIsErr = 0;
2228 
2229  if ( PyList_Check( a0 ) && PyList_Check( a1 ) &&
2230  PyList_GET_SIZE( a0 ) && PyList_GET_SIZE( a1 ) )
2231  {
2232  PyObject *o0 = PyList_GetItem( a0, 0 );
2233  PyObject *o1 = PyList_GetItem( a1, 0 );
2234  if ( o0 && o1 )
2235  {
2236  // compare polyline - polyline
2237  if ( sipCanConvertToType( o0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2238  sipCanConvertToType( o1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2239  sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2240  sipCanConvertToType( a1, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2241  {
2242  QgsPolylineXY *p0;
2243  QgsPolylineXY *p1;
2244  p0 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2245  p1 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a1, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2246  if ( sipIsErr )
2247  {
2248  sipReleaseType( p0, sipType_QVector_0100QgsPointXY, state0 );
2249  sipReleaseType( p1, sipType_QVector_0100QgsPointXY, state1 );
2250  }
2251  else
2252  {
2253  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2254  }
2255  }
2256  else if ( PyList_Check( o0 ) && PyList_Check( o1 ) &&
2257  PyList_GET_SIZE( o0 ) && PyList_GET_SIZE( o1 ) )
2258  {
2259  PyObject *oo0 = PyList_GetItem( o0, 0 );
2260  PyObject *oo1 = PyList_GetItem( o1, 0 );
2261  if ( oo0 && oo1 )
2262  {
2263  // compare polygon - polygon
2264  if ( sipCanConvertToType( oo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2265  sipCanConvertToType( oo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2266  sipCanConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2267  sipCanConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2268  {
2269  QgsPolygonXY *p0;
2270  QgsPolygonXY *p1;
2271  p0 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2272  p1 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2273  if ( sipIsErr )
2274  {
2275  sipReleaseType( p0, sipType_QVector_0600QVector_0100QgsPointXY, state0 );
2276  sipReleaseType( p1, sipType_QVector_0600QVector_0100QgsPointXY, state1 );
2277  }
2278  else
2279  {
2280  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2281  }
2282  }
2283  else if ( PyList_Check( oo0 ) && PyList_Check( oo1 ) &&
2284  PyList_GET_SIZE( oo0 ) && PyList_GET_SIZE( oo1 ) )
2285  {
2286  PyObject *ooo0 = PyList_GetItem( oo0, 0 );
2287  PyObject *ooo1 = PyList_GetItem( oo1, 0 );
2288  if ( ooo0 && ooo1 )
2289  {
2290  // compare multipolygon - multipolygon
2291  if ( sipCanConvertToType( ooo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2292  sipCanConvertToType( ooo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2293  sipCanConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2294  sipCanConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2295  {
2296  QgsMultiPolygonXY *p0;
2297  QgsMultiPolygonXY *p1;
2298  p0 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2299  p1 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2300  if ( sipIsErr )
2301  {
2302  sipReleaseType( p0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state0 );
2303  sipReleaseType( p1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state1 );
2304  }
2305  else
2306  {
2307  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2308  }
2309  }
2310  }
2311  }
2312  }
2313  }
2314  }
2315  }
2316  }
2317  % End
2318 #endif
2319 
2336  QgsGeometry smooth( unsigned int iterations = 1, double offset = 0.25,
2337  double minimumDistance = -1.0, double maxAngle = 180.0 ) const;
2338 
2342  static QgsGeometryEngine *createGeometryEngine( const QgsAbstractGeometry *geometry ) SIP_FACTORY;
2343 
2349  static void convertPointList( const QVector<QgsPointXY> &input, QgsPointSequence &output );
2350 
2356  static void convertPointList( const QgsPointSequence &input, QVector<QgsPointXY> &output );
2357 
2359  operator QVariant() const
2360  {
2361  return QVariant::fromValue( *this );
2362  }
2363 
2364  private:
2365 
2366  QgsGeometryPrivate *d; //implicitly shared data pointer
2367 
2369  mutable QString mLastError;
2370 
2375  void detach();
2376 
2381  void reset( std::unique_ptr< QgsAbstractGeometry > newGeometry );
2382 
2383  static void convertToPolyline( const QgsPointSequence &input, QgsPolylineXY &output );
2384  static void convertPolygon( const QgsPolygon &input, QgsPolygonXY &output );
2385 
2387  QgsGeometry convertToPoint( bool destMultipart ) const;
2389  QgsGeometry convertToLine( bool destMultipart ) const;
2391  QgsGeometry convertToPolygon( bool destMultipart ) const;
2392 
2404  std::unique_ptr< QgsLineString > smoothLine( const QgsLineString &line, unsigned int iterations = 1, double offset = 0.25,
2405  double minimumDistance = -1, double maxAngle = 180.0 ) const;
2406 
2418  std::unique_ptr< QgsPolygon > smoothPolygon( const QgsPolygon &polygon, unsigned int iterations = 1, double offset = 0.25,
2419  double minimumDistance = -1, double maxAngle = 180.0 ) const;
2420 
2421 
2423 
2424 }; // class QgsGeometry
2425 
2427 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsGeometry::ValidityFlags )
2428 
2429 CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsGeometry &geometry );
2432 CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsGeometry &geometry );
2433 
2434 #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:2007
Error(const QString &m)
Definition: qgsgeometry.h:1957
bool operator==(const QgsGeometry::Error &other) const
Definition: qgsgeometry.h:1989
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:1113
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:1101
#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:1961
#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:45
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:692
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:2006
#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:1105
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:1093
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:2004
Buffer to right of line.
Definition: qgsgeometry.h:1096
Class for doing transforms between two map coordinate systems.
ValidityFlag
Validity check flags.
Definition: qgsgeometry.h:366
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:1114
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:1110
Flat cap (in line with start/end of line)
Definition: qgsgeometry.h:1104
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;. Negative values mean left ...
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