QGIS API Documentation 4.3.0-Master (6402a64e93b)
Loading...
Searching...
No Matches
qgsgeometry.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsgeometry.h - Geometry (stored as Open Geospatial Consortium WKB)
3 -------------------------------------------------------------------
4Date : 02 May 2005
5Copyright : (C) 2005 by Brendan Morley
6email : 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 <climits>
20#include <functional>
21#include <limits>
22#include <memory>
23
24#include "qgis_core.h"
25#include "qgis_sip.h"
26#include "qgsabstractgeometry.h"
27#include "qgsfeatureid.h"
28#include "qgspoint.h"
29#include "qgspointxy.h"
30#include "qgsvertexid.h"
31
32#include <QDomDocument>
33#include <QJsonObject>
34#include <QSet>
35#include <QString>
36#include <QVector>
37
38using namespace Qt::StringLiterals;
39
40#ifndef SIP_RUN
41#include <nlohmann/json_fwd.hpp>
42using namespace nlohmann;
43#endif
44
46class QgsVectorLayer;
47class QgsMapToPixel;
48class QPainter;
49class QgsPolygon;
50class QgsLineString;
52class QgsCurve;
53class QgsFeedback;
54
63typedef QVector<QgsPointXY> QgsPolylineXY;
64
71#ifndef SIP_RUN
73#else
74typedef QVector<QgsPoint> QgsPolyline;
75#endif
76
84#ifndef SIP_RUN
85typedef QVector<QgsPolyline> QgsMultiPolyline;
86#else
87typedef QVector<QVector< QgsPoint >> QgsMultiPolyline;
88#endif
89
91#ifndef SIP_RUN
92typedef QVector<QgsPolylineXY> QgsPolygonXY;
93#else
94typedef QVector<QVector<QgsPointXY>> QgsPolygonXY;
95#endif
96
98typedef QVector<QgsPointXY> QgsMultiPointXY;
99
101#ifndef SIP_RUN
102typedef QVector<QgsPolylineXY> QgsMultiPolylineXY;
103#else
104typedef QVector<QVector<QgsPointXY>> QgsMultiPolylineXY;
105#endif
106
108#ifndef SIP_RUN
109typedef QVector<QgsPolygonXY> QgsMultiPolygonXY;
110#else
111typedef QVector<QVector<QVector<QgsPointXY>>> QgsMultiPolygonXY;
112#endif
113
114class QgsRectangle;
115
116class QgsConstWkbPtr;
117
118struct QgsGeometryPrivate;
119
126class CORE_EXPORT QgsGeometryParameters
127{
128 public:
139 double gridSize() const { return mGridSize; }
140
151 void setGridSize( double size ) { mGridSize = size; }
152
153 private:
154 double mGridSize = -1;
155};
156
157
165{
166 public:
187 double snappingDistance() const { return mSnappingDistance; }
188
194 void setSnappingDistance( double distance ) { mSnappingDistance = distance; }
195
216 double maximumGapWidth() const { return mMaximumGapWidth; }
217
223 void setMaximumGapWidth( double width ) { mMaximumGapWidth = width; }
224
230 Qgis::CoverageCleanOverlapMergeStrategy overlapMergeStrategy() const { return mOverlapMergeStrategy; } //#spellok
231
237 void setOverlapMergeStrategy( Qgis::CoverageCleanOverlapMergeStrategy strategy ) { mOverlapMergeStrategy = strategy; } //#spellok
238
239 private:
240 double mSnappingDistance = -1;
241 double mMaximumGapWidth = 0;
243};
244
245
266class CORE_EXPORT QgsGeometry
267{
268 Q_GADGET
269 Q_PROPERTY( bool isNull READ isNull )
270 Q_PROPERTY( Qgis::GeometryType type READ type )
271
272 public:
273 // clang-format off
275 // clang-format on
276
278 QgsGeometry( const QgsGeometry & );
279
284 QgsGeometry &operator=( QgsGeometry const &rhs ) SIP_SKIP;
285
291
297 explicit QgsGeometry( std::unique_ptr< QgsAbstractGeometry > geom ) SIP_SKIP;
298
299 virtual ~QgsGeometry();
300
312
325
338
346 bool isNull() const SIP_HOLDGIL;
347
349 Q_INVOKABLE static QgsGeometry fromWkt( const QString &wkt );
351 static QgsGeometry fromPointXY( const QgsPointXY &point ) SIP_HOLDGIL;
352
358 static QgsGeometry fromPoint( const QgsPoint &point ) SIP_HOLDGIL;
359
361 static QgsGeometry fromMultiPointXY( const QgsMultiPointXY &multipoint );
362
373 static QgsGeometry fromPolylineXY( const QgsPolylineXY &polyline );
374
383 static QgsGeometry fromPolyline( const QgsPolyline &polyline );
384
388 static QgsGeometry fromMultiPolylineXY( const QgsMultiPolylineXY &multiline );
389
390#ifndef SIP_RUN
391
395#else
396
414#endif
415 static QgsGeometry fromPolygonXY( const QgsPolygonXY &polygon );
416
420 static QgsGeometry fromMultiPolygonXY( const QgsMultiPolygonXY &multipoly );
421
423 static QgsGeometry fromRect( const QgsRectangle &rect ) SIP_HOLDGIL;
424
432 static QgsGeometry fromBox3D( const QgsBox3D &box ) SIP_HOLDGIL;
433
434
436 static QgsGeometry collectGeometry( const QVector<QgsGeometry> &geometries );
437
453 static QgsGeometry collectTinPatches( const QVector<QgsGeometry> &geometries );
454
470 static QgsGeometry createWedgeBuffer( const QgsPoint &center, double azimuth, double angularWidth, double outerRadius, double innerRadius = 0 );
471
485 static QgsGeometry createWedgeBufferFromAngles( const QgsPoint &center, double startAngle, double endAngle, double outerRadius, double innerRadius = 0 );
486
492 void fromWkb( unsigned char *wkb, int length ) SIP_SKIP;
493
497 void fromWkb( const QByteArray &wkb );
498
504
509 Qgis::GeometryType type() const SIP_HOLDGIL;
510
517 bool isEmpty() const SIP_HOLDGIL;
518
520 bool isMultipart() const SIP_HOLDGIL;
521
535 Q_DECL_DEPRECATED bool equals( const QgsGeometry &geometry ) const SIP_DEPRECATED;
536
552 Q_DECL_DEPRECATED bool isGeosEqual( const QgsGeometry & ) const SIP_DEPRECATED;
553
572 bool isExactlyEqual( const QgsGeometry &geometry, Qgis::GeometryBackend backend = Qgis::GeometryBackend::QGIS ) const SIP_THROW( QgsNotSupportedException );
573
591 bool isTopologicallyEqual( const QgsGeometry &geometry, Qgis::GeometryBackend backend = Qgis::GeometryBackend::GEOS ) const SIP_THROW( QgsNotSupportedException );
592
610 bool isFuzzyEqual( const QgsGeometry &geometry, double epsilon = 1e-4, Qgis::GeometryBackend backend = Qgis::GeometryBackend::QGIS ) const SIP_THROW( QgsNotSupportedException );
611
618 bool isGeosValid( Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const;
619
627 bool isSimple() const;
628
642 bool isAxisParallelRectangle( double maximumDeviation, bool simpleRectanglesOnly = false ) const;
643
656 double area() const;
657
672
686 double length() const;
687
695 double distance( const QgsGeometry &geom ) const;
696
697#ifndef SIP_RUN
698
699 // TODO QGIS 5: consider renaming vertices_begin, vertices_end, parts_begin, parts_end, etc
700 // to camelCase
701
706
711#endif
712
736
737#ifndef SIP_RUN
738
748
758
768
778#endif
779
818
852
869 double hausdorffDistance( const QgsGeometry &geom ) const;
870
888 double hausdorffDistanceDensify( const QgsGeometry &geom, double densifyFraction ) const;
889
904 double frechetDistance( const QgsGeometry &geom ) const SIP_THROW( QgsNotSupportedException );
905
928 double frechetDistanceDensify( const QgsGeometry &geom, double densifyFraction ) const SIP_THROW( QgsNotSupportedException );
929
942 QgsPointXY closestVertex( const QgsPointXY &point, int &closestVertexIndex SIP_OUT, int &previousVertexIndex SIP_OUT, int &nextVertexIndex SIP_OUT, double &sqrDist SIP_OUT ) const;
943
951 double distanceToVertex( int vertex ) const;
952
959 double angleAtVertex( int vertex ) const;
960
973 void adjacentVertices( int atVertex, int &beforeVertex SIP_OUT, int &afterVertex SIP_OUT ) const;
974
987 bool insertVertex( double x, double y, int beforeVertex );
988
1001 bool insertVertex( const QgsPoint &point, int beforeVertex );
1002
1010 bool addTopologicalPoint( const QgsPoint &point, double snappingTolerance = 1e-8, double segmentSearchEpsilon = 1e-12 );
1011
1019 bool moveVertex( double x, double y, int atVertex );
1020
1028 bool moveVertex( const QgsPoint &p, int atVertex );
1029
1042 bool deleteVertex( int atVertex );
1043
1057 bool deleteVertices( const QSet<int> &atVertices );
1058
1066 bool toggleCircularAtVertex( int atVertex );
1067
1073 QgsPoint vertexAt( int atVertex ) const;
1074
1080 double sqrDistToVertexAt( QgsPointXY &point SIP_IN, int atVertex ) const;
1081
1086 QgsGeometry nearestPoint( const QgsGeometry &other ) const;
1087
1097 QgsGeometry shortestLine( const QgsGeometry &other ) const;
1098
1105 double closestVertexWithContext( const QgsPointXY &point, int &atVertex SIP_OUT ) const;
1106
1118 double closestSegmentWithContext( const QgsPointXY &point, QgsPointXY &minDistPoint SIP_OUT, int &nextVertexIndex SIP_OUT, int *leftOrRightOfSegment SIP_OUT = nullptr, double epsilon = Qgis::DEFAULT_SEGMENT_EPSILON ) const;
1119
1125 Qgis::GeometryOperationResult addRing( const QVector<QgsPointXY> &ring );
1126
1133
1141 Q_DECL_DEPRECATED Qgis::GeometryOperationResult addPart( const QVector<QgsPointXY> &points, Qgis::GeometryType geomType = Qgis::GeometryType::Unknown ) SIP_PYNAME( addPointsXY ) SIP_DEPRECATED;
1142
1150 Qgis::GeometryOperationResult addPartV2( const QVector<QgsPointXY> &points, Qgis::WkbType wkbType = Qgis::WkbType::Unknown ) SIP_PYNAME( addPointsXYV2 );
1151
1160
1169
1178
1187
1193 Qgis::GeometryOperationResult addPart( const QgsGeometry &newPart ) SIP_PYNAME( addPartGeometry );
1194
1200 QgsGeometry removeInteriorRings( double minimumAllowedArea = -1 ) const;
1201
1206 Qgis::GeometryOperationResult translate( double dx, double dy, double dz = 0.0, double dm = 0.0 );
1207
1223
1232 Qgis::GeometryOperationResult transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 );
1233
1240 Qgis::GeometryOperationResult rotate( double rotation, const QgsPointXY &center );
1241
1252 Q_DECL_DEPRECATED Qgis::GeometryOperationResult splitGeometry( const QVector<QgsPointXY> &splitLine, QVector<QgsGeometry> &newGeometries, bool topological, QVector<QgsPointXY> &topologyTestPoints, bool splitFeature = true ) SIP_SKIP;
1253
1275 Qgis::GeometryOperationResult splitGeometry( const QgsPointSequence &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QgsPointSequence &topologyTestPoints SIP_OUT, bool splitFeature = true, bool skipIntersectionTest SIP_PYARGREMOVE = false ) SIP_SKIP;
1276
1277
1278 /*
1279 This SIP code is to support overloaded methods of splitGeometry.
1280 When the deprecated method is removed in QGIS 5.0 this code can be dropped
1281 TODO QGIS 5 remove MethodCode
1282 */
1283#ifdef SIP_RUN
1284// clang-format off
1285
1304 SIP_PYOBJECT splitGeometry( SIP_PYOBJECT splitLine SIP_TYPEHINT( List[Union[QgsPoint, QgsPointXY]] ), bool topological, bool splitFeature = true ) SIP_TYPEHINT( Tuple[Qgis.GeometryOperationResult, Union[List[QgsPoint], List[QgsPointXY]], Union[List[QgsPoint], List[QgsPointXY]]] );
1305 % MethodCode
1306 {
1307 int sipIsErr = 0;
1308 int state;
1309
1310 if ( PyList_Check( a0 ) && PyList_GET_SIZE( a0 ) )
1311 {
1312 PyObject *p0 = PyList_GetItem( a0, 0 );
1313 if ( sipCanConvertToType( p0, sipType_QgsPointXY, SIP_NOT_NONE ) && sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
1314 {
1315 QVector<QgsGeometry> newGeometries;
1316 QVector<QgsPointXY> topologyTestPoints;
1317
1318 QVector<QgsPointXY> *splitLine = reinterpret_cast<QVector<QgsPointXY> *>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
1319 if ( !sipIsErr )
1320 {
1321 Qgis::GeometryOperationResult result = sipCpp->splitGeometry( *splitLine, newGeometries, a1, topologyTestPoints, a2 );
1322
1323 PyObject *o0 = sipConvertFromEnum( static_cast<int>( result ), sipType_Qgis_GeometryOperationResult );
1324 PyObject *o1 = sipConvertFromType( &newGeometries, sipType_QVector_0100QgsGeometry, Py_None );
1325 PyObject *o2 = sipConvertFromType( &topologyTestPoints, sipType_QVector_0100QgsPointXY, Py_None );
1326
1327 sipRes = PyTuple_New( 3 );
1328 PyTuple_SET_ITEM( sipRes, 0, o0 );
1329 PyTuple_SET_ITEM( sipRes, 1, o1 );
1330 PyTuple_SET_ITEM( sipRes, 2, o2 );
1331 }
1332 sipReleaseType( splitLine, sipType_QVector_0100QgsPointXY, state );
1333 }
1334
1335 else if ( sipCanConvertToType( p0, sipType_QgsPoint, SIP_NOT_NONE ) && sipCanConvertToType( a0, sipType_QVector_0100QgsPoint, SIP_NOT_NONE ) )
1336 {
1337 QVector<QgsGeometry> newGeometries;
1338 QVector<QgsPoint> topologyTestPoints;
1339
1340 QVector<QgsPoint> *splitLine = reinterpret_cast<QVector<QgsPoint> *>( sipConvertToType( a0, sipType_QVector_0100QgsPoint, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
1341 if ( !sipIsErr )
1342 {
1343 Qgis::GeometryOperationResult result = sipCpp->splitGeometry( *splitLine, newGeometries, a1, topologyTestPoints, a2 );
1344
1345 PyObject *o0 = sipConvertFromEnum( static_cast<int>( result ), sipType_Qgis_GeometryOperationResult );
1346 PyObject *o1 = sipConvertFromType( &newGeometries, sipType_QVector_0100QgsGeometry, Py_None );
1347 PyObject *o2 = sipConvertFromType( &topologyTestPoints, sipType_QVector_0100QgsPoint, Py_None );
1348
1349 sipRes = PyTuple_New( 3 );
1350 PyTuple_SET_ITEM( sipRes, 0, o0 );
1351 PyTuple_SET_ITEM( sipRes, 1, o1 );
1352 PyTuple_SET_ITEM( sipRes, 2, o2 );
1353 }
1354 sipReleaseType( splitLine, sipType_QVector_0100QgsPoint, state );
1355 }
1356 else
1357 {
1358 sipIsErr = 1;
1359 PyErr_SetString( PyExc_TypeError, u"Could not convert first argument to a list of QgsPoint or QgsPointXY."_s.toUtf8().constData() );
1360 }
1361 }
1362 else
1363 {
1364 sipIsErr = 1;
1365 PyErr_SetString( PyExc_TypeError, u"First argument is not a list of points or is empty."_s.toUtf8().constData() );
1366 }
1367 }
1368 % End
1369// clang-format on
1370#endif
1371
1383 Qgis::GeometryOperationResult splitGeometry( const QgsCurve *curve, QVector<QgsGeometry> &newGeometries SIP_OUT, bool preserveCircular, bool topological, QgsPointSequence &topologyTestPoints SIP_OUT, bool splitFeature = true );
1384
1389 Qgis::GeometryOperationResult reshapeGeometry( const QgsLineString &reshapeLineString );
1390
1398 Q_DECL_DEPRECATED int makeDifferenceInPlace( const QgsGeometry &other, QgsFeedback* feedback = nullptr ) SIP_SKIP;
1399
1408 Q_DECL_DEPRECATED QgsGeometry makeDifference( const QgsGeometry &other, QgsFeedback* feedback = nullptr ) const SIP_DEPRECATED;
1409
1414 QgsRectangle boundingBox() const;
1415
1421 QgsBox3D boundingBox3D() const;
1422
1435 QgsGeometry orientedMinimumBoundingBox( double &area SIP_OUT, double &angle SIP_OUT, double &width SIP_OUT, double &height SIP_OUT ) const;
1436
1446 QgsGeometry orientedMinimumBoundingBox() const SIP_SKIP;
1447
1455 QgsGeometry minimalEnclosingCircle( QgsPointXY &center SIP_OUT, double &radius SIP_OUT, unsigned int segments = 36 ) const;
1456
1461 QgsGeometry minimalEnclosingCircle( unsigned int segments = 36 ) const SIP_SKIP;
1462
1470 QgsGeometry orthogonalize( double tolerance = 1.0E-8, int maxIterations = 1000, double angleThreshold = 15.0 ) const;
1471
1484 QgsGeometry triangularWaves( double wavelength, double amplitude, bool strictWavelength = false ) const;
1485
1504 QgsGeometry triangularWavesRandomized( double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed = 0 ) const;
1505
1518 QgsGeometry squareWaves( double wavelength, double amplitude, bool strictWavelength = false ) const;
1519
1538 QgsGeometry squareWavesRandomized( double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed = 0 ) const;
1539
1552 QgsGeometry roundWaves( double wavelength, double amplitude, bool strictWavelength = false ) const;
1553
1572 QgsGeometry roundWavesRandomized( double minimumWavelength, double maximumWavelength, double minimumAmplitude, double maximumAmplitude, unsigned long seed = 0 ) const;
1573
1587 QgsGeometry applyDashPattern( const QVector< double > &pattern, Qgis::DashPatternLineEndingRule startRule = Qgis::DashPatternLineEndingRule::NoRule, Qgis::DashPatternLineEndingRule endRule = Qgis::DashPatternLineEndingRule::NoRule, Qgis::DashPatternSizeAdjustment adjustment = Qgis::DashPatternSizeAdjustment::ScaleBothDashAndGap, double patternOffset = 0 ) const;
1588
1600 QgsGeometry snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const;
1601
1621 bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false );
1622
1632 Q_INVOKABLE bool intersects( const QgsRectangle &rectangle ) const;
1633
1648 Q_INVOKABLE bool intersects( const QgsGeometry &geometry ) const;
1649
1658 Q_INVOKABLE bool boundingBoxIntersects( const QgsRectangle &rectangle ) const;
1659
1668 Q_INVOKABLE bool boundingBoxIntersects( const QgsGeometry &geometry ) const;
1669
1673 bool contains( const QgsPointXY *p ) const;
1674
1680 Q_INVOKABLE bool contains( double x, double y ) const;
1681
1691 Q_INVOKABLE bool contains( const QgsGeometry &geometry ) const;
1692
1702 Q_INVOKABLE bool disjoint( const QgsGeometry &geometry ) const;
1703
1713 Q_INVOKABLE bool touches( const QgsGeometry &geometry ) const;
1714
1724 Q_INVOKABLE bool overlaps( const QgsGeometry &geometry ) const;
1725
1735 Q_INVOKABLE bool within( const QgsGeometry &geometry ) const;
1736
1746 Q_INVOKABLE bool crosses( const QgsGeometry &geometry ) const;
1747
1757 QgsGeometry buffer( double distance, int segments, QgsFeedback* feedback = nullptr ) const;
1758
1771 QgsGeometry buffer( double distance, int segments, Qgis::EndCapStyle endCapStyle, Qgis::JoinStyle joinStyle, double miterLimit, QgsFeedback* feedback = nullptr ) const;
1772
1780 QgsGeometry offsetCurve( double distance, int segments, Qgis::JoinStyle joinStyle, double miterLimit ) const;
1781
1796 QgsGeometry singleSidedBuffer( double distance, int segments, Qgis::BufferSide side, Qgis::JoinStyle joinStyle = Qgis::JoinStyle::Round, double miterLimit = 2.0 ) const;
1797
1815 QgsGeometry taperedBuffer( double startWidth, double endWidth, int segments ) const;
1816
1831 QgsGeometry variableWidthBufferByM( int segments ) const;
1832
1841 QgsGeometry extendLine( double startDistance, double endDistance, double startDeflection = 0, double endDeflection = 0 ) const;
1842
1848 QgsGeometry simplify( double tolerance, QgsFeedback* feedback = nullptr ) const;
1849
1858 QgsGeometry densifyByCount( int extraNodesPerSegment ) const;
1859
1873 QgsGeometry densifyByDistance( double distance ) const;
1874
1890 QgsGeometry convertToCurves( double distanceTolerance = 1e-8, double angleTolerance = 1e-8 ) const;
1891
1905 QgsGeometry centroid() const;
1906
1920 QgsGeometry pointOnSurface() const;
1921
1933 QgsGeometry poleOfInaccessibility( double precision, double *distanceToBoundary SIP_OUT = nullptr ) const;
1934
1958 QgsGeometry largestEmptyCircle( double tolerance, const QgsGeometry &boundary = QgsGeometry() ) const SIP_THROW( QgsNotSupportedException );
1959
1974 QgsGeometry minimumWidth() const SIP_THROW( QgsNotSupportedException );
1975
1997 double minimumClearance() const SIP_THROW( QgsNotSupportedException );
1998
2010 QgsGeometry minimumClearanceLine() const SIP_THROW( QgsNotSupportedException );
2011
2020 QgsGeometry convexHull() const;
2021
2037 QgsGeometry concaveHull( double targetPercent, bool allowHoles = false, QgsFeedback * feedback = nullptr ) const SIP_THROW( QgsNotSupportedException );
2038
2074 QgsGeometry concaveHullOfPolygons( double lengthRatio, bool allowHoles = false, bool isTight = false, QgsFeedback *feedback = nullptr ) const SIP_THROW( QgsNotSupportedException );
2075
2090 QgsGeometry voronoiDiagram( const QgsGeometry &extent = QgsGeometry(), double tolerance = 0.0, bool edgesOnly = false ) const;
2091
2102 QgsGeometry delaunayTriangulation( double tolerance = 0.0, bool edgesOnly = false ) const;
2103
2116 QgsGeometry constrainedDelaunayTriangulation() const SIP_THROW( QgsNotSupportedException );
2117
2135 Qgis::CoverageValidityResult validateCoverage( double gapWidth, QgsGeometry *invalidEdges SIP_OUT = nullptr ) const SIP_THROW( QgsNotSupportedException );
2136
2157 QgsGeometry simplifyCoverageVW( double tolerance, bool preserveBoundary ) const SIP_THROW( QgsNotSupportedException );
2158
2170 QgsGeometry unionCoverage() const;
2171
2189 QgsGeometry cleanCoverage( const QgsCoverageCleanParameters &parameters, QgsFeedback *feedback = nullptr ) const SIP_THROW( QgsNotSupportedException );
2190
2201 QgsGeometry node() const;
2202
2217 QgsGeometry sharedPaths( const QgsGeometry &other ) const;
2218
2241 QgsGeometry subdivide( int maxNodes = 256, const QgsGeometryParameters &parameters = QgsGeometryParameters(), QgsFeedback* feedback = nullptr ) const;
2242
2257 QgsGeometry interpolate( double distance ) const;
2258
2269 double lineLocatePoint( const QgsGeometry &point ) const;
2270
2279 double interpolateAngle( double distance ) const;
2280
2294 QgsGeometry intersection( const QgsGeometry &geometry, const QgsGeometryParameters &parameters = QgsGeometryParameters(), QgsFeedback* feedback = nullptr ) const;
2295
2304 QgsGeometry clipped( const QgsRectangle &rectangle, QgsFeedback* feedback = nullptr );
2305
2322 QgsGeometry combine( const QgsGeometry &geometry, const QgsGeometryParameters &parameters = QgsGeometryParameters(), QgsFeedback* feedback = nullptr ) const;
2323
2334 QgsGeometry mergeLines( const QgsGeometryParameters &parameters = QgsGeometryParameters() ) const;
2335
2349 QgsGeometry difference( const QgsGeometry &geometry, const QgsGeometryParameters &parameters = QgsGeometryParameters(), QgsFeedback* feedback = nullptr ) const;
2350
2364 QgsGeometry symDifference( const QgsGeometry &geometry, const QgsGeometryParameters &parameters = QgsGeometryParameters(), QgsFeedback* feedback = nullptr ) const;
2365
2367 QgsGeometry extrude( double x, double y );
2368
2369#ifndef SIP_RUN
2370
2392 QVector< QgsPointXY > randomPointsInPolygon( int count, const std::function< bool( const QgsPointXY & ) > &acceptPoint, unsigned long seed = 0, QgsFeedback *feedback = nullptr, int maxTriesPerPoint = 0 ) const;
2393
2407 QVector< QgsPointXY > randomPointsInPolygon( int count, unsigned long seed = 0, QgsFeedback *feedback = nullptr ) const;
2409#else
2410// clang-format off
2411
2425 SIP_PYOBJECT randomPointsInPolygon( int count, unsigned long seed = 0 ) const SIP_TYPEHINT( QgsPolylineXY );
2426 % MethodCode
2427 const Qgis::GeometryType type = sipCpp->type();
2428 if ( sipCpp->isNull() )
2429 {
2430 PyErr_SetString( PyExc_ValueError, u"Cannot generate points inside a null geometry."_s.toUtf8().constData() );
2431 sipIsErr = 1;
2432 }
2433 else if ( type != Qgis::GeometryType::Polygon )
2434 {
2435 PyErr_SetString( PyExc_TypeError, u"Cannot generate points inside a %1 geometry. Only Polygon types are permitted."_s.arg( QgsWkbTypes::displayString( sipCpp->wkbType() ) ).toUtf8().constData() );
2436 sipIsErr = 1;
2437 }
2438 else
2439 {
2440 const sipTypeDef *qvector_type = sipFindType( "QVector<QgsPointXY>" );
2441 sipRes = sipConvertFromNewType( new QVector< QgsPointXY >( sipCpp->randomPointsInPolygon( a0, a1 ) ), qvector_type, Py_None );
2442 }
2443 % End
2444
2445
2446// clang-format on
2447#endif
2449
2457 int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const;
2458
2465 QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const;
2466
2472 Q_INVOKABLE QString asWkt( int precision = 17 ) const;
2473
2474#ifdef SIP_RUN
2475// clang-format off
2476 SIP_PYOBJECT __repr__();
2477 % MethodCode
2478 QString str;
2479 if ( sipCpp->isNull() )
2480 str = u"<QgsGeometry: null>"_s;
2481 else
2482 {
2483 QString wkt = sipCpp->asWkt();
2484 if ( wkt.length() > 1000 )
2485 wkt = wkt.left( 1000 ) + u"..."_s;
2486 str = u"<QgsGeometry: %1>"_s.arg( wkt );
2487 }
2488 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
2489 % End
2490// clang-format on
2491#endif
2492
2497 QString asJson( int precision = 17 ) const;
2498
2504 QString asGeoJson( int precision = 17, Qgis::GeoJsonProfile profile = Qgis::GeoJsonProfile::Legacy ) const;
2505
2511 virtual json asJsonObject( int precision = 17, Qgis::GeoJsonProfile profile = Qgis::GeoJsonProfile::Legacy ) const SIP_SKIP;
2512
2549 QVector< QgsGeometry > coerceToType( Qgis::WkbType type, double defaultZ = 0, double defaultM = 0, bool avoidDuplicates = true ) const;
2550
2562 QgsGeometry convertToType( Qgis::GeometryType destType, bool destMultipart = false ) const;
2563
2564 /* Accessor functions for getting geometry data */
2565
2566#ifndef SIP_RUN
2567
2576 QgsPointXY asPoint() const;
2577#else
2578// clang-format off
2579
2590 SIP_PYOBJECT asPoint() const SIP_TYPEHINT( QgsPointXY );
2591 % MethodCode
2592 if ( sipCpp->isNull() )
2593 {
2594 PyErr_SetString( PyExc_ValueError, u"Null geometry cannot be converted to a point."_s.toUtf8().constData() );
2595 sipIsErr = 1;
2596 }
2597 else
2598 {
2599 const QgsAbstractGeometry *geom = sipCpp->constGet();
2601 {
2602 PyErr_SetString( PyExc_TypeError, u"%1 geometry cannot be converted to a point. Only Point types are permitted."_s.arg( QgsWkbTypes::displayString( geom->wkbType() ) ).toUtf8().constData() );
2603 sipIsErr = 1;
2604 }
2605 else
2606 {
2607 sipRes = sipConvertFromNewType( new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
2608 }
2609 }
2610 % End
2611// clang-format on
2612#endif
2613
2614#ifndef SIP_RUN
2615
2624 QgsPolylineXY asPolyline() const;
2625#else
2626// clang-format off
2627
2639 SIP_PYOBJECT asPolyline() const SIP_TYPEHINT( QgsPolylineXY );
2640 % MethodCode
2641 const Qgis::WkbType type = sipCpp->wkbType();
2642 if ( sipCpp->isNull() )
2643 {
2644 PyErr_SetString( PyExc_ValueError, u"Null geometry cannot be converted to a polyline."_s.toUtf8().constData() );
2645 sipIsErr = 1;
2646 }
2648 {
2649 PyErr_SetString( PyExc_TypeError, u"%1 geometry cannot be converted to a polyline. Only single line or curve types are permitted."_s.arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
2650 sipIsErr = 1;
2651 }
2652 else
2653 {
2654 const sipTypeDef *qvector_type = sipFindType( "QVector< QgsPointXY >" );
2655 sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asPolyline() ), qvector_type, Py_None );
2656 }
2657 % End
2658// clang-format on
2659#endif
2660
2661#ifndef SIP_RUN
2662
2671 QgsPolygonXY asPolygon() const;
2672#else
2673// clang-format off
2674
2686 SIP_PYOBJECT asPolygon() const SIP_TYPEHINT( QgsPolygonXY );
2687 % MethodCode
2688 const Qgis::WkbType type = sipCpp->wkbType();
2689 if ( sipCpp->isNull() )
2690 {
2691 PyErr_SetString( PyExc_ValueError, u"Null geometry cannot be converted to a polygon."_s.toUtf8().constData() );
2692 sipIsErr = 1;
2693 }
2695 {
2696 PyErr_SetString( PyExc_TypeError, u"%1 geometry cannot be converted to a polygon. Only single polygon or curve polygon types are permitted."_s.arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
2697 sipIsErr = 1;
2698 }
2699 else
2700 {
2701 const sipTypeDef *qvector_type = sipFindType( "QVector<QVector<QgsPointXY>>" );
2702 sipRes = sipConvertFromNewType( new QgsPolygonXY( sipCpp->asPolygon() ), qvector_type, Py_None );
2703 }
2704 % End
2705// clang-format on
2706#endif
2707
2708#ifndef SIP_RUN
2709
2717 QgsMultiPointXY asMultiPoint() const;
2718#else
2719// clang-format off
2720
2731 SIP_PYOBJECT asMultiPoint() const SIP_TYPEHINT( QgsMultiPointXY );
2732 % MethodCode
2733 const Qgis::WkbType type = sipCpp->wkbType();
2734 if ( sipCpp->isNull() )
2735 {
2736 PyErr_SetString( PyExc_ValueError, u"Null geometry cannot be converted to a multipoint."_s.toUtf8().constData() );
2737 sipIsErr = 1;
2738 }
2740 {
2741 PyErr_SetString( PyExc_TypeError, u"%1 geometry cannot be converted to a multipoint. Only multipoint types are permitted."_s.arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
2742 sipIsErr = 1;
2743 }
2744 else
2745 {
2746 const sipTypeDef *qvector_type = sipFindType( "QVector< QgsPointXY >" );
2747 sipRes = sipConvertFromNewType( new QgsPolylineXY( sipCpp->asMultiPoint() ), qvector_type, Py_None );
2748 }
2749 % End
2750// clang-format on
2751#endif
2752
2753#ifndef SIP_RUN
2754
2763 QgsMultiPolylineXY asMultiPolyline() const;
2764#else
2765// clang-format off
2766
2778 SIP_PYOBJECT asMultiPolyline() const SIP_TYPEHINT( QgsMultiPolylineXY );
2779 % MethodCode
2780 const Qgis::WkbType type = sipCpp->wkbType();
2781 if ( sipCpp->isNull() )
2782 {
2783 PyErr_SetString( PyExc_ValueError, u"Null geometry cannot be converted to a multilinestring."_s.toUtf8().constData() );
2784 sipIsErr = 1;
2785 }
2787 {
2788 PyErr_SetString( PyExc_TypeError, u"%1 geometry cannot be converted to a multilinestring. Only multi linestring or curves are permitted."_s.arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
2789 sipIsErr = 1;
2790 }
2791 else
2792 {
2793 const sipTypeDef *qvector_type = sipFindType( "QVector<QVector<QgsPointXY>>" );
2794 sipRes = sipConvertFromNewType( new QgsMultiPolylineXY( sipCpp->asMultiPolyline() ), qvector_type, Py_None );
2795 }
2796 % End
2797// clang-format on
2798#endif
2799
2800#ifndef SIP_RUN
2801
2810 QgsMultiPolygonXY asMultiPolygon() const;
2811#else
2812// clang-format off
2813
2825 SIP_PYOBJECT asMultiPolygon() const SIP_TYPEHINT( QgsMultiPolygonXY );
2826 % MethodCode
2827 const Qgis::WkbType type = sipCpp->wkbType();
2828 if ( sipCpp->isNull() )
2829 {
2830 PyErr_SetString( PyExc_ValueError, u"Null geometry cannot be converted to a multipolygon."_s.toUtf8().constData() );
2831 sipIsErr = 1;
2832 }
2834 {
2835 PyErr_SetString( PyExc_TypeError, u"%1 geometry cannot be converted to a multipolygon. Only multi polygon or curves are permitted."_s.arg( QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
2836 sipIsErr = 1;
2837 }
2838 else
2839 {
2840 const sipTypeDef *qvector_type = sipFindType( "QVector<QVector<QVector<QgsPointXY>>>" );
2841 sipRes = sipConvertFromNewType( new QgsMultiPolygonXY( sipCpp->asMultiPolygon() ), qvector_type, Py_None );
2842 }
2843 % End
2844// clang-format on
2845#endif
2846
2850 QVector<QgsGeometry> asGeometryCollection() const;
2851
2856 QPointF asQPointF() const SIP_HOLDGIL;
2857
2869 QPolygonF asQPolygonF() const SIP_HOLDGIL;
2870
2876 bool deleteRing( int ringNum, int partNum = 0 );
2877
2882 bool deletePart( int partNum );
2883
2892 bool convertToMultiType();
2893
2909 bool convertToCurvedMultiType();
2910
2920 bool convertToSingleType();
2921
2931 bool convertGeometryCollectionToSubclass( Qgis::GeometryType geomType );
2932
2944 Q_DECL_DEPRECATED int avoidIntersections( const QList<QgsVectorLayer *> &avoidIntersectionsLayers, const QHash<QgsVectorLayer *, QSet<QgsFeatureId> > &ignoreFeatures SIP_PYARGREMOVE = ( QHash<QgsVectorLayer *, QSet<QgsFeatureId> >() ) ) SIP_DEPRECATED;
2945
2957 Qgis::GeometryOperationResult avoidIntersectionsV2( const QList<QgsVectorLayer *> &avoidIntersectionsLayers, const QHash<QgsVectorLayer *, QSet<QgsFeatureId> > &ignoreFeatures SIP_PYARGREMOVE = ( QHash<QgsVectorLayer *, QSet<QgsFeatureId> >() ) );
2958
2980 QgsGeometry makeValid( Qgis::MakeValidMethod method = Qgis::MakeValidMethod::Linework, bool keepCollapsed = false, QgsFeedback* feedback = nullptr ) const SIP_THROW( QgsNotSupportedException );
2981
2991 Qgis::AngularDirection polygonOrientation() const;
2992
3007
3022
3023
3038 QgsGeometry forceRHR() const;
3039
3050 QgsGeometry forcePolygonClockwise() const;
3051
3062 QgsGeometry forcePolygonCounterClockwise() const;
3063
3068 class CORE_EXPORT Error
3069 {
3070 public:
3072 : mMessage( u"none"_s )
3073 {}
3074
3075 explicit Error( const QString &m )
3076 : mMessage( m )
3077 {}
3078
3079 Error( const QString &m, const QgsPointXY &p )
3080 : mMessage( m )
3081 , mLocation( p )
3082 , mHasLocation( true ) {}
3083
3087 QString what() const;
3088
3092 QgsPointXY where() const;
3093
3097 bool hasWhere() const;
3098
3099#ifdef SIP_RUN
3100// clang-format off
3101 SIP_PYOBJECT __repr__();
3102 % MethodCode
3103 QString str = u"<QgsGeometry.Error: %1>"_s.arg( sipCpp->what() );
3104 sipRes = PyUnicode_FromString( str.toUtf8().data() );
3105 % End
3106// clang-format on
3107#endif
3108
3109 // TODO c++20 - replace with = default
3110 bool operator==( const QgsGeometry::Error &other ) const
3111 {
3112 return other.mMessage == mMessage && other.mHasLocation == mHasLocation && other.mLocation == mLocation;
3113 }
3114
3115 private:
3116 QString mMessage;
3117 QgsPointXY mLocation;
3118 bool mHasLocation = false;
3119 };
3120
3130 void validateGeometry( QVector<QgsGeometry::Error> &errors SIP_OUT, Qgis::GeometryValidationEngine method = Qgis::GeometryValidationEngine::QgisInternal, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const;
3131
3141 void normalize();
3142
3153 static QgsGeometry unaryUnion( const QVector<QgsGeometry> &geometries, const QgsGeometryParameters &parameters = QgsGeometryParameters(), QgsFeedback* feedback = nullptr );
3154
3162 static QgsGeometry polygonize( const QVector<QgsGeometry> &geometries );
3163
3170 void convertToStraightSegment( double tolerance = M_PI / 180., QgsAbstractGeometry::SegmentationToleranceType toleranceType = QgsAbstractGeometry::MaximumAngle );
3171
3177 bool requiresConversionToStraightSegments() const;
3178
3183 void mapToPixel( const QgsMapToPixel &mtp );
3184
3189 void draw( QPainter &p ) const;
3190
3200 bool vertexIdFromVertexNr( int number, QgsVertexId &id SIP_OUT ) const;
3201
3212 int vertexNrFromVertexId( QgsVertexId id ) const;
3213
3220 QString lastError() const SIP_HOLDGIL;
3221
3231 void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) SIP_SKIP;
3232
3247 void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) SIP_SKIP;
3248
3253 static QgsGeometry fromQPointF( QPointF point ) SIP_HOLDGIL;
3254
3261 static QgsGeometry fromQPolygonF( const QPolygonF &polygon );
3262
3270 Q_DECL_DEPRECATED static QgsPolylineXY createPolylineFromQPolygonF( const QPolygonF &polygon ) SIP_DEPRECATED;
3271
3279 Q_DECL_DEPRECATED static QgsPolygonXY createPolygonFromQPolygonF( const QPolygonF &polygon ) SIP_DEPRECATED;
3280
3281#ifndef SIP_RUN
3282
3291 static bool compare( const QgsPolylineXY &p1, const QgsPolylineXY &p2, double epsilon = 4 * std::numeric_limits<double>::epsilon() );
3292
3301 static bool compare( const QgsPolygonXY &p1, const QgsPolygonXY &p2, double epsilon = 4 * std::numeric_limits<double>::epsilon() );
3302
3312 static bool compare( const QgsMultiPolygonXY &p1, const QgsMultiPolygonXY &p2, double epsilon = 4 * std::numeric_limits<double>::epsilon() );
3313#else
3314// clang-format off
3315
3334 static bool compare( PyObject *obj1, PyObject *obj2, double epsilon = 4 * std::numeric_limits<double>::epsilon() );
3335 % MethodCode
3336 {
3337 sipRes = false;
3338 int state0;
3339 int state1;
3340 int sipIsErr = 0;
3341
3342 if ( PyList_Check( a0 ) && PyList_Check( a1 ) && PyList_GET_SIZE( a0 ) && PyList_GET_SIZE( a1 ) )
3343 {
3344 PyObject *o0 = PyList_GetItem( a0, 0 );
3345 PyObject *o1 = PyList_GetItem( a1, 0 );
3346 if ( o0 && o1 )
3347 {
3348 // compare polyline - polyline
3349 if ( sipCanConvertToType( o0, sipType_QgsPointXY, SIP_NOT_NONE ) && sipCanConvertToType( o1, sipType_QgsPointXY, SIP_NOT_NONE ) && sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) && sipCanConvertToType( a1, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
3350 {
3351 QgsPolylineXY *p0;
3352 QgsPolylineXY *p1;
3353 p0 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
3354 p1 = reinterpret_cast<QgsPolylineXY *>( sipConvertToType( a1, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
3355 if ( !sipIsErr )
3356 {
3357 sipRes = QgsGeometry::compare( *p0, *p1, a2 );
3358 }
3359 sipReleaseType( p0, sipType_QVector_0100QgsPointXY, state0 );
3360 sipReleaseType( p1, sipType_QVector_0100QgsPointXY, state1 );
3361 }
3362 else if ( PyList_Check( o0 ) && PyList_Check( o1 ) && PyList_GET_SIZE( o0 ) && PyList_GET_SIZE( o1 ) )
3363 {
3364 PyObject *oo0 = PyList_GetItem( o0, 0 );
3365 PyObject *oo1 = PyList_GetItem( o1, 0 );
3366 if ( oo0 && oo1 )
3367 {
3368 // compare polygon - polygon
3369 if ( sipCanConvertToType( oo0, sipType_QgsPointXY, SIP_NOT_NONE ) && sipCanConvertToType( oo1, sipType_QgsPointXY, SIP_NOT_NONE ) && sipCanConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) && sipCanConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
3370 {
3371 QgsPolygonXY *p0;
3372 QgsPolygonXY *p1;
3373 p0 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
3374 p1 = reinterpret_cast<QgsPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
3375 if ( !sipIsErr )
3376 {
3377 sipRes = QgsGeometry::compare( *p0, *p1, a2 );
3378 }
3379 sipReleaseType( p0, sipType_QVector_0600QVector_0100QgsPointXY, state0 );
3380 sipReleaseType( p1, sipType_QVector_0600QVector_0100QgsPointXY, state1 );
3381 }
3382 else if ( PyList_Check( oo0 ) && PyList_Check( oo1 ) && PyList_GET_SIZE( oo0 ) && PyList_GET_SIZE( oo1 ) )
3383 {
3384 PyObject *ooo0 = PyList_GetItem( oo0, 0 );
3385 PyObject *ooo1 = PyList_GetItem( oo1, 0 );
3386 if ( ooo0 && ooo1 )
3387 {
3388 // compare multipolygon - multipolygon
3389 if ( sipCanConvertToType( ooo0, sipType_QgsPointXY, SIP_NOT_NONE ) && sipCanConvertToType( ooo1, sipType_QgsPointXY, SIP_NOT_NONE ) && sipCanConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) && sipCanConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
3390 {
3393 p0 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
3394 p1 = reinterpret_cast<QgsMultiPolygonXY *>( sipConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
3395 if ( !sipIsErr )
3396 {
3397 sipRes = QgsGeometry::compare( *p0, *p1, a2 );
3398 }
3399 sipReleaseType( p0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state0 );
3400 sipReleaseType( p1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state1 );
3401 }
3402 }
3403 }
3404 }
3405 }
3406 }
3407 }
3408 }
3409 % End
3410// clang-format on
3411#endif
3412
3428 QgsGeometry smooth( unsigned int iterations = 1, double offset = 0.25, double minimumDistance = -1.0, double maxAngle = 180.0 ) const;
3429
3469 static QgsGeometryEngine *createGeometryEngine( const QgsAbstractGeometry *geometry, double precision = 0.0, Qgis::GeosCreationFlags flags = Qgis::GeosCreationFlag::SkipEmptyInteriorRings ) SIP_FACTORY;
3470
3476 static void convertPointList( const QVector<QgsPointXY> &input, QgsPointSequence &output );
3477
3483 static void convertPointList( const QgsPointSequence &input, QVector<QgsPointXY> &output );
3484
3486 operator QVariant() const
3487 {
3488 return QVariant::fromValue( *this );
3489 }
3490
3496 {
3497 Chamfer = 1,
3498 Fillet,
3499 };
3500#ifndef SIP_RUN
3501 Q_ENUM( ChamferFilletOperationType )
3502#endif
3503
3520 QgsGeometry fillet( int vertexIndex, double radius, int segments = 8 ) const;
3521
3540 static QgsGeometry fillet( const QgsPoint &segment1Start, const QgsPoint &segment1End, const QgsPoint &segment2Start, const QgsPoint &segment2End, double radius, int segments = 8 ) SIP_THROW( QgsInvalidArgumentException );
3541
3555 QgsGeometry chamfer( int vertexIndex, double distance1, double distance2 = -1.0 ) const;
3556
3575 static QgsGeometry chamfer( const QgsPoint &segment1Start, const QgsPoint &segment1End, const QgsPoint &segment2Start, const QgsPoint &segment2End, double distance1, double distance2 = -1.0 ) SIP_THROW( QgsInvalidArgumentException );
3576
3577
3578 private:
3579 QgsGeometryPrivate *d; //implicitly shared data pointer
3580
3582 mutable QString mLastError;
3583
3588 void detach();
3589
3594 void reset( std::unique_ptr< QgsAbstractGeometry > newGeometry );
3595
3596 static void convertPolygon( const QgsPolygon &input, QgsPolygonXY &output );
3597
3599 QgsGeometry convertToPoint( bool destMultipart ) const;
3601 QgsGeometry convertToLine( bool destMultipart ) const;
3603 QgsGeometry convertToPolygon( bool destMultipart ) const;
3604
3616 std::unique_ptr< QgsLineString > smoothLine( const QgsLineString &line, unsigned int iterations = 1, double offset = 0.25, double minimumDistance = -1, double maxAngle = 180.0 ) const;
3617
3629 std::unique_ptr< QgsPolygon > smoothPolygon( const QgsPolygon &polygon, unsigned int iterations = 1, double offset = 0.25, double minimumDistance = -1, double maxAngle = 180.0 ) const;
3630
3631 QgsGeometry doChamferFillet( ChamferFilletOperationType op, int vertexIndex, double distance1, double distance2, int segments ) const;
3632
3634
3635}; // class QgsGeometry
3636
3638
3640CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsGeometry &geometry );
3642CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsGeometry &geometry );
3643
3644#endif
Provides global constants and enumerations for use throughout the application.
Definition qgis.h:62
CoverageCleanOverlapMergeStrategy
Merge strategies for coverage cleaning operations.
Definition qgis.h:6967
@ LongestBorder
Polygon with longest common border is selected to merge overlapping polygons into.
Definition qgis.h:6968
@ CounterClockwise
Counter-clockwise direction.
Definition qgis.h:3650
@ Clockwise
Clockwise direction.
Definition qgis.h:3649
GeometryOperationResult
Success or failure of a geometry operation.
Definition qgis.h:2192
QFlags< GeometryValidityFlag > GeometryValidityFlags
Geometry validity flags.
Definition qgis.h:2226
GeometryValidationEngine
Available engines for validating geometries.
Definition qgis.h:2235
@ QgisInternal
Use internal QgsGeometryValidator method.
Definition qgis.h:2236
@ SkipEmptyInteriorRings
Skip any empty polygon interior ring.
Definition qgis.h:2313
QFlags< GeosCreationFlag > GeosCreationFlags
Geos geometry creation behavior flags.
Definition qgis.h:2322
GeoJsonProfile
GeoJson export Profile according to OGC Features and Geometries JSON - Part 1: Core https://docs....
Definition qgis.h:5066
@ Legacy
Legacy GeoJson profile used in QGIS prior to 4.2, which included some non-standard extensions and dev...
Definition qgis.h:5067
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
Definition qgis.h:379
@ Point
Points.
Definition qgis.h:380
@ Line
Lines.
Definition qgis.h:381
@ Polygon
Polygons.
Definition qgis.h:382
@ Unknown
Unknown types.
Definition qgis.h:383
static const double DEFAULT_SEGMENT_EPSILON
Default snapping tolerance for segments.
Definition qgis.h:7108
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:294
@ Point
Point.
Definition qgis.h:296
@ Unknown
Unknown.
Definition qgis.h:295
TransformDirection
Indicates the direction (forward or inverse) of a transform.
Definition qgis.h:2862
@ Forward
Forward transform (from source to destination).
Definition qgis.h:2863
The part_iterator class provides an STL-style iterator for const references to geometry parts.
The part_iterator class provides an STL-style iterator for geometry parts.
The vertex_iterator class provides an STL-style iterator for vertices.
Abstract base class for all geometries.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
@ MaximumAngle
Maximum angle between generating radii (lines from arc center to output vertices).
virtual const QgsAbstractGeometry * simplifiedTypeRef() const
Returns a reference to the simplest lossless representation of this geometry, e.g.
QFlags< WkbFlag > WkbFlags
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
A 3-dimensional box composed of x, y, z coordinates.
Definition qgsbox3d.h:45
Compound curve geometry type.
A const WKB pointer.
Definition qgswkbptr.h:211
Handles coordinate transforms between two coordinate systems.
Encapsulates parameters for a coverage cleaning operation.
void setSnappingDistance(double distance)
Sets the snapping distance.
double maximumGapWidth() const
Returns the maximum gap width.
Qgis::CoverageCleanOverlapMergeStrategy overlapMergeStrategy() const
Returns the overlap merge strategy to use during cleaning.
double snappingDistance() const
Returns the snapping distance.
void setOverlapMergeStrategy(Qgis::CoverageCleanOverlapMergeStrategy strategy)
Sets the overlap merge strategy to use during cleaning.
void setMaximumGapWidth(double width)
Sets the maximum gap width.
Custom exception class for Coordinate Reference System related exceptions.
Abstract base class for curved geometry type.
Definition qgscurve.h:36
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
Java-style iterator for const traversal of parts of a geometry.
A geometry engine is a low-level representation of a QgsAbstractGeometry object, optimised for use wi...
Encapsulates parameters under which a geometry operation is performed.
double gridSize() const
Returns the grid size which will be used to snap vertices of a geometry.
void setGridSize(double size)
Sets the grid size which will be used to snap vertices of a geometry.
Java-style iterator for traversal of parts of a geometry.
A geometry error.
Error(const QString &m)
Error(const QString &m, const QgsPointXY &p)
bool operator==(const QgsGeometry::Error &other) const
A geometry is the spatial representation of a feature.
double closestSegmentWithContext(const QgsPointXY &point, QgsPointXY &minDistPoint, int &nextVertexIndex, int *leftOrRightOfSegment=nullptr, double epsilon=Qgis::DEFAULT_SEGMENT_EPSILON) const
Searches for the closest segment of geometry to the given point.
QVector< QgsPointXY > randomPointsInPolygon(int count, const std::function< bool(const QgsPointXY &) > &acceptPoint, unsigned long seed=0, QgsFeedback *feedback=nullptr, int maxTriesPerPoint=0) const
Returns a list of count random points generated inside a (multi)polygon geometry (if acceptPoint is s...
double hausdorffDistanceDensify(const QgsGeometry &geom, double densifyFraction) const
Returns the Hausdorff distance between this geometry and geom.
double area3D() const
Returns the 3-dimensional surface area of the geometry.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
void adjacentVertices(int atVertex, int &beforeVertex, int &afterVertex) const
Returns the indexes of the vertices before and after the given vertex index.
QVector< QgsPointXY > randomPointsInPolygon(int count, unsigned long seed=0, QgsFeedback *feedback=nullptr) const
Returns a list of count random points generated inside a (multi)polygon geometry.
bool deleteVertex(int atVertex)
Deletes the vertex at the given position number and item (first number is index 0).
double length() const
Returns the planar, 2-dimensional length of geometry.
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.
QgsVertexIterator vertices() const
Returns a read-only, Java-style iterator for traversal of vertices of all the geometry,...
ChamferFilletOperationType
Privatly used in chamfer/fillet functions.
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
static QgsGeometry collectTinPatches(const QVector< QgsGeometry > &geometries)
Collects all patches from a list of TIN or Triangle geometries into a single TIN geometry.
bool addTopologicalPoint(const QgsPoint &point, double snappingTolerance=1e-8, double segmentSearchEpsilon=1e-12)
Adds a vertex to the segment which intersect point but don't already have a vertex there.
bool isExactlyEqual(const QgsGeometry &geometry, Qgis::GeometryBackend backend=Qgis::GeometryBackend::QGIS) const
Compares the geometry with another geometry using the specified backend.
QgsGeometry nearestPoint(const QgsGeometry &other) const
Returns the nearest (closest) point on this geometry to another geometry.
static QgsGeometry collectGeometry(const QVector< QgsGeometry > &geometries)
Creates a new multipart geometry from a list of QgsGeometry objects.
static QgsGeometry fromMultiPolylineXY(const QgsMultiPolylineXY &multiline)
Creates a new geometry from a QgsMultiPolylineXY object.
double frechetDistance(const QgsGeometry &geom) const
Returns the Fréchet distance between this geometry and geom, restricted to discrete points for both g...
bool isAxisParallelRectangle(double maximumDeviation, bool simpleRectanglesOnly=false) const
Returns true if the geometry is a polygon that is almost an axis-parallel rectangle.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
static QgsGeometry fromPolylineXY(const QgsPolylineXY &polyline)
Creates a new LineString geometry from a list of QgsPointXY points.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
QgsPointXY closestVertex(const QgsPointXY &point, int &closestVertexIndex, int &previousVertexIndex, int &nextVertexIndex, double &sqrDist) const
Returns the vertex closest to the given point, the corresponding vertex index, squared distance snap ...
double distance(const QgsGeometry &geom) const
Returns the minimum distance between this geometry and another geometry.
static QgsGeometry fromMultiPointXY(const QgsMultiPointXY &multipoint)
Creates a new geometry from a QgsMultiPointXY object.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
friend class QgsInternalGeometryEngine
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static Q_INVOKABLE QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
QgsAbstractGeometry::part_iterator parts_begin()
Returns STL-style iterator pointing to the first part of the geometry.
Q_DECL_DEPRECATED bool equals(const QgsGeometry &geometry) const
Test if this geometry is exactly equal to another geometry.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
bool insertVertex(double x, double y, int beforeVertex)
Insert a new vertex before the given vertex index, ring and item (first number is index 0) If the req...
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
Qgis::GeometryOperationResult addRing(const QVector< QgsPointXY > &ring)
Adds a new ring to this geometry.
Qgis::GeometryType type
bool isSimple() const
Determines whether the geometry is simple (according to OGC definition), i.e.
static QgsGeometry fromPolyline(const QgsPolyline &polyline)
Creates a new LineString geometry from a list of QgsPoint points.
double area() const
Returns the planar, 2-dimensional area of the geometry.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
Qgis::AngularDirection polygonOrientation() const
Returns the orientation of the polygon.
double hausdorffDistance(const QgsGeometry &geom) const
Returns the Hausdorff distance between this geometry and geom.
bool deleteVertices(const QSet< int > &atVertices)
Deletes vertices at the given positions (first number is index 0).
Q_DECL_DEPRECATED Qgis::GeometryOperationResult addPart(const QVector< QgsPointXY > &points, Qgis::GeometryType geomType=Qgis::GeometryType::Unknown)
Adds a new part to a the geometry.
QgsGeometryPartIterator parts()
Returns Java-style iterator for traversal of parts of the geometry.
void set(QgsAbstractGeometry *geometry)
Sets the underlying geometry store.
static QgsGeometry fromPolygonXY(const QgsPolygonXY &polygon)
Creates a new geometry from a QgsPolygonXY.
double sqrDistToVertexAt(QgsPointXY &point, int atVertex) const
Returns the squared Cartesian distance between the given point to the given vertex index (vertex at t...
void fromWkb(unsigned char *wkb, int length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length.
static QgsGeometry fromMultiPolygonXY(const QgsMultiPolygonXY &multipoly)
Creates a new geometry from a QgsMultiPolygonXY.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
bool isPolygonClockwise() const
Returns True if the Polygon is clockwise.
double distanceToVertex(int vertex) const
Returns the distance along this geometry from its first vertex to the specified vertex.
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
QgsAbstractGeometry::part_iterator parts_end()
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
bool isFuzzyEqual(const QgsGeometry &geometry, double epsilon=1e-4, Qgis::GeometryBackend backend=Qgis::GeometryBackend::QGIS) const
Compares the geometry with another geometry within the tolerance epsilon using the specified backend.
static QgsGeometry createWedgeBuffer(const QgsPoint &center, double azimuth, double angularWidth, double outerRadius, double innerRadius=0)
Creates a wedge shaped buffer from a center point.
double frechetDistanceDensify(const QgsGeometry &geom, double densifyFraction) const
Returns the Fréchet distance between this geometry and geom, restricted to discrete points for both g...
bool isTopologicallyEqual(const QgsGeometry &geometry, Qgis::GeometryBackend backend=Qgis::GeometryBackend::GEOS) const
Compares the geometry with another geometry using the specified backend.
QgsGeometryConstPartIterator constParts() const
Returns Java-style iterator for traversal of parts of the geometry.
bool isPolygonCounterClockwise() const
Returns True if the Polygon is counter-clockwise.
Qgis::GeometryOperationResult addPartV2(const QVector< QgsPointXY > &points, Qgis::WkbType wkbType=Qgis::WkbType::Unknown)
Adds a new part to a the geometry.
Qgis::GeometryOperationResult rotate(double rotation, const QgsPointXY &center)
Rotate this geometry around the Z axis.
Qgis::GeometryOperationResult translate(double dx, double dy, double dz=0.0, double dm=0.0)
Translates this geometry by dx, dy, dz and dm.
double angleAtVertex(int vertex) const
Returns the bisector angle for this geometry at the specified vertex.
double closestVertexWithContext(const QgsPointXY &point, int &atVertex) const
Searches for the closest vertex in this geometry to the given point.
Q_DECL_DEPRECATED Qgis::GeometryOperationResult splitGeometry(const QVector< QgsPointXY > &splitLine, QVector< QgsGeometry > &newGeometries, bool topological, QVector< QgsPointXY > &topologyTestPoints, bool splitFeature=true)
Splits this geometry according to a given line.
bool toggleCircularAtVertex(int atVertex)
Converts the vertex at the given position from/to circular.
Qgis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.).
bool moveVertex(double x, double y, int atVertex)
Moves the vertex at the given position number and item (first number is index 0) to the given coordin...
Q_DECL_DEPRECATED bool isGeosEqual(const QgsGeometry &) const
Compares the geometry with another geometry using GEOS.
static QgsGeometry fromBox3D(const QgsBox3D &box)
Creates a new geometry from a QgsBox3D object Returns a 2D polygon geometry if the box is purely 2d,...
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
static QgsGeometry createWedgeBufferFromAngles(const QgsPoint &center, double startAngle, double endAngle, double outerRadius, double innerRadius=0)
Creates a wedge shaped buffer from a center point.
QgsGeometry removeInteriorRings(double minimumAllowedArea=-1) const
Removes the interior rings from a (multi)polygon geometry.
static QgsGeometry fromPoint(const QgsPoint &point)
Creates a new geometry from a QgsPoint object.
QgsGeometry shortestLine(const QgsGeometry &other) const
Returns the shortest line joining this geometry to another geometry.
Custom exception class when argument are invalid.
Line string geometry type, with support for z-dimension and m-values.
Perform transforms between map coordinates and device coordinates.
Custom exception class which is raised when an operation is not supported.
Represents a 2D point.
Definition qgspointxy.h:62
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:53
Polygon geometry type.
Definition qgspolygon.h:37
A rectangle specified with double values.
Represents a vector layer which manages a vector based dataset.
Java-style iterator for traversal of vertices of a geometry.
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
static Q_INVOKABLE QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
static Q_INVOKABLE bool isMultiType(Qgis::WkbType type)
Returns true if the WKB type is a multi type.
As part of the API refactoring and improvements which landed in QGIS
#define SIP_TYPEHINT(type)
Definition qgis_sip.h:237
#define SIP_IN
Definition qgis_sip.h:70
#define SIP_DEPRECATED
Definition qgis_sip.h:113
#define SIP_SKIP
Definition qgis_sip.h:133
#define SIP_PYNAME(name)
Definition qgis_sip.h:88
#define SIP_PYARGREMOVE
Definition qgis_sip.h:158
#define SIP_TRANSFER
Definition qgis_sip.h:35
#define SIP_OUT
Definition qgis_sip.h:57
#define SIP_HOLDGIL
Definition qgis_sip.h:178
#define SIP_FACTORY
Definition qgis_sip.h:83
#define SIP_THROW(name,...)
Definition qgis_sip.h:210
QVector< QgsPoint > QgsPointSequence
Q_DECLARE_METATYPE(QgsDatabaseQueryLogEntry)
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item.
Definition qgsgeometry.h:92
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
Definition qgsgeometry.h:98
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
Definition qgsgeometry.h:63
QVector< QgsPolyline > QgsMultiPolyline
Multi polyline represented as a vector of polylines.
Definition qgsgeometry.h:85
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
QgsPointSequence QgsPolyline
Polyline as represented as a vector of points.
Definition qgsgeometry.h:72
Utility class for identifying a unique vertex within a geometry.
Definition qgsvertexid.h:35