Skip to content

Commit

Permalink
[FEATURE] Expose GEOS Voronoi and delaunay triangulation to QgsGeometry
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jan 31, 2017
1 parent f85ac23 commit aaa8c4e
Show file tree
Hide file tree
Showing 6 changed files with 279 additions and 0 deletions.
4 changes: 4 additions & 0 deletions python/core/geometry/qgsgeometry.sip
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,10 @@ class QgsGeometry
/** Returns the smallest convex polygon that contains all the points in the geometry. */
QgsGeometry convexHull() const;

QgsGeometry voronoiDiagram( const QgsGeometry& extent = QgsGeometry(), double tolerance = 0.0, bool edgesOnly = false ) const;

QgsGeometry delaunayTriangulation( double tolerance = 0.0, bool edgesOnly = false ) const;

/**
* Return interpolated point on line at distance
* @note added in 1.9
Expand Down
22 changes: 22 additions & 0 deletions src/core/geometry/qgsgeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1606,6 +1606,28 @@ QgsGeometry QgsGeometry::convexHull() const
return QgsGeometry( cHull );
}

QgsGeometry QgsGeometry::voronoiDiagram( const QgsGeometry& extent, double tolerance, bool edgesOnly ) const
{
if ( !d->geometry )
{
return QgsGeometry();
}

QgsGeos geos( d->geometry );
return geos.voronoiDiagram( extent.geometry(), tolerance, edgesOnly );
}

QgsGeometry QgsGeometry::delaunayTriangulation( double tolerance, bool edgesOnly ) const
{
if ( !d->geometry )
{
return QgsGeometry();
}

QgsGeos geos( d->geometry );
return geos.delaunayTriangulation( tolerance, edgesOnly );
}

QgsGeometry QgsGeometry::interpolate( double distance ) const
{
if ( !d->geometry )
Expand Down
28 changes: 28 additions & 0 deletions src/core/geometry/qgsgeometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,34 @@ class CORE_EXPORT QgsGeometry
//! Returns the smallest convex polygon that contains all the points in the geometry.
QgsGeometry convexHull() const;

/**
* Creates a Voronoi diagram for the nodes contained within the geometry.
*
* Returns the Voronoi polygons for the nodes contained within the geometry.
* If \a extent is specified then it will be used as a clipping envelope for the diagram.
* If no extent is set then the clipping envelope will be automatically calculated.
* In either case the diagram will be clipped to the larger of the provided envelope
* OR the envelope surrounding all input nodes.
* The \a tolerance parameter specifies an optional snapping tolerance which can
* be used to improve the robustness of the diagram calculation.
* If \a edgesOnly is true than line string boundary geometries will be returned
* instead of polygons.
* An empty geometry will be returned if the diagram could not be calculated.
* @note added in QGIS 3.0
*/
QgsGeometry voronoiDiagram( const QgsGeometry& extent = QgsGeometry(), double tolerance = 0.0, bool edgesOnly = false ) const;

/**
* Returns the Delaunay triangulation for the vertices of the geometry.
* The \a tolerance parameter specifies an optional snapping tolerance which can
* be used to improve the robustness of the triangulation.
* If \a edgesOnly is true than line string boundary geometries will be returned
* instead of polygons.
* An empty geometry will be returned if the diagram could not be calculated.
* @note added in QGIS 3.0
*/
QgsGeometry delaunayTriangulation( double tolerance = 0.0, bool edgesOnly = false ) const;

