QGIS API Documentation 3.41.0-Master (88383c3d16f)
Loading...
Searching...
No Matches
qgsgeos.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsgeos.h
3 -------------------------------------------------------------------
4Date : 22 Sept 2014
5Copyright : (C) 2014 by Marco Hugentobler
6email : marco.hugentobler at sourcepole dot com
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 QGSGEOS_H
17#define QGSGEOS_H
18
19#include "qgis_core.h"
20#include "qgis_sip.h"
21#include "qgsgeometryengine.h"
22#include "qgsgeometry.h"
23#include "qgsconfig.h"
24#include <geos_c.h>
25
26class QgsLineString;
27class QgsPolygon;
28class QgsGeometry;
30
31#if !defined(USE_THREAD_LOCAL) || defined(Q_OS_WIN)
32#include <QThreadStorage>
33#endif
34
35#ifndef SIP_RUN
43class CORE_EXPORT QgsGeosContext
44{
45 public:
46
49
53 static GEOSContextHandle_t get();
54
55 private:
56 GEOSContextHandle_t mContext = nullptr;
57
63#if defined(USE_THREAD_LOCAL) && !defined(Q_OS_WIN)
64 static thread_local QgsGeosContext sGeosContext;
65#else
66 static QThreadStorage< QgsGeosContext * > sGeosContext;
67#endif
68};
69
74namespace geos
75{
76
81 struct GeosDeleter
82 {
83
88 void CORE_EXPORT operator()( GEOSGeometry *geom ) const;
89
94 void CORE_EXPORT operator()( const GEOSPreparedGeometry *geom ) const;
95
100 void CORE_EXPORT operator()( GEOSBufferParams *params ) const;
101
106 void CORE_EXPORT operator()( GEOSCoordSequence *sequence ) const;
107 };
108
112 using unique_ptr = std::unique_ptr< GEOSGeometry, GeosDeleter>;
113
117 using prepared_unique_ptr = std::unique_ptr< const GEOSPreparedGeometry, GeosDeleter>;
118
122 using buffer_params_unique_ptr = std::unique_ptr< GEOSBufferParams, GeosDeleter>;
123
127 using coord_sequence_unique_ptr = std::unique_ptr< GEOSCoordSequence, GeosDeleter>;
128
129}
130#endif
131
138class CORE_EXPORT QgsGeos: public QgsGeometryEngine
139{
140 public:
141
150
157 SIP_SKIP static QgsGeometry geometryFromGeos( GEOSGeometry *geos );
158
164 SIP_SKIP static QgsGeometry geometryFromGeos( const geos::unique_ptr &geos );
165
174 std::unique_ptr< QgsAbstractGeometry > makeValid( Qgis::MakeValidMethod method = Qgis::MakeValidMethod::Linework, bool keepCollapsed = false, QString *errorMsg = nullptr ) const SIP_THROW( QgsNotSupportedException );
175
184 SIP_SKIP static Qgis::GeometryOperationResult addPart( QgsGeometry &geometry, GEOSGeometry *newPart );
185
186 void geometryChanged() override;
187 void prepareGeometry() override;
188
189 QgsAbstractGeometry *intersection( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr, const QgsGeometryParameters &parameters = QgsGeometryParameters() ) const override;
190 QgsAbstractGeometry *difference( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr, const QgsGeometryParameters &parameters = QgsGeometryParameters() ) const override;
191
201 std::unique_ptr< QgsAbstractGeometry > clip( const QgsRectangle &rectangle, QString *errorMsg SIP_OUT = nullptr ) const;
202
221 std::unique_ptr< QgsAbstractGeometry > subdivide( int maxNodes, QString *errorMsg SIP_OUT = nullptr, const QgsGeometryParameters &parameters = QgsGeometryParameters() ) const;
222
223 QgsAbstractGeometry *combine( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr, const QgsGeometryParameters &parameters = QgsGeometryParameters() ) const override;
224 QgsAbstractGeometry *combine( const QVector<QgsAbstractGeometry *> &geomList, QString *errorMsg, const QgsGeometryParameters &parameters = QgsGeometryParameters() ) const override;
225 QgsAbstractGeometry *combine( const QVector< QgsGeometry > &, QString *errorMsg = nullptr, const QgsGeometryParameters &parameters = QgsGeometryParameters() ) const override;
226 QgsAbstractGeometry *symDifference( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr, const QgsGeometryParameters &parameters = QgsGeometryParameters() ) const override;
227 QgsAbstractGeometry *buffer( double distance, int segments, QString *errorMsg = nullptr ) const override;
228 QgsAbstractGeometry *buffer( double distance, int segments, Qgis::EndCapStyle endCapStyle, Qgis::JoinStyle joinStyle, double miterLimit, QString *errorMsg = nullptr ) const override;
229
236 SIP_SKIP static geos::unique_ptr buffer( const GEOSGeometry *geometry, double distance, int segments, Qgis::EndCapStyle endCapStyle, Qgis::JoinStyle joinStyle, double miterLimit, QString *errorMsg = nullptr );
237
238 QgsAbstractGeometry *simplify( double tolerance, QString *errorMsg = nullptr ) const override;
239 QgsAbstractGeometry *interpolate( double distance, QString *errorMsg = nullptr ) const override;
240 QgsAbstractGeometry *envelope( QString *errorMsg = nullptr ) const override;
241 QgsPoint *centroid( QString *errorMsg = nullptr ) const override;
242 QgsPoint *pointOnSurface( QString *errorMsg = nullptr ) const override;
243 QgsAbstractGeometry *convexHull( QString *errorMsg = nullptr ) const override;
244 double distance( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
245 bool distanceWithin( const QgsAbstractGeometry *geom, double maxdistance, QString *errorMsg = nullptr ) const override;
246
260 bool contains( double x, double y, QString *errorMsg SIP_OUT = nullptr ) const;
261
275 double distance( double x, double y, QString *errorMsg SIP_OUT = nullptr ) const;
276
296 double hausdorffDistance( const QgsAbstractGeometry *geometry, QString *errorMsg SIP_OUT = nullptr ) const;
297
319 double hausdorffDistanceDensify( const QgsAbstractGeometry *geometry, double densifyFraction, QString *errorMsg SIP_OUT = nullptr ) const;
320
338 double frechetDistance( const QgsAbstractGeometry *geometry, QString *errorMsg SIP_OUT = nullptr ) const SIP_THROW( QgsNotSupportedException );
339
368 double frechetDistanceDensify( const QgsAbstractGeometry *geometry, double densifyFraction, QString *errorMsg SIP_OUT = nullptr ) const SIP_THROW( QgsNotSupportedException );
369
370 bool intersects( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
371 bool touches( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
372 bool crosses( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
373 bool within( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
374 bool overlaps( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
375 bool contains( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
376 bool disjoint( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
377 QString relate( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
378 bool relatePattern( const QgsAbstractGeometry *geom, const QString &pattern, QString *errorMsg = nullptr ) const override;
379 double area( QString *errorMsg = nullptr ) const override;
380 double length( QString *errorMsg = nullptr ) const override;
381 bool isValid( QString *errorMsg = nullptr, bool allowSelfTouchingHoles = false, QgsGeometry *errorLoc = nullptr ) const override;
382 bool isEqual( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
383 bool isEmpty( QString *errorMsg = nullptr ) const override;
384 bool isSimple( QString *errorMsg = nullptr ) const override;
385
386 EngineOperationResult splitGeometry( const QgsLineString &splitLine,
387 QVector<QgsGeometry> &newGeometries,
388 bool topological,
389 QgsPointSequence &topologyTestPoints,
390 QString *errorMsg = nullptr, bool skipIntersectionCheck = false ) const override;
391
398 SIP_SKIP static geos::unique_ptr offsetCurve( const GEOSGeometry *geometry, double distance, int segments, Qgis::JoinStyle joinStyle, double miterLimit, QString *errorMsg = nullptr );
399
400 QgsAbstractGeometry *offsetCurve( double distance, int segments, Qgis::JoinStyle joinStyle, double miterLimit, QString *errorMsg = nullptr ) const override;
401
413 std::unique_ptr< QgsAbstractGeometry > singleSidedBuffer( double distance, int segments, Qgis::BufferSide side,
414 Qgis::JoinStyle joinStyle, double miterLimit,
415 QString *errorMsg SIP_OUT = nullptr ) const;
416
446 std::unique_ptr< QgsAbstractGeometry > maximumInscribedCircle( double tolerance, QString *errorMsg SIP_OUT = nullptr ) const SIP_THROW( QgsNotSupportedException );
447
477 std::unique_ptr< QgsAbstractGeometry > largestEmptyCircle( double tolerance, const QgsAbstractGeometry *boundary = nullptr, QString *errorMsg SIP_OUT = nullptr ) const SIP_THROW( QgsNotSupportedException );
478
497 std::unique_ptr< QgsAbstractGeometry > minimumWidth( QString *errorMsg SIP_OUT = nullptr ) const SIP_THROW( QgsNotSupportedException );
498
524 double minimumClearance( QString *errorMsg SIP_OUT = nullptr ) const SIP_THROW( QgsNotSupportedException );
525
541 std::unique_ptr< QgsAbstractGeometry > minimumClearanceLine( QString *errorMsg SIP_OUT = nullptr ) const SIP_THROW( QgsNotSupportedException );
542
557 std::unique_ptr< QgsAbstractGeometry > node( QString *errorMsg SIP_OUT = nullptr ) const;
558
576 std::unique_ptr< QgsAbstractGeometry > sharedPaths( const QgsAbstractGeometry *other, QString *errorMsg SIP_OUT = nullptr ) const;
577
587 SIP_SKIP std::unique_ptr< QgsAbstractGeometry > reshapeGeometry( const QgsLineString &reshapeWithLine, EngineOperationResult *errorCode, QString *errorMsg = nullptr ) const;
588
598 std::unique_ptr< QgsAbstractGeometry > mergeLines( QString *errorMsg SIP_OUT = nullptr ) const;
599
610 std::unique_ptr< QgsAbstractGeometry > closestPoint( const QgsGeometry &other, QString *errorMsg SIP_OUT = nullptr ) const;
611
622 std::unique_ptr< QgsAbstractGeometry > shortestLine( const QgsGeometry &other, QString *errorMsg SIP_OUT = nullptr ) const;
623
635 std::unique_ptr< QgsAbstractGeometry > shortestLine( const QgsAbstractGeometry *other, QString *errorMsg SIP_OUT = nullptr ) const;
636
648 double lineLocatePoint( const QgsPoint &point, QString *errorMsg SIP_OUT = nullptr ) const;
649
668 double lineLocatePoint( double x, double y, QString *errorMsg SIP_OUT = nullptr ) const;
669
680 SIP_SKIP static QgsGeometry polygonize( const QVector<const QgsAbstractGeometry *> &geometries, QString *errorMsg = nullptr );
681
703 std::unique_ptr< QgsAbstractGeometry > voronoiDiagram( const QgsAbstractGeometry *extent = nullptr, double tolerance = 0.0, bool edgesOnly = false, QString *errorMsg SIP_OUT = nullptr ) const;
704
721 std::unique_ptr< QgsAbstractGeometry > delaunayTriangulation( double tolerance = 0.0, bool edgesOnly = false, QString *errorMsg SIP_OUT = nullptr ) const;
722
739 std::unique_ptr< QgsAbstractGeometry > constrainedDelaunayTriangulation( QString *errorMsg SIP_OUT = nullptr ) const SIP_THROW( QgsNotSupportedException );
740
768 std::unique_ptr< QgsAbstractGeometry > concaveHull( double targetPercent, bool allowHoles = false, QString *errorMsg SIP_OUT = nullptr ) const SIP_THROW( QgsNotSupportedException );
769
791 SIP_SKIP Qgis::CoverageValidityResult validateCoverage( double gapWidth, std::unique_ptr< QgsAbstractGeometry > *invalidEdges, QString *errorMsg = nullptr ) const SIP_THROW( QgsNotSupportedException );
792
816 std::unique_ptr< QgsAbstractGeometry > simplifyCoverageVW( double tolerance, bool preserveBoundary, QString *errorMsg SIP_OUT = nullptr ) const SIP_THROW( QgsNotSupportedException );
817
833 std::unique_ptr< QgsAbstractGeometry > unionCoverage( QString *errorMsg SIP_OUT = nullptr ) const;
834
840 SIP_SKIP static std::unique_ptr< QgsAbstractGeometry > fromGeos( const GEOSGeometry *geos );
841
845 SIP_SKIP static std::unique_ptr< QgsPolygon > fromGeosPolygon( const GEOSGeometry *geos );
846
854 SIP_SKIP static geos::unique_ptr asGeos( const QgsGeometry &geometry, double precision = 0, Qgis::GeosCreationFlags flags = Qgis::GeosCreationFlags() );
855
864 SIP_SKIP static geos::unique_ptr asGeos( const QgsAbstractGeometry *geometry, double precision = 0, Qgis::GeosCreationFlags flags = Qgis::GeosCreationFlags() );
865
869 SIP_SKIP static QgsPoint coordSeqPoint( const GEOSCoordSequence *cs, int i, bool hasZ, bool hasM );
870
871 private:
872
873#ifdef SIP_RUN
874 QgsGeos( const QgsGeos & );
875#endif
876
877 mutable geos::unique_ptr mGeos;
878 geos::prepared_unique_ptr mGeosPrepared;
879 double mPrecision = 0.0;
880
881 enum Overlay
882 {
883 OverlayIntersection,
884 OverlayDifference,
885 OverlayUnion,
886 OverlaySymDifference
887 };
888
889 enum Relation
890 {
891 RelationIntersects,
892 RelationTouches,
893 RelationCrosses,
894 RelationWithin,
895 RelationOverlaps,
896 RelationContains,
897 RelationDisjoint
898 };
899
900 //geos util functions
901 void cacheGeos( Qgis::GeosCreationFlags flags ) const;
902
910 std::unique_ptr< QgsAbstractGeometry > overlay( const QgsAbstractGeometry *geom, Overlay op, QString *errorMsg = nullptr, const QgsGeometryParameters &parameters = QgsGeometryParameters() ) const;
911 bool relation( const QgsAbstractGeometry *geom, Relation r, QString *errorMsg = nullptr ) const;
912 static GEOSCoordSequence *createCoordinateSequence( const QgsCurve *curve, double precision, bool forceClose = false );
913 static std::unique_ptr< QgsLineString > sequenceToLinestring( const GEOSGeometry *geos, bool hasZ, bool hasM );
914 static int numberOfGeometries( GEOSGeometry *g );
915 static geos::unique_ptr nodeGeometries( const GEOSGeometry *splitLine, const GEOSGeometry *geom );
916 int mergeGeometriesMultiTypeSplit( std::vector<geos::unique_ptr> &splitResult ) const;
917
921 static geos::unique_ptr createGeosCollection( int typeId, std::vector<geos::unique_ptr> &geoms );
922
923 static geos::unique_ptr createGeosPointXY( double x, double y, bool hasZ, double z, bool hasM, double m, int coordDims, double precision, Qgis::GeosCreationFlags flags = Qgis::GeosCreationFlags() );
924 static geos::unique_ptr createGeosPoint( const QgsAbstractGeometry *point, int coordDims, double precision, Qgis::GeosCreationFlags flags = Qgis::GeosCreationFlags() );
925 static geos::unique_ptr createGeosLinestring( const QgsAbstractGeometry *curve, double precision, Qgis::GeosCreationFlags flags = Qgis::GeosCreationFlags() );
926 static geos::unique_ptr createGeosPolygon( const QgsAbstractGeometry *poly, double precision, Qgis::GeosCreationFlags flags = Qgis::GeosCreationFlags() );
927
928 //utils for geometry split
929 bool topologicalTestPointsSplit( const GEOSGeometry *splitLine, QgsPointSequence &testPoints, QString *errorMsg = nullptr ) const;
930 geos::unique_ptr linePointDifference( GEOSGeometry *GEOSsplitPoint ) const;
931 EngineOperationResult splitLinearGeometry( const GEOSGeometry *splitLine, QVector<QgsGeometry > &newGeometries, bool skipIntersectionCheck ) const;
932 EngineOperationResult splitPolygonGeometry( const GEOSGeometry *splitLine, QVector<QgsGeometry > &newGeometries, bool skipIntersectionCheck ) const;
933
934 //utils for reshape
935 static geos::unique_ptr reshapeLine( const GEOSGeometry *line, const GEOSGeometry *reshapeLineGeos, double precision );
936 static geos::unique_ptr reshapePolygon( const GEOSGeometry *polygon, const GEOSGeometry *reshapeLineGeos, double precision );
937 static int lineContainedInLine( const GEOSGeometry *line1, const GEOSGeometry *line2 );
938 static int pointContainedInLine( const GEOSGeometry *point, const GEOSGeometry *line );
939 static int geomDigits( const GEOSGeometry *geom );
940 void subdivideRecursive( const GEOSGeometry *currentPart, int maxNodes, int depth, QgsGeometryCollection *parts, const QgsRectangle &clipRect, double gridSize = -1 ) const;
941};
942
944
945#ifndef SIP_RUN
946
947class GEOSException : public std::runtime_error
948{
949 public:
950 explicit GEOSException( const QString &message )
951 : std::runtime_error( message.toUtf8().constData() )
952 {
953 }
954};
955
956#endif
957
959
960#endif // QGSGEOS_H
BufferSide
Side of line to buffer.
Definition qgis.h:2026
GeometryOperationResult
Success or failure of a geometry operation.
Definition qgis.h:1972
@ SkipEmptyInteriorRings
Skip any empty polygon interior ring.
QFlags< GeosCreationFlag > GeosCreationFlags
Geos geometry creation behavior flags.
Definition qgis.h:2075
JoinStyle
Join styles for buffers.
Definition qgis.h:2051
EndCapStyle
End cap styles for buffers.
Definition qgis.h:2038
CoverageValidityResult
Coverage validity results.
Definition qgis.h:2084
MakeValidMethod
Algorithms to use when repairing invalid geometries.
Definition qgis.h:2097
@ Linework
Combines all rings into a set of noded lines and then extracts valid polygons from that linework.
Abstract base class for all geometries.
Abstract base class for curved geometry type.
Definition qgscurve.h:35
A geometry engine is a low-level representation of a QgsAbstractGeometry object, optimised for use wi...
EngineOperationResult
Success or failure of a geometry operation.
Encapsulates parameters under which a geometry operation is performed.
A geometry is the spatial representation of a feature.
Used to create and store a proj context object, correctly freeing the context upon destruction.
Definition qgsgeos.h:44
static GEOSContextHandle_t get()
Returns a thread local instance of a GEOS context, safe for use in the current thread.
Does vector analysis using the GEOS library and handles import, export, and exception handling.
Definition qgsgeos.h:139
Line string geometry type, with support for z-dimension and m-values.
Custom exception class which is raised when an operation is not supported.
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:49
Polygon geometry type.
Definition qgspolygon.h:33
A rectangle specified with double values.
Contains geos related utilities and functions.
Definition qgsgeos.h:75
#define SIP_SKIP
Definition qgis_sip.h:126
#define SIP_OUT
Definition qgis_sip.h:58
#define SIP_THROW(name,...)
Definition qgis_sip.h:203
QVector< QgsPoint > QgsPointSequence
int precision
struct GEOSGeom_t GEOSGeometry
Definition util.h:41