QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
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 
125 #if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=8 )
126 
131  std::unique_ptr< QgsAbstractGeometry > makeValid( QString *errorMsg = nullptr ) const;
132 #endif
133 
140  static Qgis::GeometryOperationResult addPart( QgsGeometry &geometry, GEOSGeometry *newPart );
141 
142  void geometryChanged() override;
143  void prepareGeometry() override;
144 
145  QgsAbstractGeometry *intersection( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
146  QgsAbstractGeometry *difference( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
147 
152  std::unique_ptr< QgsAbstractGeometry > clip( const QgsRectangle &rectangle, QString *errorMsg = nullptr ) const;
153 
168  std::unique_ptr< QgsAbstractGeometry > subdivide( int maxNodes, QString *errorMsg = nullptr ) const;
169 
170  QgsAbstractGeometry *combine( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
171  QgsAbstractGeometry *combine( const QVector<QgsAbstractGeometry *> &geomList, QString *errorMsg ) const override;
172  QgsAbstractGeometry *combine( const QVector< QgsGeometry > &, QString *errorMsg = nullptr ) const override;
173  QgsAbstractGeometry *symDifference( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
174  QgsAbstractGeometry *buffer( double distance, int segments, QString *errorMsg = nullptr ) const override;
175  QgsAbstractGeometry *buffer( double distance, int segments, Qgis::EndCapStyle endCapStyle, Qgis::JoinStyle joinStyle, double miterLimit, QString *errorMsg = nullptr ) const override;
176  QgsAbstractGeometry *simplify( double tolerance, QString *errorMsg = nullptr ) const override;
177  QgsAbstractGeometry *interpolate( double distance, QString *errorMsg = nullptr ) const override;
178  QgsAbstractGeometry *envelope( QString *errorMsg = nullptr ) const override;
179  QgsPoint *centroid( QString *errorMsg = nullptr ) const override;
180  QgsPoint *pointOnSurface( QString *errorMsg = nullptr ) const override;
181  QgsAbstractGeometry *convexHull( QString *errorMsg = nullptr ) const override;
182  double distance( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
183  bool distanceWithin( const QgsAbstractGeometry *geom, double maxdistance, QString *errorMsg = nullptr ) const override;
184 
200  double hausdorffDistance( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const;
201 
218  double hausdorffDistanceDensify( const QgsAbstractGeometry *geom, double densifyFraction, QString *errorMsg = nullptr ) const;
219 
232  double frechetDistance( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const;
233 
256  double frechetDistanceDensify( const QgsAbstractGeometry *geom, double densifyFraction, QString *errorMsg = nullptr ) const;
257 
258  bool intersects( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
259  bool touches( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
260  bool crosses( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
261  bool within( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
262  bool overlaps( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
263  bool contains( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
264  bool disjoint( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
265  QString relate( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
266  bool relatePattern( const QgsAbstractGeometry *geom, const QString &pattern, QString *errorMsg = nullptr ) const override;
267  double area( QString *errorMsg = nullptr ) const override;
268  double length( QString *errorMsg = nullptr ) const override;
269  bool isValid( QString *errorMsg = nullptr, bool allowSelfTouchingHoles = false, QgsGeometry *errorLoc = nullptr ) const override;
270  bool isEqual( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
271  bool isEmpty( QString *errorMsg = nullptr ) const override;
272  bool isSimple( QString *errorMsg = nullptr ) const override;
273 
275  QVector<QgsGeometry> &newGeometries,
276  bool topological,
277  QgsPointSequence &topologyTestPoints,
278  QString *errorMsg = nullptr, bool skipIntersectionCheck = false ) const override;
279 
280  QgsAbstractGeometry *offsetCurve( double distance, int segments, Qgis::JoinStyle joinStyle, double miterLimit, QString *errorMsg = nullptr ) const override;
281 
295  std::unique_ptr< QgsAbstractGeometry > singleSidedBuffer( double distance, int segments, Qgis::BufferSide side,
296  Qgis::JoinStyle joinStyle, double miterLimit,
297  QString *errorMsg = nullptr ) const;
298 
323  std::unique_ptr< QgsAbstractGeometry > maximumInscribedCircle( double tolerance, QString *errorMsg = nullptr ) const;
324 
348  std::unique_ptr< QgsAbstractGeometry > largestEmptyCircle( double tolerance, const QgsAbstractGeometry *boundary = nullptr, QString *errorMsg = nullptr ) const;
349 
364  std::unique_ptr< QgsAbstractGeometry > minimumWidth( QString *errorMsg = nullptr ) const;
365 
387  double minimumClearance( QString *errorMsg = nullptr ) const;
388 
400  std::unique_ptr< QgsAbstractGeometry > minimumClearanceLine( QString *errorMsg = nullptr ) const;
401 
412  std::unique_ptr< QgsAbstractGeometry > node( QString *errorMsg = nullptr ) const;
413 
428  std::unique_ptr< QgsAbstractGeometry > sharedPaths( const QgsAbstractGeometry *other, QString *errorMsg = nullptr ) const;
429 
437  std::unique_ptr< QgsAbstractGeometry > reshapeGeometry( const QgsLineString &reshapeWithLine, EngineOperationResult *errorCode, QString *errorMsg = nullptr ) const;
438 
448  QgsGeometry mergeLines( QString *errorMsg = nullptr ) const;
449 
455  QgsGeometry closestPoint( const QgsGeometry &other, QString *errorMsg = nullptr ) const;
456 
462  QgsGeometry shortestLine( const QgsGeometry &other, QString *errorMsg = nullptr ) const;
463 
469  QgsGeometry shortestLine( const QgsAbstractGeometry *other, QString *errorMsg = nullptr ) const;
470 
481  double lineLocatePoint( const QgsPoint &point, QString *errorMsg = nullptr ) const;
482 
492  static QgsGeometry polygonize( const QVector<const QgsAbstractGeometry *> &geometries, QString *errorMsg = nullptr );
493 
509  QgsGeometry voronoiDiagram( const QgsAbstractGeometry *extent = nullptr, double tolerance = 0.0, bool edgesOnly = false, QString *errorMsg = nullptr ) const;
510 
520  QgsGeometry delaunayTriangulation( double tolerance = 0.0, bool edgesOnly = false, QString *errorMsg = nullptr ) const;
521 
526  static std::unique_ptr< QgsAbstractGeometry > fromGeos( const GEOSGeometry *geos );
527  static std::unique_ptr< QgsPolygon > fromGeosPolygon( const GEOSGeometry *geos );
528 
529 
535  static geos::unique_ptr asGeos( const QgsGeometry &geometry, double precision = 0 );
536 
542  static geos::unique_ptr asGeos( const QgsAbstractGeometry *geometry, double precision = 0 );
543  static QgsPoint coordSeqPoint( const GEOSCoordSequence *cs, int i, bool hasZ, bool hasM );
544 
545  static GEOSContextHandle_t getGEOSHandler();
546 
547 
548  private:
549  mutable geos::unique_ptr mGeos;
550  geos::prepared_unique_ptr mGeosPrepared;
551  double mPrecision = 0.0;
552 
553  enum Overlay
554  {
555  OverlayIntersection,
556  OverlayDifference,
557  OverlayUnion,
558  OverlaySymDifference
559  };
560 
561  enum Relation
562  {
563  RelationIntersects,
564  RelationTouches,
565  RelationCrosses,
566  RelationWithin,
567  RelationOverlaps,
568  RelationContains,
569  RelationDisjoint
570  };
571 
572  //geos util functions
573  void cacheGeos() const;
574  std::unique_ptr< QgsAbstractGeometry > overlay( const QgsAbstractGeometry *geom, Overlay op, QString *errorMsg = nullptr ) const;
575  bool relation( const QgsAbstractGeometry *geom, Relation r, QString *errorMsg = nullptr ) const;
576  static GEOSCoordSequence *createCoordinateSequence( const QgsCurve *curve, double precision, bool forceClose = false );
577  static std::unique_ptr< QgsLineString > sequenceToLinestring( const GEOSGeometry *geos, bool hasZ, bool hasM );
578  static int numberOfGeometries( GEOSGeometry *g );
579  static geos::unique_ptr nodeGeometries( const GEOSGeometry *splitLine, const GEOSGeometry *geom );
580  int mergeGeometriesMultiTypeSplit( QVector<GEOSGeometry *> &splitResult ) const;
581 
585  static geos::unique_ptr createGeosCollection( int typeId, const QVector<GEOSGeometry *> &geoms );
586 
587  static geos::unique_ptr createGeosPointXY( double x, double y, bool hasZ, double z, bool hasM, double m, int coordDims, double precision );
588  static geos::unique_ptr createGeosPoint( const QgsAbstractGeometry *point, int coordDims, double precision );
589  static geos::unique_ptr createGeosLinestring( const QgsAbstractGeometry *curve, double precision );
590  static geos::unique_ptr createGeosPolygon( const QgsAbstractGeometry *poly, double precision );
591 
592  //utils for geometry split
593  bool topologicalTestPointsSplit( const GEOSGeometry *splitLine, QgsPointSequence &testPoints, QString *errorMsg = nullptr ) const;
594  geos::unique_ptr linePointDifference( GEOSGeometry *GEOSsplitPoint ) const;
595  EngineOperationResult splitLinearGeometry( GEOSGeometry *splitLine, QVector<QgsGeometry > &newGeometries, bool skipIntersectionCheck ) const;
596  EngineOperationResult splitPolygonGeometry( GEOSGeometry *splitLine, QVector<QgsGeometry > &newGeometries, bool skipIntersectionCheck ) const;
597 
598  //utils for reshape
599  static geos::unique_ptr reshapeLine( const GEOSGeometry *line, const GEOSGeometry *reshapeLineGeos, double precision );
600  static geos::unique_ptr reshapePolygon( const GEOSGeometry *polygon, const GEOSGeometry *reshapeLineGeos, double precision );
601  static int lineContainedInLine( const GEOSGeometry *line1, const GEOSGeometry *line2 );
602  static int pointContainedInLine( const GEOSGeometry *point, const GEOSGeometry *line );
603  static int geomDigits( const GEOSGeometry *geom );
604  void subdivideRecursive( const GEOSGeometry *currentPart, int maxNodes, int depth, QgsGeometryCollection *parts, const QgsRectangle &clipRect ) const;
605 };
606 
608 
609 
610 class GEOSException : public std::runtime_error
611 {
612  public:
613  explicit GEOSException( const QString &message )
614  : std::runtime_error( message.toUtf8().constData() )
615  {
616  }
617 };
618 
620 
621 #endif // QGSGEOS_H
BufferSide
Side of line to buffer.
Definition: qgis.h:699
GeometryOperationResult
Success or failure of a geometry operation.
Definition: qgis.h:647
JoinStyle
Join styles for buffers.
Definition: qgis.h:724
EndCapStyle
End cap styles for buffers.
Definition: qgis.h:711
Abstract base class for all geometries.
Abstract base class for curved geometry type.
Definition: qgscurve.h:36
Geometry collection.
A geometry engine is a low-level representation of a QgsAbstractGeometry object, optimised for use wi...
virtual bool isEqual(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if this is equal to geom.
virtual double area(QString *errorMsg=nullptr) const =0
virtual QgsAbstractGeometry * buffer(double distance, int segments, QString *errorMsg=nullptr) const =0
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.
virtual void geometryChanged()=0
Should be called whenever the geometry associated with the engine has been modified and the engine mu...
virtual QgsAbstractGeometry * intersection(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Calculate the intersection of this and geom.
virtual bool intersects(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if geom intersects this.
virtual QgsAbstractGeometry * difference(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Calculate the difference of this and geom.
virtual QgsAbstractGeometry * symDifference(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Calculate the symmetric difference of this and geom.
virtual double distance(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Calculates the distance between this and geom.
virtual bool distanceWithin(const QgsAbstractGeometry *geom, double maxdistance, QString *errorMsg=nullptr) const =0
Checks if geom is within maxdistance distance from this geometry.
virtual bool isValid(QString *errorMsg=nullptr, bool allowSelfTouchingHoles=false, QgsGeometry *errorLoc=nullptr) const =0
Returns true if the geometry is valid.
virtual bool touches(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if geom touches this.
virtual QgsAbstractGeometry * offsetCurve(double distance, int segments, Qgis::JoinStyle joinStyle, double miterLimit, QString *errorMsg=nullptr) const =0
Offsets a curve.
EngineOperationResult
Success or failure of a geometry operation.
virtual bool isEmpty(QString *errorMsg) const =0
virtual QgsAbstractGeometry * envelope(QString *errorMsg=nullptr) const =0
virtual bool crosses(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if geom crosses this.
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...
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...
virtual bool isSimple(QString *errorMsg=nullptr) const =0
Determines whether the geometry is simple (according to OGC definition).
virtual QgsAbstractGeometry * convexHull(QString *errorMsg=nullptr) const =0
Calculate the convex hull of this.
virtual bool overlaps(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if geom overlaps this.
virtual QgsPoint * pointOnSurface(QString *errorMsg=nullptr) const =0
Calculate a point that is guaranteed to be on the surface of this.
virtual QgsPoint * centroid(QString *errorMsg=nullptr) const =0
Calculates the centroid of this.
virtual bool within(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if geom is within this.
virtual void prepareGeometry()=0
Prepares the geometry, so that subsequent calls to spatial relation methods are much faster.
virtual bool contains(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if geom contains this.
virtual double length(QString *errorMsg=nullptr) const =0
virtual QgsAbstractGeometry * interpolate(double distance, QString *errorMsg=nullptr) const =0
virtual QgsAbstractGeometry * combine(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Calculate the combination of this and geom.
virtual QgsAbstractGeometry * simplify(double tolerance, QString *errorMsg=nullptr) const =0
virtual bool disjoint(const QgsAbstractGeometry *geom, QString *errorMsg=nullptr) const =0
Checks if geom is disjoint from this.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:125
Does vector analysis using the geos library and handles import, export, exception handling*.
Definition: qgsgeos.h:104
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:44
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
Polygon geometry type.
Definition: qgspolygon.h:34
A rectangle specified with double values.
Definition: qgsrectangle.h:42
Contains geos related utilities and functions.
Definition: qgsgeos.h:42
std::unique_ptr< const GEOSPreparedGeometry, GeosDeleter > prepared_unique_ptr
Scoped GEOS prepared geometry pointer.
Definition: qgsgeos.h:84
std::unique_ptr< GEOSGeometry, GeosDeleter > unique_ptr
Scoped GEOS pointer.
Definition: qgsgeos.h:79
std::unique_ptr< GEOSCoordSequence, GeosDeleter > coord_sequence_unique_ptr
Scoped GEOS coordinate sequence pointer.
Definition: qgsgeos.h:94
std::unique_ptr< GEOSBufferParams, GeosDeleter > buffer_params_unique_ptr
Scoped GEOS buffer params pointer.
Definition: qgsgeos.h:89
QVector< QgsPoint > QgsPointSequence
int precision
Destroys the GEOS geometry geom, using the static QGIS geos context.
Definition: qgsgeos.h:49
void CORE_EXPORT operator()(GEOSBufferParams *params)
Destroys the GEOS buffer params params, using the static QGIS geos context.
void CORE_EXPORT operator()(const GEOSPreparedGeometry *geom)
Destroys the GEOS prepared geometry geom, using the static QGIS geos context.
void CORE_EXPORT operator()(GEOSCoordSequence *sequence)
Destroys the GEOS coordinate sequence sequence, using the static QGIS geos context.
void CORE_EXPORT operator()(GEOSGeometry *geom)
Destroys the GEOS geometry geom, using the static QGIS geos context.