/**
* Return interpolated point on line at distance
* @note added in 1.9
Expand Down
56 changes: 56 additions & 0 deletions src/core/geometry/qgsgeos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1980,6 +1980,62 @@ QgsGeometry QgsGeos::polygonize( const QList<QgsAbstractGeometry*>& geometries,
}
}

QgsGeometry QgsGeos::voronoiDiagram( const QgsAbstractGeometry* extent, double tolerance, bool edgesOnly, QString* errorMsg ) const
{
if ( !mGeos )
{
return QgsGeometry();
}

GEOSGeometry* extentGeos = nullptr;
GEOSGeomScopedPtr extentGeosGeom( nullptr );
if ( extent )
{
extentGeosGeom.reset( asGeos( extent, mPrecision ) );
if ( !extentGeosGeom )
{
return QgsGeometry();
}
extentGeos = extentGeosGeom.get();
}

GEOSGeomScopedPtr geos;
try
{
geos.reset( GEOSVoronoiDiagram_r( geosinit.ctxt, mGeos, extentGeos, tolerance, edgesOnly ) );

if ( !geos || GEOSisEmpty_r( geosinit.ctxt, geos.get() ) != 0 )
{
return QgsGeometry();
}

return QgsGeometry( fromGeos( geos.get() ) );
}
CATCH_GEOS_WITH_ERRMSG( QgsGeometry() );
}

QgsGeometry QgsGeos::delaunayTriangulation( double tolerance, bool edgesOnly, QString* errorMsg ) const
{
if ( !mGeos )
{
return QgsGeometry();
}

GEOSGeomScopedPtr geos;
try
{
geos.reset( GEOSDelaunayTriangulation_r( geosinit.ctxt, mGeos, tolerance, edgesOnly ) );

if ( !geos || GEOSisEmpty_r( geosinit.ctxt, geos.get() ) != 0 )
{
return QgsGeometry();
}

return QgsGeometry( fromGeos( geos.get() ) );
}
CATCH_GEOS_WITH_ERRMSG( QgsGeometry() );
}


//! Extract coordinates of linestring's endpoints. Returns false on error.
static bool _linestringEndpoints( const GEOSGeometry* linestring, double& x1, double& y1, double& x2, double& y2 )
Expand Down
28 changes: 28 additions & 0 deletions src/core/geometry/qgsgeos.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,34 @@ class CORE_EXPORT QgsGeos: public QgsGeometryEngine
*/
static QgsGeometry polygonize( const QList<QgsAbstractGeometry*>& geometries, QString* errorMsg = nullptr );

/**
* Creates a Voronoi diagram for the nodes contained within the geometry.
*
* Returns the Voronoi polygons for the nodes contained within the geometry.
* If \a extent is specified then it will be used as a clipping envelope for the diagram.
* If no extent is set then the clipping envelope will be automatically calculated.
* In either case the diagram will be clipped to the larger of the provided envelope
* OR the envelope surrounding all input nodes.
* The \a tolerance parameter specifies an optional snapping tolerance which can
* be used to improve the robustness of the diagram calculation.
* If \a edgesOnly is true than line string boundary geometries will be returned
* instead of polygons.
* An empty geometry will be returned if the diagram could not be calculated.
* @note added in QGIS 3.0
*/
QgsGeometry voronoiDiagram( const QgsAbstractGeometry* extent = nullptr, double tolerance = 0.0, bool edgesOnly = false, QString* errorMsg = nullptr ) const;

/**
* Returns the Delaunay triangulation for the vertices of the geometry.
* The \a tolerance parameter specifies an optional snapping tolerance which can
* be used to improve the robustness of the triangulation.
* If \a edgesOnly is true than line string boundary geometries will be returned
* instead of polygons.
* An empty geometry will be returned if the diagram could not be calculated.
* @note added in QGIS 3.0
*/
QgsGeometry delaunayTriangulation( double tolerance = 0.0, bool edgesOnly = false, QString* errorMsg = nullptr ) const;

/** Create a geometry from a GEOSGeometry
* @param geos GEOSGeometry. Ownership is NOT transferred.
*/
Expand Down
Loading

1 comment on commit aaa8c4e

@nirvn
Copy link
Contributor

@nirvn nirvn commented on aaa8c4e Jan 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nyalldawson , should the relevant processing qgis algs be updateD?

Please sign in to comment.