QGIS API Documentation  3.6.0-Noosa (5873452)
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 <QSet>
23 #include <QString>
24 #include <QVector>
25 
26 #include <climits>
27 #include <limits>
28 #include <memory>
29 
30 #include "qgis_core.h"
31 #include "qgis_sip.h"
32 
33 #include "qgsabstractgeometry.h"
34 #include "qgspointxy.h"
35 #include "qgspoint.h"
36 #include "qgsfeatureid.h"
37 
38 
39 class QgsGeometryEngine;
40 class QgsVectorLayer;
41 class QgsMapToPixel;
42 class QPainter;
43 class QgsPolygon;
45 
55 typedef QVector<QgsPointXY> QgsPolylineXY;
56 
64 typedef QVector<QgsPoint> QgsPolyline;
65 
67 #ifndef SIP_RUN
68 typedef QVector<QgsPolylineXY> QgsPolygonXY;
69 #else
70 typedef QVector<QVector<QgsPointXY>> QgsPolygonXY;
71 #endif
72 
74 typedef QVector<QgsPointXY> QgsMultiPointXY;
75 
77 #ifndef SIP_RUN
78 typedef QVector<QgsPolylineXY> QgsMultiPolylineXY;
79 #else
80 typedef QVector<QVector<QgsPointXY>> QgsMultiPolylineXY;
81 #endif
82 
84 #ifndef SIP_RUN
85 typedef QVector<QgsPolygonXY> QgsMultiPolygonXY;
86 #else
87 typedef QVector<QVector<QVector<QgsPointXY>>> QgsMultiPolygonXY;
88 #endif
89 
90 class QgsRectangle;
91 
92 class QgsConstWkbPtr;
93 
94 struct QgsGeometryPrivate;
95 
106 class CORE_EXPORT QgsGeometry
107 {
108  Q_GADGET
109  Q_PROPERTY( bool isNull READ isNull )
110  Q_PROPERTY( QgsWkbTypes::GeometryType type READ type )
111 
112  public:
113 
119  {
120  Success = 0,
121  NothingHappened = 1000,
128  /* Add part issues */
131  /* Add ring issues*/
136  /* Split features */
138  };
139 
141  QgsGeometry();
142 
144  QgsGeometry( const QgsGeometry & );
145 
150  QgsGeometry &operator=( QgsGeometry const &rhs ) SIP_SKIP;
151 
157  explicit QgsGeometry( QgsAbstractGeometry *geom SIP_TRANSFER );
158 
164  explicit QgsGeometry( std::unique_ptr< QgsAbstractGeometry > geom ) SIP_SKIP;
165 
166  ~QgsGeometry();
167 
179  const QgsAbstractGeometry *constGet() const;
180 
193  QgsAbstractGeometry *get();
194 
207  void set( QgsAbstractGeometry *geometry SIP_TRANSFER ) SIP_DEPRECATED;
208 
216  bool isNull() const;
217 
219  static QgsGeometry fromWkt( const QString &wkt );
221  static QgsGeometry fromPointXY( const QgsPointXY &point );
223  static QgsGeometry fromMultiPointXY( const QgsMultiPointXY &multipoint );
224 
236  static QgsGeometry fromPolylineXY( const QgsPolylineXY &polyline );
237 
247  static QgsGeometry fromPolyline( const QgsPolyline &polyline );
248 
250  static QgsGeometry fromMultiPolylineXY( const QgsMultiPolylineXY &multiline );
252  static QgsGeometry fromPolygonXY( const QgsPolygonXY &polygon );
254  static QgsGeometry fromMultiPolygonXY( const QgsMultiPolygonXY &multipoly );
256  static QgsGeometry fromRect( const QgsRectangle &rect );
258  static QgsGeometry collectGeometry( const QVector<QgsGeometry> &geometries );
259 
275  static QgsGeometry createWedgeBuffer( const QgsPoint &center, double azimuth, double angularWidth,
276  double outerRadius, double innerRadius = 0 );
277 
283  void fromWkb( unsigned char *wkb, int length ) SIP_SKIP;
284 
289  void fromWkb( const QByteArray &wkb );
290 
295  QgsWkbTypes::Type wkbType() const;
296 
301  QgsWkbTypes::GeometryType type() const;
302 
309  bool isEmpty() const;
310 
312  bool isMultipart() const;
313 
328  bool equals( const QgsGeometry &geometry ) const;
329 
346  bool isGeosEqual( const QgsGeometry & ) const;
347 
352  bool isGeosValid() const;
353 
362  bool isSimple() const;
363 
368  double area() const;
369 
374  double length() const;
375 
382  double distance( const QgsGeometry &geom ) const;
383 
384 #ifndef SIP_RUN
385 
386  // TODO QGIS 4: consider renaming vertices_begin, vertices_end, parts_begin, parts_end, etc
387  // to camelCase
388 
393  QgsAbstractGeometry::vertex_iterator vertices_begin() const;
394 
399  QgsAbstractGeometry::vertex_iterator vertices_end() const;
400 #endif
401 
424  QgsVertexIterator vertices() const;
425 
426 #ifndef SIP_RUN
427 
437 
447 
456  QgsAbstractGeometry::const_part_iterator const_parts_begin() const;
457 
466  QgsAbstractGeometry::const_part_iterator const_parts_end() const;
467 #endif
468 
505  QgsGeometryPartIterator parts();
506 
538  QgsGeometryConstPartIterator constParts() const;
539 
557  double hausdorffDistance( const QgsGeometry &geom ) const;
558 
577  double hausdorffDistanceDensify( const QgsGeometry &geom, double densifyFraction ) const;
578 
579  //TODO QGIS 4.0 - rename beforeVertex to previousVertex, afterVertex to nextVertex
580 
593  QgsPointXY closestVertex( const QgsPointXY &point, int &atVertex SIP_OUT, int &beforeVertex SIP_OUT, int &afterVertex SIP_OUT, double &sqrDist SIP_OUT ) const;
594 
601  double distanceToVertex( int vertex ) const;
602 
610  double angleAtVertex( int vertex ) const;
611 
624  void adjacentVertices( int atVertex, int &beforeVertex SIP_OUT, int &afterVertex SIP_OUT ) const;
625 
638  bool insertVertex( double x, double y, int beforeVertex );
639 
652  bool insertVertex( const QgsPoint &point, int beforeVertex );
653 
661  bool moveVertex( double x, double y, int atVertex );
662 
670  bool moveVertex( const QgsPoint &p, int atVertex );
671 
683  bool deleteVertex( int atVertex );
684 
690  QgsPoint vertexAt( int atVertex ) const;
691 
697  double sqrDistToVertexAt( QgsPointXY &point SIP_IN, int atVertex ) const;
698 
704  QgsGeometry nearestPoint( const QgsGeometry &other ) const;
705 
711  QgsGeometry shortestLine( const QgsGeometry &other ) const;
712 
719  double closestVertexWithContext( const QgsPointXY &point, int &atVertex SIP_OUT ) const;
720 
732  double closestSegmentWithContext( const QgsPointXY &point, QgsPointXY &minDistPoint SIP_OUT, int &afterVertex SIP_OUT, int *leftOf SIP_OUT = nullptr, double epsilon = DEFAULT_SEGMENT_EPSILON ) const;
733 
739  OperationResult addRing( const QVector<QgsPointXY> &ring );
740 
746  OperationResult addRing( QgsCurve *ring SIP_TRANSFER );
747 
754  OperationResult addPart( const QVector<QgsPointXY> &points, QgsWkbTypes::GeometryType geomType = QgsWkbTypes::UnknownGeometry ) SIP_PYNAME( addPointsXY );
755 
763 
771 
777  OperationResult addPart( const QgsGeometry &newPart ) SIP_PYNAME( addPartGeometry );
778 
785  QgsGeometry removeInteriorRings( double minimumAllowedArea = -1 ) const;
786 
791  OperationResult translate( double dx, double dy, double dz = 0.0, double dm = 0.0 );
792 
808 
817  OperationResult transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 );
818 
825  OperationResult rotate( double rotation, const QgsPointXY &center );
826 
835  OperationResult splitGeometry( const QVector<QgsPointXY> &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QVector<QgsPointXY> &topologyTestPoints SIP_OUT );
836 
841  OperationResult reshapeGeometry( const QgsLineString &reshapeLineString );
842 
848  int makeDifferenceInPlace( const QgsGeometry &other ) SIP_SKIP;
849 
857  QgsGeometry makeDifference( const QgsGeometry &other ) const;
858 
863  QgsRectangle boundingBox() const;
864 
872  QgsGeometry orientedMinimumBoundingBox( double &area SIP_OUT, double &angle SIP_OUT, double &width SIP_OUT, double &height SIP_OUT ) const;
873 
879  QgsGeometry orientedMinimumBoundingBox() const SIP_SKIP;
880 
889  QgsGeometry minimalEnclosingCircle( QgsPointXY &center SIP_OUT, double &radius SIP_OUT, unsigned int segments = 36 ) const;
890 
896  QgsGeometry minimalEnclosingCircle( unsigned int segments = 36 ) const SIP_SKIP;
897 
906  QgsGeometry orthogonalize( double tolerance = 1.0E-8, int maxIterations = 1000, double angleThreshold = 15.0 ) const;
907 
920  QgsGeometry snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const;
921 
942  bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false );
943 
953  bool intersects( const QgsRectangle &rectangle ) const;
954 
964  bool intersects( const QgsGeometry &geometry ) const;
965 
975  bool boundingBoxIntersects( const QgsRectangle &rectangle ) const;
976 
986  bool boundingBoxIntersects( const QgsGeometry &geometry ) const;
987 
989  bool contains( const QgsPointXY *p ) const;
990 
995  bool contains( const QgsGeometry &geometry ) const;
996 
1001  bool disjoint( const QgsGeometry &geometry ) const;
1002 
1007  bool touches( const QgsGeometry &geometry ) const;
1008 
1013  bool overlaps( const QgsGeometry &geometry ) const;
1014 
1019  bool within( const QgsGeometry &geometry ) const;
1020 
1025  bool crosses( const QgsGeometry &geometry ) const;
1026 
1029  {
1030  SideLeft = 0,
1032  };
1033  Q_ENUM( BufferSide )
1034 
1035 
1037  {
1038  CapRound = 1,
1041  };
1042  Q_ENUM( EndCapStyle )
1043 
1044 
1046  {
1047  JoinStyleRound = 1,
1050  };
1051  Q_ENUM( JoinStyle )
1052 
1053 
1060  QgsGeometry buffer( double distance, int segments ) const;
1061 
1074  QgsGeometry buffer( double distance, int segments, EndCapStyle endCapStyle, JoinStyle joinStyle, double miterLimit ) const;
1075 
1084  QgsGeometry offsetCurve( double distance, int segments, JoinStyle joinStyle, double miterLimit ) const;
1085 
1101  QgsGeometry singleSidedBuffer( double distance, int segments, BufferSide side,
1102  JoinStyle joinStyle = JoinStyleRound,
1103  double miterLimit = 2.0 ) const;
1104 
1122  QgsGeometry taperedBuffer( double startWidth, double endWidth, int segments ) const;
1123 
1138  QgsGeometry variableWidthBufferByM( int segments ) const;
1139 
1146  QgsGeometry extendLine( double startDistance, double endDistance ) const;
1147 
1149  QgsGeometry simplify( double tolerance ) const;
1150 
1160  QgsGeometry densifyByCount( int extraNodesPerSegment ) const;
1161 
1176  QgsGeometry densifyByDistance( double distance ) const;
1177 
1191  QgsGeometry centroid() const;
1192 
1206  QgsGeometry pointOnSurface() const;
1207 
1220  QgsGeometry poleOfInaccessibility( double precision, double *distanceToBoundary SIP_OUT = nullptr ) const;
1221 
1230  QgsGeometry convexHull() const;
1231 
1247  QgsGeometry voronoiDiagram( const QgsGeometry &extent = QgsGeometry(), double tolerance = 0.0, bool edgesOnly = false ) const;
1248 
1258  QgsGeometry delaunayTriangulation( double tolerance = 0.0, bool edgesOnly = false ) const;
1259 
1279  QgsGeometry subdivide( int maxNodes = 256 ) const;
1280 
1296  QgsGeometry interpolate( double distance ) const;
1297 
1309  double lineLocatePoint( const QgsGeometry &point ) const;
1310 
1320  double interpolateAngle( double distance ) const;
1321 
1330  QgsGeometry intersection( const QgsGeometry &geometry ) const;
1331 
1339  QgsGeometry clipped( const QgsRectangle &rectangle );
1340 
1352  QgsGeometry combine( const QgsGeometry &geometry ) const;
1353 
1362  QgsGeometry mergeLines() const;
1363 
1372  QgsGeometry difference( const QgsGeometry &geometry ) const;
1373 
1382  QgsGeometry symDifference( const QgsGeometry &geometry ) const;
1383 
1385  QgsGeometry extrude( double x, double y );
1386 
1391  QByteArray asWkb() const;
1392 
1398  QString asWkt( int precision = 17 ) const;
1399 
1400 #ifdef SIP_RUN
1401  SIP_PYOBJECT __repr__();
1402  % MethodCode
1403  QString str;
1404  if ( sipCpp->isNull() )
1405  str = QStringLiteral( "<QgsGeometry: null>" );
1406  else
1407  {
1408  QString wkt = sipCpp->asWkt();
1409  if ( wkt.length() > 1000 )
1410  wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
1411  str = QStringLiteral( "<QgsGeometry: %1>" ).arg( wkt );
1412  }
1413  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
1414  % End
1415 #endif
1416 
1420  QString asJson( int precision = 17 ) const;
1421 
1429  QgsGeometry convertToType( QgsWkbTypes::GeometryType destType, bool destMultipart = false ) const SIP_FACTORY;
1430 
1431  /* Accessor functions for getting geometry data */
1432 
1433 #ifndef SIP_RUN
1434 
1442  QgsPointXY asPoint() const;
1443 #else
1444 
1454  SIP_PYOBJECT asPoint() const SIP_TYPEHINT( QgsPointXY );
1455  % MethodCode
1456  const QgsWkbTypes::Type type = sipCpp->wkbType();
1457  if ( sipCpp->isNull() )
1458  {
1459  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a point." ).toUtf8().constData() );
1460  sipIsErr = 1;
1461  }
1462  else if ( QgsWkbTypes::flatType( type ) != QgsWkbTypes::Point )
1463  {
1464  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1465  sipIsErr = 1;
1466  }
1467  else
1468  {
1469  sipRes = sipConvertFromNewType( new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
1470  }
1471  % End
1472 #endif
1473 
1474 #ifndef SIP_RUN
1475 
1484  QgsPolylineXY asPolyline() const;
1485 #else
1486 
1497  SIP_PYOBJECT asPolyline() const SIP_TYPEHINT( QgsPolylineXY );
1498  % MethodCode
1499  const QgsWkbTypes::Type type = sipCpp->wkbType();
1500  if ( sipCpp->isNull() )
1501  {
1502  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a polyline." ).toUtf8().constData() );
1503  sipIsErr = 1;
1504  }
1506  {
1507  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() );
1508  sipIsErr = 1;
1509  }
1510  else
1511  {
1512  const sipMappedType *qvector_type = sipFindMappedType( "QVector< QgsPointXY >" );
1513  sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asPolyline() ), qvector_type, Py_None );
1514  }
1515  % End
1516 #endif
1517 
1518 #ifndef SIP_RUN
1519 
1528  QgsPolygonXY asPolygon() const;
1529 #else
1530 
1541  SIP_PYOBJECT asPolygon() const SIP_TYPEHINT( QgsPolygonXY );
1542  % MethodCode
1543  const QgsWkbTypes::Type type = sipCpp->wkbType();
1544  if ( sipCpp->isNull() )
1545  {
1546  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a polygon." ).toUtf8().constData() );
1547  sipIsErr = 1;
1548  }
1550  {
1551  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() );
1552  sipIsErr = 1;
1553  }
1554  else
1555  {
1556  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QgsPointXY>>" );
1557  sipRes = sipConvertFromNewType( new QgsPolygonXY( sipCpp->asPolygon() ), qvector_type, Py_None );
1558  }
1559  % End
1560 #endif
1561 
1562 #ifndef SIP_RUN
1563 
1571  QgsMultiPointXY asMultiPoint() const;
1572 #else
1573 
1583  SIP_PYOBJECT asMultiPoint() const SIP_TYPEHINT( QgsMultiPointXY );
1584  % MethodCode
1585  const QgsWkbTypes::Type type = sipCpp->wkbType();
1586  if ( sipCpp->isNull() )
1587  {
1588  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multipoint." ).toUtf8().constData() );
1589  sipIsErr = 1;
1590  }
1592  {
1593  PyErr_SetString( PyExc_TypeError, QStringLiteral( "%1 geometry cannot be converted to a multipoint. Only multipoint types are permitted." ).arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1594  sipIsErr = 1;
1595  }
1596  else
1597  {
1598  const sipMappedType *qvector_type = sipFindMappedType( "QVector< QgsPointXY >" );
1599  sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asMultiPoint() ), qvector_type, Py_None );
1600  }
1601  % End
1602 #endif
1603 
1604 #ifndef SIP_RUN
1605 
1614  QgsMultiPolylineXY asMultiPolyline() const;
1615 #else
1616 
1627  SIP_PYOBJECT asMultiPolyline() const SIP_TYPEHINT( QgsMultiPolylineXY );
1628  % MethodCode
1629  const QgsWkbTypes::Type type = sipCpp->wkbType();
1630  if ( sipCpp->isNull() )
1631  {
1632  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multilinestring." ).toUtf8().constData() );
1633  sipIsErr = 1;
1634  }
1636  {
1637  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() );
1638  sipIsErr = 1;
1639  }
1640  else
1641  {
1642  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QgsPointXY>>" );
1643  sipRes = sipConvertFromNewType( new QgsMultiPolylineXY( sipCpp->asMultiPolyline() ), qvector_type, Py_None );
1644  }
1645  % End
1646 #endif
1647 
1648 #ifndef SIP_RUN
1649 
1658  QgsMultiPolygonXY asMultiPolygon() const;
1659 #else
1660 
1671  SIP_PYOBJECT asMultiPolygon() const SIP_TYPEHINT( QgsMultiPolygonXY );
1672  % MethodCode
1673  const QgsWkbTypes::Type type = sipCpp->wkbType();
1674  if ( sipCpp->isNull() )
1675  {
1676  PyErr_SetString( PyExc_ValueError, QStringLiteral( "Null geometry cannot be converted to a multipolygon." ).toUtf8().constData() );
1677  sipIsErr = 1;
1678  }
1680  {
1681  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() );
1682  sipIsErr = 1;
1683  }
1684  else
1685  {
1686  const sipMappedType *qvector_type = sipFindMappedType( "QVector<QVector<QVector<QgsPointXY>>>" );
1687  sipRes = sipConvertFromNewType( new QgsMultiPolygonXY( sipCpp->asMultiPolygon() ), qvector_type, Py_None );
1688  }
1689  % End
1690 #endif
1691 
1696  QVector<QgsGeometry> asGeometryCollection() const;
1697 
1703  QPointF asQPointF() const;
1704 
1711  QPolygonF asQPolygonF() const;
1712 
1719  bool deleteRing( int ringNum, int partNum = 0 );
1720 
1726  bool deletePart( int partNum );
1727 
1736  bool convertToMultiType();
1737 
1747  bool convertToSingleType();
1748 
1758  bool convertGeometryCollectionToSubclass( QgsWkbTypes::GeometryType geomType );
1759 
1770  int avoidIntersections( const QList<QgsVectorLayer *> &avoidIntersectionsLayers,
1771  const QHash<QgsVectorLayer *, QSet<QgsFeatureId> > &ignoreFeatures SIP_PYARGREMOVE = ( QHash<QgsVectorLayer *, QSet<QgsFeatureId> >() ) );
1772 
1791  QgsGeometry makeValid() const;
1792 
1800  QgsGeometry forceRHR() const;
1801 
1805  class CORE_EXPORT Error
1806  {
1807  public:
1809  : mMessage( QStringLiteral( "none" ) )
1810  {}
1811 
1812  explicit Error( const QString &m )
1813  : mMessage( m )
1814  {}
1815 
1816  Error( const QString &m, const QgsPointXY &p )
1817  : mMessage( m )
1818  , mLocation( p )
1819  , mHasLocation( true ) {}
1820 
1824  QString what() const;
1825 
1829  QgsPointXY where() const;
1830 
1834  bool hasWhere() const;
1835 
1836 #ifdef SIP_RUN
1837  SIP_PYOBJECT __repr__();
1838  % MethodCode
1839  QString str = QStringLiteral( "<QgsGeometry.Error: %1>" ).arg( sipCpp->what() );
1840  sipRes = PyUnicode_FromString( str.toUtf8().data() );
1841  % End
1842 #endif
1843 
1844  private:
1845  QString mMessage;
1846  QgsPointXY mLocation;
1847  bool mHasLocation = false;
1848  };
1849 
1855  {
1858  };
1859 
1866  void validateGeometry( QVector<QgsGeometry::Error> &errors SIP_OUT, ValidationMethod method = ValidatorQgisInternal ) const;
1867 
1873  static QgsGeometry unaryUnion( const QVector<QgsGeometry> &geometries );
1874 
1883  static QgsGeometry polygonize( const QVector<QgsGeometry> &geometries );
1884 
1892  void convertToStraightSegment( double tolerance = M_PI / 180., QgsAbstractGeometry::SegmentationToleranceType toleranceType = QgsAbstractGeometry::MaximumAngle );
1893 
1900  bool requiresConversionToStraightSegments() const;
1901 
1907  void mapToPixel( const QgsMapToPixel &mtp );
1908 
1914  void draw( QPainter &p ) const;
1915 
1926  bool vertexIdFromVertexNr( int number, QgsVertexId &id SIP_OUT ) const;
1927 
1939  int vertexNrFromVertexId( QgsVertexId id ) const;
1940 
1948  QString lastError() const;
1949 
1959  void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) SIP_SKIP;
1960 
1975  void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) SIP_SKIP;
1976 
1982  static QgsGeometry fromQPointF( QPointF point );
1983 
1991  static QgsGeometry fromQPolygonF( const QPolygonF &polygon );
1992 
1999  static QgsPolylineXY createPolylineFromQPolygonF( const QPolygonF &polygon ) SIP_FACTORY;
2000 
2007  static QgsPolygonXY createPolygonFromQPolygonF( const QPolygonF &polygon ) SIP_FACTORY;
2008 
2009 #ifndef SIP_RUN
2010 
2020  static bool compare( const QgsPolylineXY &p1, const QgsPolylineXY &p2,
2021  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2022 
2032  static bool compare( const QgsPolygonXY &p1, const QgsPolygonXY &p2,
2033  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2034 
2045  static bool compare( const QgsMultiPolygonXY &p1, const QgsMultiPolygonXY &p2,
2046  double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2047 #else
2048 
2067  static bool compare( PyObject *obj1, PyObject *obj2, double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2068  % MethodCode
2069  {
2070  sipRes = false;
2071  int state0;
2072  int state1;
2073  int sipIsErr = 0;
2074 
2075  if ( PyList_Check( a0 ) && PyList_Check( a1 ) &&
2076  PyList_GET_SIZE( a0 ) && PyList_GET_SIZE( a1 ) )
2077  {
2078  PyObject *o0 = PyList_GetItem( a0, 0 );
2079  PyObject *o1 = PyList_GetItem( a1, 0 );
2080  if ( o0 && o1 )
2081  {
2082  // compare polyline - polyline
2083  if ( sipCanConvertToType( o0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2084  sipCanConvertToType( o1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2085  sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2086  sipCanConvertToType( a1, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2087  {
2088  QgsPolylineXY *p0;
2089  QgsPolylineXY *p1;
2090  p0 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2091  p1 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a1, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2092  if ( sipIsErr )
2093  {
2094  sipReleaseType( p0, sipType_QVector_0100QgsPointXY, state0 );
2095  sipReleaseType( p1, sipType_QVector_0100QgsPointXY, state1 );
2096  }
2097  else
2098  {
2099  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2100  }
2101  }
2102  else if ( PyList_Check( o0 ) && PyList_Check( o1 ) &&
2103  PyList_GET_SIZE( o0 ) && PyList_GET_SIZE( o1 ) )
2104  {
2105  PyObject *oo0 = PyList_GetItem( o0, 0 );
2106  PyObject *oo1 = PyList_GetItem( o1, 0 );
2107  if ( oo0 && oo1 )
2108  {
2109  // compare polygon - polygon
2110  if ( sipCanConvertToType( oo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2111  sipCanConvertToType( oo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2112  sipCanConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2113  sipCanConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2114  {
2115  QgsPolygonXY *p0;
2116  QgsPolygonXY *p1;
2117  p0 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2118  p1 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2119  if ( sipIsErr )
2120  {
2121  sipReleaseType( p0, sipType_QVector_0600QVector_0100QgsPointXY, state0 );
2122  sipReleaseType( p1, sipType_QVector_0600QVector_0100QgsPointXY, state1 );
2123  }
2124  else
2125  {
2126  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2127  }
2128  }
2129  else if ( PyList_Check( oo0 ) && PyList_Check( oo1 ) &&
2130  PyList_GET_SIZE( oo0 ) && PyList_GET_SIZE( oo1 ) )
2131  {
2132  PyObject *ooo0 = PyList_GetItem( oo0, 0 );
2133  PyObject *ooo1 = PyList_GetItem( oo1, 0 );
2134  if ( ooo0 && ooo1 )
2135  {
2136  // compare multipolygon - multipolygon
2137  if ( sipCanConvertToType( ooo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2138  sipCanConvertToType( ooo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2139  sipCanConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2140  sipCanConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2141  {
2142  QgsMultiPolygonXY *p0;
2143  QgsMultiPolygonXY *p1;
2144  p0 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2145  p1 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2146  if ( sipIsErr )
2147  {
2148  sipReleaseType( p0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state0 );
2149  sipReleaseType( p1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state1 );
2150  }
2151  else
2152  {
2153  sipRes = QgsGeometry::compare( *p0, *p1, a2 );
2154  }
2155  }
2156  }
2157  }
2158  }
2159  }
2160  }
2161  }
2162  }
2163  % End
2164 #endif
2165 
2182  QgsGeometry smooth( unsigned int iterations = 1, double offset = 0.25,
2183  double minimumDistance = -1.0, double maxAngle = 180.0 ) const;
2184 
2188  static QgsGeometryEngine *createGeometryEngine( const QgsAbstractGeometry *geometry ) SIP_FACTORY;
2189 
2195  static void convertPointList( const QVector<QgsPointXY> &input, QgsPointSequence &output );
2196 
2202  static void convertPointList( const QgsPointSequence &input, QVector<QgsPointXY> &output );
2203 
2205  operator QVariant() const
2206  {
2207  return QVariant::fromValue( *this );
2208  }
2209 
2210  private:
2211 
2212  QgsGeometryPrivate *d; //implicitly shared data pointer
2213 
2215  mutable QString mLastError;
2216 
2221  void detach();
2222 
2227  void reset( std::unique_ptr< QgsAbstractGeometry > newGeometry );
2228 
2229  static void convertToPolyline( const QgsPointSequence &input, QgsPolylineXY &output );
2230  static void convertPolygon( const QgsPolygon &input, QgsPolygonXY &output );
2231 
2233  QgsGeometry convertToPoint( bool destMultipart ) const;
2235  QgsGeometry convertToLine( bool destMultipart ) const;
2237  QgsGeometry convertToPolygon( bool destMultipart ) const;
2238 
2250  std::unique_ptr< QgsLineString > smoothLine( const QgsLineString &line, unsigned int iterations = 1, double offset = 0.25,
2251  double minimumDistance = -1, double maxAngle = 180.0 ) const;
2252 
2264  std::unique_ptr< QgsPolygon > smoothPolygon( const QgsPolygon &polygon, unsigned int iterations = 1, double offset = 0.25,
2265  double minimumDistance = -1, double maxAngle = 180.0 ) const;
2266 
2267 
2269 
2270 }; // class QgsGeometry
2271 
2273 
2274 CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsGeometry &geometry );
2277 CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsGeometry &geometry );
2278 
2279 #endif
Geometry engine misses a method implemented or an error occurred in the geometry engine.
Definition: qgsgeometry.h:126
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:135
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:559
The source geometry is not multi.
Definition: qgsgeometry.h:130
Maximum angle between generating radii (lines from arc center to output vertices) ...
Use GEOS validation methods.
Definition: qgsgeometry.h:1857
Error(const QString &m)
Definition: qgsgeometry.h:1812
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:64
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:68
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:106
Use mitered joins.
Definition: qgsgeometry.h:1048
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
Definition: qgsgeometry.h:74
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:1036
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:206
Q_DECLARE_METATYPE(QModelIndex)
OperationResult
Success or failure of a geometry operation.
Definition: qgsgeometry.h:118
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:85
Error(const QString &m, const QgsPointXY &p)
Definition: qgsgeometry.h:1816
#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:78
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:127
The selected geometry cannot be found.
Definition: qgsgeometry.h:129
No features were selected.
Definition: qgsgeometry.h:124
More than one features were selected.
Definition: qgsgeometry.h:125
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:134
#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:665
Use internal QgsGeometryValidator method.
Definition: qgsgeometry.h:1856
#define SIP_TRANSFER
Definition: qgis_sip.h:36
The input ring is not closed.
Definition: qgsgeometry.h:132
Square cap (extends past start/end of line by buffer distance)
Definition: qgsgeometry.h:1040
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.
BufferSide
Side of line to buffer.
Definition: qgsgeometry.h:1028
QVector< QgsPoint > QgsPointSequence
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:138
#define SIP_PYARGREMOVE
Definition: qgis_sip.h:139
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
Definition: qgsgeometry.h:44
The base geometry on which the operation is done is invalid or empty.
Definition: qgsgeometry.h:122
The input geometry (ring, part, split line, etc.) has not the correct geometry type.
Definition: qgsgeometry.h:123
#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:1854
Buffer to right of line.
Definition: qgsgeometry.h:1031
Class for doing transforms between two map coordinate systems.
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:133
#define SIP_THROW(name)
Definition: qgis_sip.h:177
Contains geometry relation and modification algorithms.
Use beveled joins.
Definition: qgsgeometry.h:1049
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:1045
Flat cap (in line with start/end of line)
Definition: qgsgeometry.h:1039
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:429
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