Skip to content
Permalink
Browse files

[FEATURE] API call to make geometries valid (port of ST_MakeValid)

This introduces QgsGeometry::makeValid() which will try to make a valid
geometry out of invalid one. This is more complicated method than just
doing a buffer with zero width, but it should not loose any vertices.

Finally we should have a reliable way in QGIS to fix bad geometries!

Ported the C code from lwgeom library to QGIS.
  • Loading branch information
wonder-sk committed Jan 27, 2017
1 parent 137eb3a commit b245ccc105ff8456c39444b9cbe6bcbed0ce44b3
@@ -747,6 +747,19 @@ class QgsGeometry
*/
int avoidIntersections( const QList<QgsVectorLayer*>& avoidIntersectionsLayers );

/**
* Attempts to make an invalid geometry valid without losing vertices.
*
* @note Ported from PostGIS ST_MakeValid() and it should return equivalent results.
* Already-valid geometries are returned without further intervention.
* In case of full or partial dimensional collapses, the output geometry may be a collection
* of lower-to-equal dimension geometries or a geometry of lower dimension.
* Single polygons may become multi-geometries in case of self-intersections.
* @return new valid QgsGeometry or null geometry on error
* @note added in QGIS 3.0
*/
QgsGeometry makeValid();

class Error
{
public:
@@ -361,6 +361,7 @@ SET(QGIS_CORE_SRCS
geometry/qgsgeometrycollection.cpp
geometry/qgsgeometryeditutils.cpp
geometry/qgsgeometryfactory.cpp
geometry/qgsgeometrymakevalid.cpp
geometry/qgsgeometryutils.cpp
geometry/qgsgeos.cpp
geometry/qgsinternalgeometryengine.cpp
@@ -22,6 +22,7 @@ email : morb at ozemail dot com dot au
#include "qgsgeometry.h"
#include "qgsgeometryeditutils.h"
#include "qgsgeometryfactory.h"
#include "qgsgeometrymakevalid.h"
#include "qgsgeometryutils.h"
#include "qgsinternalgeometryengine.h"
#include "qgsgeos.h"
@@ -1887,6 +1888,21 @@ int QgsGeometry::avoidIntersections( const QList<QgsVectorLayer*>& avoidIntersec
return 0;
}


QgsGeometry QgsGeometry::makeValid()
{
if ( !d->geometry )
return QgsGeometry();

QString errorMsg;
QgsAbstractGeometry* g = _qgis_lwgeom_make_valid( *d->geometry, errorMsg );
if ( !g )
return QgsGeometry();

return QgsGeometry( g );
}


void QgsGeometry::validateGeometry( QList<Error> &errors )
{
QgsGeometryValidator::validateGeometry( this, errors );
@@ -802,6 +802,19 @@ class CORE_EXPORT QgsGeometry
int avoidIntersections( const QList<QgsVectorLayer*>& avoidIntersectionsLayers,
const QHash<QgsVectorLayer*, QSet<QgsFeatureId> >& ignoreFeatures = ( QHash<QgsVectorLayer*, QSet<QgsFeatureId> >() ) );

/**
* Attempts to make an invalid geometry valid without losing vertices.
*
* @note Ported from PostGIS ST_MakeValid() and it should return equivalent results.
* Already-valid geometries are returned without further intervention.
* In case of full or partial dimensional collapses, the output geometry may be a collection
* of lower-to-equal dimension geometries or a geometry of lower dimension.
* Single polygons may become multi-geometries in case of self-intersections.
* @return new valid QgsGeometry or null geometry on error
* @note added in QGIS 3.0
*/
QgsGeometry makeValid();

/** \ingroup core
*/
class Error

0 comments on commit b245ccc

Please sign in to comment.
You can’t perform that action at this time.