QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsgeos.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgeos.h
3  -------------------------------------------------------------------
4 Date : 22 Sept 2014
5 Copyright : (C) 2014 by Marco Hugentobler
6 email : 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 #define SIP_NO_FILE
20 
21 #include "qgis_core.h"
22 #include "qgsgeometryengine.h"
23 #include "qgsgeometry.h"
24 #include <geos_c.h>
25 
26 #if defined(GEOS_VERSION_MAJOR) && (GEOS_VERSION_MAJOR<3)
27 #define GEOSGeometry struct GEOSGeom_t
28 #define GEOSCoordSequence struct GEOSCoordSeq_t
29 #endif
30 
31 class QgsLineString;
32 class QgsPolygon;
33 class QgsGeometry;
35 
41 namespace geos
42 {
43 
48  struct GeosDeleter
49  {
50 
55  void CORE_EXPORT operator()( GEOSGeometry *geom );
56 
61  void CORE_EXPORT operator()( const GEOSPreparedGeometry *geom );
62 
67  void CORE_EXPORT operator()( GEOSBufferParams *params );
68 
73  void CORE_EXPORT operator()( GEOSCoordSequence *sequence );
74  };
75 
79  using unique_ptr = std::unique_ptr< GEOSGeometry, GeosDeleter>;
80 
84  using prepared_unique_ptr = std::unique_ptr< const GEOSPreparedGeometry, GeosDeleter>;
85 
89  using buffer_params_unique_ptr = std::unique_ptr< GEOSBufferParams, GeosDeleter>;
90 
94  using coord_sequence_unique_ptr = std::unique_ptr< GEOSCoordSequence, GeosDeleter>;
95 
96 }
97 
103 class CORE_EXPORT QgsGeos: public QgsGeometryEngine
104 {
105  public:
106 
112  QgsGeos( const QgsAbstractGeometry *geometry, double precision = 0 );
113 
118  static QgsGeometry geometryFromGeos( GEOSGeometry *geos );
119 
123  static QgsGeometry geometryFromGeos( const geos::unique_ptr &geos );
124 
131  static QgsGeometry::OperationResult addPart( QgsGeometry &geometry, GEOSGeometry *newPart );
132 
133  void geometryChanged() override;
134  void prepareGeometry() override;
135 
136  QgsAbstractGeometry *intersection( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
137  QgsAbstractGeometry *difference( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
138 
143  std::unique_ptr< QgsAbstractGeometry > clip( const QgsRectangle &rectangle, QString *errorMsg = nullptr ) const;
144 
159  std::unique_ptr< QgsAbstractGeometry > subdivide( int maxNodes, QString *errorMsg = nullptr ) const;
160 
161  QgsAbstractGeometry *combine( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
162  QgsAbstractGeometry *combine( const QVector<QgsAbstractGeometry *> &geomList, QString *errorMsg ) const override;
163  QgsAbstractGeometry *combine( const QVector< QgsGeometry > &, QString *errorMsg = nullptr ) const override;
164  QgsAbstractGeometry *symDifference( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
165  QgsAbstractGeometry *buffer( double distance, int segments, QString *errorMsg = nullptr ) const override;
166  QgsAbstractGeometry *buffer( double distance, int segments, int endCapStyle, int joinStyle, double miterLimit, QString *errorMsg = nullptr ) const override;
167  QgsAbstractGeometry *simplify( double tolerance, QString *errorMsg = nullptr ) const override;
168  QgsAbstractGeometry *interpolate( double distance, QString *errorMsg = nullptr ) const override;
169  QgsAbstractGeometry *envelope( QString *errorMsg = nullptr ) const override;
170  QgsPoint *centroid( QString *errorMsg = nullptr ) const override;
171  QgsPoint *pointOnSurface( QString *errorMsg = nullptr ) const override;
172  QgsAbstractGeometry *convexHull( QString *errorMsg = nullptr ) const override;
173  double distance( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
174 
190  double hausdorffDistance( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const;
191 
208  double hausdorffDistanceDensify( const QgsAbstractGeometry *geom, double densifyFraction, QString *errorMsg = nullptr ) const;
209 
210  bool intersects( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
211  bool touches( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
212  bool crosses( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
213  bool within( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
214  bool overlaps( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
215  bool contains( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
216  bool disjoint( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
217  QString relate( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
218  bool relatePattern( const QgsAbstractGeometry *geom, const QString &pattern, QString *errorMsg = nullptr ) const override;
219  double area( QString *errorMsg = nullptr ) const override;
220  double length( QString *errorMsg = nullptr ) const override;
221  bool isValid( QString *errorMsg = nullptr, bool allowSelfTouchingHoles = false, QgsGeometry *errorLoc = nullptr ) const override;
222  bool isEqual( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
223  bool isEmpty( QString *errorMsg = nullptr ) const override;
224  bool isSimple( QString *errorMsg = nullptr ) const override;
225 
227  QVector<QgsGeometry> &newGeometries,
228  bool topological,
229  QgsPointSequence &topologyTestPoints,
230  QString *errorMsg = nullptr, bool skipIntersectionCheck = false ) const override;
231 
232  QgsAbstractGeometry *offsetCurve( double distance, int segments, int joinStyle, double miterLimit, QString *errorMsg = nullptr ) const override;
233 
247  std::unique_ptr< QgsAbstractGeometry > singleSidedBuffer( double distance, int segments, int side,
248  int joinStyle, double miterLimit,
249  QString *errorMsg = nullptr ) const;
250 
258  std::unique_ptr< QgsAbstractGeometry > reshapeGeometry( const QgsLineString &reshapeWithLine, EngineOperationResult *errorCode, QString *errorMsg = nullptr ) const;
259 
269  QgsGeometry mergeLines( QString *errorMsg = nullptr ) const;
270 
276  QgsGeometry closestPoint( const QgsGeometry &other, QString *errorMsg = nullptr ) const;
277 
283  QgsGeometry shortestLine( const QgsGeometry &other, QString *errorMsg = nullptr ) const;
284 
295  double lineLocatePoint( const QgsPoint &point, QString *errorMsg = nullptr ) const;
296 
306  static QgsGeometry polygonize( const QVector<const QgsAbstractGeometry *> &geometries, QString *errorMsg = nullptr );
307 
323  QgsGeometry voronoiDiagram( const QgsAbstractGeometry *extent = nullptr, double tolerance = 0.0, bool edgesOnly = false, QString *errorMsg = nullptr ) const;
324 
334  QgsGeometry delaunayTriangulation( double tolerance = 0.0, bool edgesOnly = false, QString *errorMsg = nullptr ) const;
335 
340  static std::unique_ptr< QgsAbstractGeometry > fromGeos( const GEOSGeometry *geos );
341  static std::unique_ptr< QgsPolygon > fromGeosPolygon( const GEOSGeometry *geos );
342 
343 
349  static geos::unique_ptr asGeos( const QgsGeometry &geometry, double precision = 0 );
350 
356  static geos::unique_ptr asGeos( const QgsAbstractGeometry *geometry, double precision = 0 );
357  static QgsPoint coordSeqPoint( const GEOSCoordSequence *cs, int i, bool hasZ, bool hasM );
358 
359  static GEOSContextHandle_t getGEOSHandler();
360 
361 
362  private:
363  mutable geos::unique_ptr mGeos;
364  geos::prepared_unique_ptr mGeosPrepared;
365  double mPrecision = 0.0;
366 
367  enum Overlay
368  {
369  OverlayIntersection,
370  OverlayDifference,
371  OverlayUnion,
372  OverlaySymDifference
373  };
374 
375  enum Relation
376  {
377  RelationIntersects,
378  RelationTouches,
379  RelationCrosses,
380  RelationWithin,
381  RelationOverlaps,
382  RelationContains,
383  RelationDisjoint
384  };
385 
386  //geos util functions
387  void cacheGeos() const;
388  std::unique_ptr< QgsAbstractGeometry > overlay( const QgsAbstractGeometry *geom, Overlay op, QString *errorMsg = nullptr ) const;
389  bool relation( const QgsAbstractGeometry *geom, Relation r, QString *errorMsg = nullptr ) const;
390  static GEOSCoordSequence *createCoordinateSequence( const QgsCurve *curve, double precision, bool forceClose = false );
391  static std::unique_ptr< QgsLineString > sequenceToLinestring( const GEOSGeometry *geos, bool hasZ, bool hasM );
392  static int numberOfGeometries( GEOSGeometry *g );
393  static geos::unique_ptr nodeGeometries( const GEOSGeometry *splitLine, const GEOSGeometry *geom );
394  int mergeGeometriesMultiTypeSplit( QVector<GEOSGeometry *> &splitResult ) const;
395 
399  static geos::unique_ptr createGeosCollection( int typeId, const QVector<GEOSGeometry *> &geoms );
400 
401  static geos::unique_ptr createGeosPointXY( double x, double y, bool hasZ, double z, bool hasM, double m, int coordDims, double precision );
402  static geos::unique_ptr createGeosPoint( const QgsAbstractGeometry *point, int coordDims, double precision );
403  static geos::unique_ptr createGeosLinestring( const QgsAbstractGeometry *curve, double precision );
404  static geos::unique_ptr createGeosPolygon( const QgsAbstractGeometry *poly, double precision );
405 
406  //utils for geometry split
407  bool topologicalTestPointsSplit( const GEOSGeometry *splitLine, QgsPointSequence &testPoints, QString *errorMsg = nullptr ) const;
408  geos::unique_ptr linePointDifference( GEOSGeometry *GEOSsplitPoint ) const;
409  EngineOperationResult splitLinearGeometry( GEOSGeometry *splitLine, QVector<QgsGeometry > &newGeometries, bool skipIntersectionCheck ) const;
410  EngineOperationResult splitPolygonGeometry( GEOSGeometry *splitLine, QVector<QgsGeometry > &newGeometries, bool skipIntersectionCheck ) const;
411 
412  //utils for reshape
413  static geos::unique_ptr reshapeLine( const GEOSGeometry *line, const GEOSGeometry *reshapeLineGeos, double precision );
414  static geos::unique_ptr reshapePolygon( const GEOSGeometry *polygon, const GEOSGeometry *reshapeLineGeos, double precision );
415  static int lineContainedInLine( const GEOSGeometry *line1, const GEOSGeometry *line2 );
416  static int pointContainedInLine( const GEOSGeometry *point, const GEOSGeometry *line );
417  static int geomDigits( const GEOSGeometry *geom );
418  void subdivideRecursive( const GEOSGeometry *currentPart, int maxNodes, int depth, QgsGeometryCollection *parts, const QgsRectangle &clipRect ) const;
419 };
420 
422 
423 
424 class GEOSException : public std::runtime_error
425 {
426  public:
427  explicit GEOSException( const QString &message )
428  : std::runtime_error( message.toUtf8().constData() )
429  {
430  }
431 };
432 
434 
435 #endif // QGSGEOS_H
QgsCurve
Abstract base class for curved geometry type.
Definition: qgscurve.h:36
QgsGeometryEngine::isValid
virtual bool isValid(QString *errorMsg=nullptr, bool allowSelfTouchingHoles=false, QgsGeometry *errorLoc=nullptr) const =0
Returns true if the geometry is valid.
QgsGeometryEngine::touches
virtual bool touches(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if geom touches this.
geos::buffer_params_unique_ptr
std::unique_ptr< GEOSBufferParams, GeosDeleter > buffer_params_unique_ptr
Scoped GEOS buffer params pointer.
Definition: qgsgeos.h:89
QgsPolygon
Polygon geometry type.
Definition: qgspolygon.h:34
QgsGeometryEngine::interpolate
virtual QgsAbstractGeometry * interpolate(double distance, QString *errorMsg=nullptr) const =0
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:38
geos::GeosDeleter::operator()
void CORE_EXPORT operator()(GEOSBufferParams *params)
Destroys the GEOS buffer params params, using the static QGIS geos context.
geos::GeosDeleter
Destroys the GEOS geometry geom, using the static QGIS geos context.
Definition: qgsgeos.h:49
QgsGeometryEngine::relatePattern
virtual bool relatePattern(const QgsAbstractGeometry *geom, const QString &pattern, QString *errorMsg=nullptr) const =0
Tests whether two geometries are related by a specified Dimensional Extended 9 Intersection Model (DE...
geos
Contains geos related utilities and functions.
Definition: qgsgeos.h:42
QgsGeometryEngine::convexHull
virtual QgsAbstractGeometry * convexHull(QString *errorMsg=nullptr) const =0
Calculate the convex hull of this.
QgsGeometryEngine::length
virtual double length(QString *errorMsg=nullptr) const =0
QgsGeometry::OperationResult
OperationResult
Success or failure of a geometry operation.
Definition: qgsgeometry.h:136
QgsGeometryEngine::intersection
virtual QgsAbstractGeometry * intersection(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Calculate the intersection of this and geom.
QgsGeometryEngine::relate
virtual QString relate(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Returns the Dimensional Extended 9 Intersection Model (DE-9IM) representation of the relationship bet...
QgsLineString
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:44
QgsGeometryEngine::buffer
virtual QgsAbstractGeometry * buffer(double distance, int segments, QString *errorMsg=nullptr) const =0
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QgsGeometryEngine::crosses
virtual bool crosses(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if geom crosses this.
QgsGeometryEngine::disjoint
virtual bool disjoint(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if geom is disjoint from this.
QgsGeometryEngine::pointOnSurface
virtual QgsPoint * pointOnSurface(QString *errorMsg=nullptr) const =0
Calculate a point that is guaranteed to be on the surface of this.
geos::unique_ptr
std::unique_ptr< GEOSGeometry, GeosDeleter > unique_ptr
Scoped GEOS pointer.
Definition: qgsgeos.h:79
precision
int precision
Definition: qgswfsgetfeature.cpp:49
QgsGeometryCollection
Geometry collection.
Definition: qgsgeometrycollection.h:36
QgsGeometryEngine::isEmpty
virtual bool isEmpty(QString *errorMsg) const =0
qgsgeometryengine.h
QgsGeometryEngine::geometryChanged
virtual void geometryChanged()=0
Should be called whenever the geometry associated with the engine has been modified and the engine mu...
QgsGeos
Does vector analysis using the geos library and handles import, export, exception handling*.
Definition: qgsgeos.h:104
QgsGeometryEngine::intersects
virtual bool intersects(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if geom intersects this.
QgsGeometryEngine::envelope
virtual QgsAbstractGeometry * envelope(QString *errorMsg=nullptr) const =0
QgsGeometryEngine::combine
virtual QgsAbstractGeometry * combine(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Calculate the combination of this and geom.
geos::GeosDeleter::operator()
void CORE_EXPORT operator()(const GEOSPreparedGeometry *geom)
Destroys the GEOS prepared geometry geom, using the static QGIS geos context.
QgsAbstractGeometry
Abstract base class for all geometries.
Definition: qgsabstractgeometry.h:74
QgsGeometryEngine::symDifference
virtual QgsAbstractGeometry * symDifference(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Calculate the symmetric difference of this and geom.
QgsGeometryEngine::isSimple
virtual bool isSimple(QString *errorMsg=nullptr) const =0
Determines whether the geometry is simple (according to OGC definition).
QgsGeometryEngine::distance
virtual double distance(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Calculates the distance between this and geom.
QgsGeometryEngine::isEqual
virtual bool isEqual(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if this is equal to geom.
QgsGeometryEngine::simplify
virtual QgsAbstractGeometry * simplify(double tolerance, QString *errorMsg=nullptr) const =0
QgsGeometryEngine::offsetCurve
virtual QgsAbstractGeometry * offsetCurve(double distance, int segments, int joinStyle, double miterLimit, QString *errorMsg=nullptr) const =0
QgsGeometryEngine::area
virtual double area(QString *errorMsg=nullptr) const =0
QgsGeometryEngine::prepareGeometry
virtual void prepareGeometry()=0
Prepares the geometry, so that subsequent calls to spatial relation methods are much faster.
qgsgeometry.h
QgsPointSequence
QVector< QgsPoint > QgsPointSequence
Definition: qgsabstractgeometry.h:46
QgsGeometryEngine::within
virtual bool within(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if geom is within this.
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsGeometryEngine::splitGeometry
virtual QgsGeometryEngine::EngineOperationResult splitGeometry(const QgsLineString &splitLine, QVector< QgsGeometry > &newGeometries, bool topological, QgsPointSequence &topologyTestPoints, QString *errorMsg=nullptr, bool skipIntersectionCheck=false) const
Splits this geometry according to a given line.
Definition: qgsgeometryengine.h:261
geos::coord_sequence_unique_ptr
std::unique_ptr< GEOSCoordSequence, GeosDeleter > coord_sequence_unique_ptr
Scoped GEOS coordinate sequence pointer.
Definition: qgsgeos.h:94
geos::prepared_unique_ptr
std::unique_ptr< const GEOSPreparedGeometry, GeosDeleter > prepared_unique_ptr
Scoped GEOS prepared geometry pointer.
Definition: qgsgeos.h:84
QgsGeometryEngine::EngineOperationResult
EngineOperationResult
Success or failure of a geometry operation.
Definition: qgsgeometryengine.h:43
geos::GeosDeleter::operator()
void CORE_EXPORT operator()(GEOSCoordSequence *sequence)
Destroys the GEOS coordinate sequence sequence, using the static QGIS geos context.
geos::GeosDeleter::operator()
void CORE_EXPORT operator()(GEOSGeometry *geom)
Destroys the GEOS geometry geom, using the static QGIS geos context.
QgsGeometryEngine::difference
virtual QgsAbstractGeometry * difference(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Calculate the difference of this and geom.
QgsGeometryEngine::overlaps
virtual bool overlaps(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if geom overlaps this.
QgsGeometryEngine::centroid
virtual QgsPoint * centroid(QString *errorMsg=nullptr) const =0
Calculates the centroid of this.
QgsGeometryEngine
Contains geometry relation and modification algorithms.
Definition: qgsgeometryengine.h:35
QgsGeometryEngine::contains
virtual bool contains(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if geom contains this.