QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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>
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 
111 class CORE_EXPORT QgsGeometry
112 {
113  Q_GADGET
114  Q_PROPERTY( bool isNull READ isNull )
115  Q_PROPERTY( QgsWkbTypes::GeometryType type READ type )
116 
117  public:
118 
124  {
125  Success = 0,
126  NothingHappened = 1000,
133  /* Add part issues */
136  /* Add ring issues*/
141  /* Split features */
143  };
144 
146  QgsGeometry();
147 
149  QgsGeometry( const QgsGeometry & );
150 
155  QgsGeometry &operator=( QgsGeometry const &rhs ) SIP_SKIP;
156 
162  explicit QgsGeometry( QgsAbstractGeometry *geom SIP_TRANSFER );
163 
169  explicit QgsGeometry( std::unique_ptr< QgsAbstractGeometry > geom ) SIP_SKIP;
170 
171  virtual ~QgsGeometry();
172 
184  const QgsAbstractGeometry *constGet() const;
185 
198  QgsAbstractGeometry *get();
199 
212  void set( QgsAbstractGeometry *geometry SIP_TRANSFER ) SIP_DEPRECATED;
213 
221  bool isNull() const;
222 
224  static QgsGeometry fromWkt( const QString &wkt );
226  static QgsGeometry fromPointXY( const QgsPointXY &point );
228  static QgsGeometry fromMultiPointXY( const QgsMultiPointXY &multipoint );
229 
241  static QgsGeometry fromPolylineXY( const QgsPolylineXY &polyline );
242 
252  static QgsGeometry fromPolyline( const QgsPolyline &polyline );
253 
255  static QgsGeometry fromMultiPolylineXY( const QgsMultiPolylineXY &multiline );
257  static QgsGeometry fromPolygonXY( const QgsPolygonXY &polygon );
259  static QgsGeometry fromMultiPolygonXY( const QgsMultiPolygonXY &multipoly );
261  static QgsGeometry fromRect( const QgsRectangle &rect );
263  static QgsGeometry collectGeometry( const QVector<QgsGeometry> &geometries );
264 
280  static QgsGeometry createWedgeBuffer( const QgsPoint &center, double azimuth, double angularWidth,
281  double outerRadius, double innerRadius = 0 );
282 
288  void fromWkb( unsigned char *wkb, int length ) SIP_SKIP;
289 
294  void fromWkb( const QByteArray &wkb );
295 
300  QgsWkbTypes::Type wkbType() const;
301 
306  QgsWkbTypes::GeometryType type() const;
307 
314  bool isEmpty() const;
315 
317  bool isMultipart() const;
318 
333  bool equals( const QgsGeometry &geometry ) const;
334 
351  bool isGeosEqual( const QgsGeometry & ) const;
352 
355  {
356  FlagAllowSelfTouchingHoles = 1 << 0,
357  };
358  Q_DECLARE_FLAGS( ValidityFlags, ValidityFlag )
359 
360 
367  bool isGeosValid( QgsGeometry::ValidityFlags flags = nullptr ) const;
368 
377  bool isSimple() const;
378 
383  double area() const;
384 
389  double length() const;
390 
397  double distance( const QgsGeometry &geom ) const;
398 
399 #ifndef SIP_RUN
400 
401  // TODO QGIS 4: consider renaming vertices_begin, vertices_end, parts_begin, parts_end, etc
402  // to camelCase
403 
408  QgsAbstractGeometry::vertex_iterator vertices_begin() const;
409 
414  QgsAbstractGeometry::vertex_iterator vertices_end() const;
415 #endif
416 
439  QgsVertexIterator vertices() const;
440 
441 #ifndef SIP_RUN
442 
452 
462 
471  QgsAbstractGeometry::const_part_iterator const_parts_begin() const;
472 
481  QgsAbstractGeometry::const_part_iterator const_parts_end() const;
482 #endif
483 
520  QgsGeometryPartIterator parts();
521 
553  QgsGeometryConstPartIterator constParts() const;
554 
572  double hausdorffDistance( const QgsGeometry &geom ) const;
573 
592  double hausdorffDistanceDensify( const QgsGeometry &geom, double densifyFraction ) const;
593 
594  //TODO QGIS 4.0 - rename beforeVertex to previousVertex, afterVertex to nextVertex
595 
608  QgsPointXY closestVertex( const QgsPointXY &point, int &atVertex SIP_OUT, int &beforeVertex SIP_OUT, int &afterVertex SIP_OUT, double &sqrDist SIP_OUT ) const;
609 
616  double distanceToVertex( int vertex ) const;
617 
625  double angleAtVertex( int vertex ) const;
626 
639  void adjacentVertices( int atVertex, int &beforeVertex SIP_OUT, int &afterVertex SIP_OUT ) const;
640 
653  bool insertVertex( double x, double y, int beforeVertex );
654 
667  bool insertVertex( const QgsPoint &point, int beforeVertex );
668 
676  bool moveVertex( double x, double y, int atVertex );
677 
685  bool moveVertex( const QgsPoint &p, int atVertex );
686 
698  bool deleteVertex( int atVertex );
699 
705  QgsPoint vertexAt( int atVertex ) const;
706 
712  double sqrDistToVertexAt( QgsPointXY &point SIP_IN, int atVertex ) const;
713 
719  QgsGeometry nearestPoint( const QgsGeometry &other ) const;
720 
726  QgsGeometry shortestLine( const QgsGeometry &other ) const;
727 
734  double closestVertexWithContext( const QgsPointXY &point, int &atVertex SIP_OUT ) const;
735 
747  double closestSegmentWithContext( const QgsPointXY &point, QgsPointXY &minDistPoint SIP_OUT, int &afterVertex SIP_OUT, int *leftOf SIP_OUT = nullptr, double epsilon = DEFAULT_SEGMENT_EPSILON ) const;
748 
754  OperationResult addRing( const QVector<QgsPointXY> &ring );
755 
761  OperationResult addRing( QgsCurve *ring SIP_TRANSFER );
762 
769  OperationResult addPart( const QVector<QgsPointXY> &points, QgsWkbTypes::GeometryType geomType = QgsWkbTypes::UnknownGeometry ) SIP_PYNAME( addPointsXY );
770 
778 
786 
792  OperationResult addPart( const QgsGeometry &newPart ) SIP_PYNAME( addPartGeometry );
793 
800  QgsGeometry removeInteriorRings( double minimumAllowedArea = -1 ) const;
801 
806  OperationResult translate( double dx, double dy, double dz = 0.0, double dm = 0.0 );
807 
823 
832  OperationResult transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 );
833 
840  OperationResult rotate( double rotation, const QgsPointXY &center );
841 
850  OperationResult splitGeometry( const QVector<QgsPointXY> &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QVector<QgsPointXY> &topologyTestPoints SIP_OUT );
851 
856  OperationResult reshapeGeometry( const QgsLineString &reshapeLineString );
857 
863  int makeDifferenceInPlace( const QgsGeometry &other ) SIP_SKIP;
864 
872  QgsGeometry makeDifference( const QgsGeometry &other ) const;
873 
878  QgsRectangle boundingBox() const;
879 
887  QgsGeometry orientedMinimumBoundingBox( double &area SIP_OUT, double &angle SIP_OUT, double &width SIP_OUT, double &height SIP_OUT ) const;
888 
894  QgsGeometry orientedMinimumBoundingBox() const SIP_SKIP;
895 
904  QgsGeometry minimalEnclosingCircle( QgsPointXY &center SIP_OUT, double &radius SIP_OUT, unsigned int segments = 36 ) const;
905 
911  QgsGeometry minimalEnclosingCircle( unsigned int segments = 36 ) const SIP_SKIP;
912 
921  QgsGeometry orthogonalize( double tolerance = 1.0E-8, int maxIterations = 1000, double angleThreshold = 15.0 ) const;
922 
935  QgsGeometry snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const;
936 
957  bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false );
958 
968  bool intersects( const QgsRectangle &rectangle ) const;
969 
979  bool intersects( const QgsGeometry &geometry ) const;
980 
990  bool boundingBoxIntersects( const QgsRectangle &rectangle ) const;
991 
1001  bool boundingBoxIntersects( const QgsGeometry &geometry ) const;
1002 
1004  bool contains( const QgsPointXY *p ) const;
1005 
1010  bool contains( const QgsGeometry &geometry ) const;
1011 
1016  bool disjoint( const QgsGeometry &geometry ) const;
1017 
1022  bool touches( const QgsGeometry &geometry ) const;
1023 
1028  bool overlaps( const QgsGeometry &geometry ) const;
1029 
1034  bool within( const QgsGeometry &geometry ) const;
1035 
1040  bool crosses( const QgsGeometry &geometry ) const;
1041 
1044  {
1045  SideLeft = 0,
1047  };
1048  Q_ENUM( BufferSide )
1049 
1050 
1052  {
1053  CapRound = 1,
1056  };
1057  Q_ENUM( EndCapStyle )
1058 
1059 
1061  {
1062  JoinStyleRound = 1,
1065  };
1066  Q_ENUM( JoinStyle )
1067 
1068 
1075  QgsGeometry buffer( double distance, int segments ) const;
1076 
1089  QgsGeometry buffer( double distance, int segments, EndCapStyle endCapStyle, JoinStyle joinStyle, double miterLimit ) const;
1090 
1099  QgsGeometry offsetCurve( double distance, int segments, JoinStyle joinStyle, double miterLimit ) const;
1100 
1116  QgsGeometry singleSidedBuffer( double distance, int segments, BufferSide side,
1117  JoinStyle joinStyle = JoinStyleRound,
1118  double miterLimit = 2.0 ) const;
1119 
1137  QgsGeometry taperedBuffer( double startWidth, double endWidth, int segments ) const;
1138 
1153  QgsGeometry variableWidthBufferByM( int segments ) const;
1154 
1161  QgsGeometry extendLine( double startDistance, double endDistance ) const;
1162 
1164  QgsGeometry simplify( double tolerance ) const;
1165 
1175  QgsGeometry densifyByCount( int extraNodesPerSegment ) const;
1176 
1191  QgsGeometry densifyByDistance( double distance ) const;
1192 
1206  QgsGeometry centroid() const;
1207 
1221  QgsGeometry pointOnSurface() const;
1222 
1235  QgsGeometry poleOfInaccessibility( double precision, double *distanceToBoundary SIP_OUT = nullptr ) const;
1236 
1245  QgsGeometry convexHull() const;
1246 
1262  QgsGeometry voronoiDiagram( const QgsGeometry &extent = QgsGeometry(), double tolerance = 0.0, bool edgesOnly = false ) const;
1263 
1273  QgsGeometry delaunayTriangulation( double tolerance = 0.0, bool edgesOnly = false ) const;
1274 
1294  QgsGeometry subdivide( int maxNodes = 256 ) const;
1295 
1311  QgsGeometry interpolate( double distance ) const;
1312 
1324  double lineLocatePoint( const QgsGeometry &point ) const;
1325 
1335  double interpolateAngle( double distance ) const;
1336 
1345  QgsGeometry intersection( const QgsGeometry &geometry ) const;
1346 
1354  QgsGeometry clipped( const QgsRectangle &rectangle );
1355 
1367  QgsGeometry combine( const QgsGeometry &geometry ) const;
1368 
1377  QgsGeometry mergeLines() const;
1378 
1387  QgsGeometry difference( const QgsGeometry &geometry ) const;
1388 
1397  QgsGeometry symDifference( const QgsGeometry &geometry ) const;
1398 
1400  QgsGeometry extrude( double x, double y );
1401 
1406  QByteArray asWkb() const;
1407 
1413  QString asWkt( int precision = 17 ) const;
1414 
1415 #ifdef SIP_RUN
1416  SIP_PYOBJECT __repr__();
1417  % MethodCode
1418  QString str;
1419  if ( sipCpp->isNull() )
1420  str = QStringLiteral( "<QgsGeometry: null>" );
1421  else
1422  {
1423  QString wkt = sipCpp->asWkt();
1424  if ( wkt.length() > 1000 )
1425  wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
1426  str = QStringLiteral( "<QgsGeometry: %1>" ).arg( wkt );
1427  }
1428  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
1429  % End
1430 #endif
1431 
1435  QString asJson( int precision = 17 ) const;
1436 
1442  virtual json asJsonObject( int precision = 17 ) const SIP_SKIP;
1443 
1451  QgsGeometry convertToType( QgsWkbTypes::GeometryType destType, bool destMultipart = false ) const SIP_FACTORY;
1452 
1453  /* Accessor functions for getting geometry data */
1454 
1455 #ifndef SIP_RUN
1456 
1464  QgsPointXY asPoint() const;
1465 #else
1466 
1476  SIP_PYOBJECT asPoint() const SIP_TYPEHINT( QgsPointXY );
1477  % MethodCode
1478  const QgsWkbTypes::Type type = sipCpp->wkbType();
1479  if ( sipCpp->isNull() )
1480  {
1481  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a point." ).toUtf8().constData() );
1482  sipIsErr = 1;
1483  }
1484  else if ( QgsWkbTypes::flatType( type ) != QgsWkbTypes::Point )
1485  {
1486  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1487  sipIsErr = 1;
1488  }
1489  else
1490  {
1491  sipRes = sipConvertFromNewType( new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
1492  }
1493  % End
1494 #endif
1495 
1496 #ifndef SIP_RUN
1497 
1506  QgsPolylineXY asPolyline() const;
1507 #else
1508 
1519  SIP_PYOBJECT asPolyline() const SIP_TYPEHINT( QgsPolylineXY );
1520  % MethodCode
1521  const QgsWkbTypes::Type type = sipCpp->wkbType();
1522  if ( sipCpp->isNull() )
1523  {
1524  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a polyline." ).toUtf8().constData() );
1525  sipIsErr = 1;
1526  }
1528  {
1529  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() );
1530  sipIsErr = 1;
1531  }
1532  else
1533  {
1534  const sipMappedType *qvector_type = sipFindMappedType( "QVector< QgsPointXY >" );
1535  sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asPolyline() ), qvector_type, Py_None );
1536  }
1537  % End
1538 #endif
1539 
1540 #ifndef SIP_RUN
1541 
1550  QgsPolygonXY asPolygon() const;
1551 #else
1552 
1563  SIP_PYOBJECT asPolygon() const SIP_TYPEHINT( QgsPolygonXY );
1564  % MethodCode
1565  const QgsWkbTypes::Type type = sipCpp->wkbType();
1566  if ( sipCpp->isNull() )
1567  {
1568  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a polygon." ).toUtf8().constData() );
1569  sipIsErr = 1;
1570  }
1572  {
1573  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() );
1574  sipIsErr = 1;
1575  }
1576  else
1577  {
1578  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QgsPointXY>>" );
1579  sipRes = sipConvertFromNewType( new QgsPolygonXY( sipCpp->asPolygon() ), qvector_type, Py_None );
1580  }
1581  % End
1582 #endif
1583 
1584 #ifndef SIP_RUN
1585 
1593  QgsMultiPointXY asMultiPoint() const;
1594 #else
1595 
1605  SIP_PYOBJECT asMultiPoint() const SIP_TYPEHINT( QgsMultiPointXY );
1606  % MethodCode
1607  const QgsWkbTypes::Type type = sipCpp->wkbType();
1608  if ( sipCpp->isNull() )
1609  {
1610  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multipoint." ).toUtf8().constData() );
1611  sipIsErr = 1;
1612  }
1614  {
1615  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a multipoint. Only multipoint types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1616  sipIsErr = 1;
1617  }
1618  else
1619  {
1620  const sipMappedType *qvector_type = sipFindMappedType( "QVector< QgsPointXY >" );
1621  sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asMultiPoint() ), qvector_type, Py_None );
1622  }
1623  % End
1624 #endif
1625 
1626 #ifndef SIP_RUN
1627 
1636  QgsMultiPolylineXY asMultiPolyline() const;
1637 #else
1638 
1649  SIP_PYOBJECT asMultiPolyline() const SIP_TYPEHINT( QgsMultiPolylineXY );
1650  % MethodCode
1651  const QgsWkbTypes::Type type = sipCpp->wkbType();
1652  if ( sipCpp->isNull() )
1653  {
1654  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multilinestring." ).toUtf8().constData() );
1655  sipIsErr = 1;
1656  }
1658  {
1659  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() );
1660  sipIsErr = 1;
1661  }
1662  else
1663  {
1664  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QgsPointXY>>" );
1665  sipRes = sipConvertFromNewType( new QgsMultiPolylineXY( sipCpp->asMultiPolyline() ), qvector_type, Py_None );
1666  }
1667  % End
1668 #endif
1669 
1670 #ifndef SIP_RUN
1671 
1680  QgsMultiPolygonXY asMultiPolygon() const;
1681 #else
1682 
1693  SIP_PYOBJECT asMultiPolygon() const SIP_TYPEHINT( QgsMultiPolygonXY );
1694  % MethodCode
1695  const QgsWkbTypes::Type type = sipCpp->wkbType();
1696  if ( sipCpp->isNull() )
1697  {
1698  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multipolygon." ).toUtf8().constData() );
1699  sipIsErr = 1;
1700  }
1702  {
1703  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() );
1704  sipIsErr = 1;
1705  }
1706  else
1707  {
1708  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QVector<QgsPointXY>>>" );
1709  sipRes = sipConvertFromNewType( new QgsMultiPolygonXY( sipCpp->asMultiPolygon() ), qvector_type, Py_None );
1710  }
1711  % End
1712 #endif
1713 
1718  QVector<QgsGeometry> asGeometryCollection() const;
1719 
1725  QPointF asQPointF() const;
1726 
1733  QPolygonF asQPolygonF() const;
1734 
1741  bool deleteRing( int ringNum, int partNum = 0 );
1742 
1748  bool deletePart( int partNum );
1749 
1758  bool convertToMultiType();
1759 
1769  bool convertToSingleType();
1770 
1780  bool convertGeometryCollectionToSubclass( QgsWkbTypes::GeometryType geomType );
1781 
1792  int avoidIntersections( const QList<QgsVectorLayer *> &avoidIntersectionsLayers,
1793  const QHash<QgsVectorLayer *, QSet<QgsFeatureId> > &ignoreFeatures SIP_PYARGREMOVE = ( QHash<QgsVectorLayer *, QSet<QgsFeatureId> >() ) );
1794 
1813  QgsGeometry makeValid() const;
1814 
1822  QgsGeometry forceRHR() const;
1823 
1827  class CORE_EXPORT Error
1828  {
1829  public:
1831  : mMessage( QStringLiteral( "none" ) )
1832  {}
1833 
1834  explicit Error( const QString &m )
1835  : mMessage( m )
1836  {}
1837 
1838  Error( const QString &m, const QgsPointXY &p )
1839  : mMessage( m )
1840  , mLocation( p )
1841  , mHasLocation( true ) {}
1842 
1846  QString what() const;
1847 
1851  QgsPointXY where() const;
1852 
1856  bool hasWhere() const;
1857 
1858 #ifdef SIP_RUN
1859  SIP_PYOBJECT __repr__();
1860  % MethodCode
1861  QString str = QStringLiteral( "<QgsGeometry.Error: %1>" ).arg( sipCpp->what() );
1862  sipRes = PyUnicode_FromString( str.toUtf8().data() );
1863  % End
1864 #endif
1865 
1866  bool operator==( const QgsGeometry::Error &other ) const
1867  {
1868  return other.mMessage == mMessage && other.mHasLocation == mHasLocation && other.mLocation == mLocation;
1869  }
1870 
1871  private:
1872  QString mMessage;
1873  QgsPointXY mLocation;
1874  bool mHasLocation = false;
1875  };
1876 
1882  {
1885  };
1886 
1895  void validateGeometry( QVector<QgsGeometry::Error> &errors SIP_OUT, ValidationMethod method = ValidatorQgisInternal, QgsGeometry::ValidityFlags flags = nullptr ) const;
1896 
1902  static QgsGeometry unaryUnion( const QVector<QgsGeometry> &geometries );
1903 
1912  static QgsGeometry polygonize( const QVector<QgsGeometry> &geometries );
1913 
1921  void convertToStraightSegment( double tolerance = M_PI / 180., QgsAbstractGeometry::SegmentationToleranceType toleranceType = QgsAbstractGeometry::MaximumAngle );
1922 
1929  bool requiresConversionToStraightSegments() const;
1930 
1936  void mapToPixel( const QgsMapToPixel &mtp );
1937 
1943  void draw( QPainter &p ) const;
1944 
1955  bool vertexIdFromVertexNr( int number, QgsVertexId &id SIP_OUT ) const;
1956 
1968  int vertexNrFromVertexId( QgsVertexId id ) const;
1969 
1977  QString lastError() const;
1978 
1988  void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) SIP_SKIP;
1989 
2004  void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) SIP_SKIP;
2005 
2011  static QgsGeometry fromQPointF( QPointF point );
2012 
2020  static QgsGeometry fromQPolygonF( const QPolygonF &polygon );
2021 
2028  static QgsPolylineXY createPolylineFromQPolygonF( const QPolygonF &polygon ) SIP_FACTORY;
2029 
2036  static QgsPolygonXY createPolygonFromQPolygonF( const QPolygonF &polygon ) SIP_FACTORY;
2037 
2038 #ifndef SIP_RUN
2039 
2049  static bool compare( const QgsPolylineXY &p1, const QgsPolylineXY &p2,
2050  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2051 
2061  static bool compare( const QgsPolygonXY &p1, const QgsPolygonXY &p2,
2062  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2063 
2074  static bool compare( const QgsMultiPolygonXY &p1, const QgsMultiPolygonXY &p2,
2075  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2076 #else
2077 
2096  static bool compare( PyObject *obj1, PyObject *obj2, double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2097  % MethodCode
2098  {
2099  sipRes = false;
2100  int state0;
2101  int state1;
2102  int sipIsErr = 0;
2103 
2104  if ( PyList_Check( a0 ) && PyList_Check( a1 ) &&
2105  PyList_GET_SIZE( a0 ) && PyList_GET_SIZE( a1 ) )
2106  {
2107  PyObject *o0 = PyList_GetItem( a0, 0 );
2108  PyObject *o1 = PyList_GetItem( a1, 0 );
2109  if ( o0 && o1 )
2110  {
2111  // compare polyline - polyline
2112  if ( sipCanConvertToType( o0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2113  sipCanConvertToType( o1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2114  sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2115  sipCanConvertToType( a1, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2116  {
2117  QgsPolylineXY *p0;
2118  QgsPolylineXY *p1;
2119  p0 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2120  p1 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a1, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2121  if ( sipIsErr )
2122  {
2123  sipReleaseType( p0, sipType_QVector_0100QgsPointXY, state0 );
2124  sipReleaseType( p1, sipType_QVector_0100QgsPointXY, state1 );
2125  }
2126  else
2127  {
2128  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2129  }
2130  }
2131  else if ( PyList_Check( o0 ) && PyList_Check( o1 ) &&
2132  PyList_GET_SIZE( o0 ) && PyList_GET_SIZE( o1 ) )
2133  {
2134  PyObject *oo0 = PyList_GetItem( o0, 0 );
2135  PyObject *oo1 = PyList_GetItem( o1, 0 );
2136  if ( oo0 && oo1 )
2137  {
2138  // compare polygon - polygon
2139  if ( sipCanConvertToType( oo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2140  sipCanConvertToType( oo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2141  sipCanConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2142  sipCanConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2143  {
2144  QgsPolygonXY *p0;
2145  QgsPolygonXY *p1;
2146  p0 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2147  p1 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2148  if ( sipIsErr )
2149  {
2150  sipReleaseType( p0, sipType_QVector_0600QVector_0100QgsPointXY, state0 );
2151  sipReleaseType( p1, sipType_QVector_0600QVector_0100QgsPointXY, state1 );
2152  }
2153  else
2154  {
2155  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2156  }
2157  }
2158  else if ( PyList_Check( oo0 ) && PyList_Check( oo1 ) &&
2159  PyList_GET_SIZE( oo0 ) && PyList_GET_SIZE( oo1 ) )
2160  {
2161  PyObject *ooo0 = PyList_GetItem( oo0, 0 );
2162  PyObject *ooo1 = PyList_GetItem( oo1, 0 );
2163  if ( ooo0 && ooo1 )
2164  {
2165  // compare multipolygon - multipolygon
2166  if ( sipCanConvertToType( ooo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2167  sipCanConvertToType( ooo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2168  sipCanConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2169  sipCanConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2170  {
2171  QgsMultiPolygonXY *p0;
2172  QgsMultiPolygonXY *p1;
2173  p0 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2174  p1 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2175  if ( sipIsErr )
2176  {
2177  sipReleaseType( p0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state0 );
2178  sipReleaseType( p1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state1 );
2179  }
2180  else
2181  {
2182  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2183  }
2184  }
2185  }
2186  }
2187  }
2188  }
2189  }
2190  }
2191  }
2192  % End
2193 #endif
2194 
2211  QgsGeometry smooth( unsigned int iterations = 1, double offset = 0.25,
2212  double minimumDistance = -1.0, double maxAngle = 180.0 ) const;
2213 
2217  static QgsGeometryEngine *createGeometryEngine( const QgsAbstractGeometry *geometry ) SIP_FACTORY;
2218 
2224  static void convertPointList( const QVector<QgsPointXY> &input, QgsPointSequence &output );
2225 
2231  static void convertPointList( const QgsPointSequence &input, QVector<QgsPointXY> &output );
2232 
2234  operator QVariant() const
2235  {
2236  return QVariant::fromValue( *this );
2237  }
2238 
2239  private:
2240 
2241  QgsGeometryPrivate *d; //implicitly shared data pointer
2242 
2244  mutable QString mLastError;
2245 
2250  void detach();
2251 
2256  void reset( std::unique_ptr< QgsAbstractGeometry > newGeometry );
2257 
2258  static void convertToPolyline( const QgsPointSequence &input, QgsPolylineXY &output );
2259  static void convertPolygon( const QgsPolygon &input, QgsPolygonXY &output );
2260 
2262  QgsGeometry convertToPoint( bool destMultipart ) const;
2264  QgsGeometry convertToLine( bool destMultipart ) const;
2266  QgsGeometry convertToPolygon( bool destMultipart ) const;
2267 
2279  std::unique_ptr< QgsLineString > smoothLine( const QgsLineString &line, unsigned int iterations = 1, double offset = 0.25,
2280  double minimumDistance = -1, double maxAngle = 180.0 ) const;
2281 
2293  std::unique_ptr< QgsPolygon > smoothPolygon( const QgsPolygon &polygon, unsigned int iterations = 1, double offset = 0.25,
2294  double minimumDistance = -1, double maxAngle = 180.0 ) const;
2295 
2296 
2298 
2299 }; // class QgsGeometry
2300 
2302 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsGeometry::ValidityFlags )
2303 
2304 CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsGeometry &geometry );
2307 CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsGeometry &geometry );
2308 
2309 #endif
Geometry engine misses a method implemented or an error occurred in the geometry engine.
Definition: qgsgeometry.h:131
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:140
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:560
The source geometry is not multi.
Definition: qgsgeometry.h:135
Maximum angle between generating radii (lines from arc center to output vertices) ...
Use GEOS validation methods.
Definition: qgsgeometry.h:1884
Error(const QString &m)
Definition: qgsgeometry.h:1834
bool operator==(const QgsGeometry::Error &other) const
Definition: qgsgeometry.h:1866
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:111
Use mitered joins.
Definition: qgsgeometry.h:1063
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:1051
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:206
OperationResult
Success or failure of a geometry operation.
Definition: qgsgeometry.h:123
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:1838
#define SIP_IN
Definition: qgis_sip.h:56
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:132
The selected geometry cannot be found.
Definition: qgsgeometry.h:134
No features were selected.
Definition: qgsgeometry.h:129
More than one features were selected.
Definition: qgsgeometry.h:130
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:573
The input ring crosses existing rings (it is not disjoint)
Definition: qgsgeometry.h:139
#define SIP_SKIP
Definition: qgis_sip.h:119
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:666
Use internal QgsGeometryValidator method.
Definition: qgsgeometry.h:1883
#define SIP_TRANSFER
Definition: qgis_sip.h:36
Q_DECLARE_METATYPE(QgsMeshTimeSettings)
The input ring is not closed.
Definition: qgsgeometry.h:137
Square cap (extends past start/end of line by buffer distance)
Definition: qgsgeometry.h:1055
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
#define SIP_FACTORY
Definition: qgis_sip.h:69
Abstract base class for all geometries.
The vertex_iterator class provides STL-style iterator for vertices.
#define SIP_DEPRECATED
Definition: qgis_sip.h:99
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.
nlohmann::json json
Definition: qgsjsonutils.h:27
BufferSide
Side of line to buffer.
Definition: qgsgeometry.h:1043
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:139
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
Definition: qgsgeometry.h:49
nlohmann::json json
Definition: qgsgeometry.h:41
The base geometry on which the operation is done is invalid or empty.
Definition: qgsgeometry.h:127
The input geometry (ring, part, split line, etc.) has not the correct geometry type.
Definition: qgsgeometry.h:128
#define SIP_OUT
Definition: qgis_sip.h:51
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:1881
Buffer to right of line.
Definition: qgsgeometry.h:1046
Class for doing transforms between two map coordinate systems.
ValidityFlag
Validity check flags.
Definition: qgsgeometry.h:354
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:138
#define SIP_THROW(name)
Definition: qgis_sip.h:177
Contains geometry relation and modification algorithms.
Use beveled joins.
Definition: qgsgeometry.h:1064
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:1060
Flat cap (in line with start/end of line)
Definition: qgsgeometry.h:1054
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:430
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:74