Skip to content

Commit

Permalink
[Geometry checker] Guard against producing degenerate geometries
Browse files Browse the repository at this point in the history
  • Loading branch information
manisandro committed Jul 14, 2016
1 parent 54e424f commit 120bdb7
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 5 deletions.
8 changes: 5 additions & 3 deletions src/plugins/geometry_checker/checks/qgsgeometryanglecheck.cpp
Expand Up @@ -114,14 +114,16 @@ void QgsGeometryAngleCheck::fixError( QgsGeometryCheckError* error, int method,
}
else if ( method == DeleteNode )
{

if ( n <= 3 )
if ( !QgsGeometryCheckerUtils::canDeleteVertex( geometry, vidx.part, vidx.ring ) )
{
error->setFixFailed( tr( "Resulting geometry is degenerate" ) );
}
else if ( !geometry->deleteVertex( error->vidx() ) )
{
error->setFixFailed( tr( "Failed to delete vertex" ) );
}
else
{
geometry->deleteVertex( vidx );
mFeaturePool->updateFeature( feature );
error->setFixed( method );
changes[error->featureId()].append( Change( ChangeNode, ChangeRemoved, vidx ) );
Expand Down
Expand Up @@ -86,11 +86,14 @@ void QgsGeometryDuplicateNodesCheck::fixError( QgsGeometryCheckError* error, int
}
else if ( method == RemoveDuplicates )
{
geom->deleteVertex( error->vidx() );
if ( QgsGeometryCheckerUtils::polyLineSize( geom, vidx.part, vidx.ring ) < 3 )
if ( !QgsGeometryCheckerUtils::canDeleteVertex( geom, vidx.part, vidx.ring ) )
{
error->setFixFailed( tr( "Resulting geometry is degenerate" ) );
}
else if ( !geom->deleteVertex( error->vidx() ) )
{
error->setFixFailed( tr( "Failed to delete vertex" ) );
}
else
{
mFeaturePool->updateFeature( feature );
Expand Down
8 changes: 8 additions & 0 deletions src/plugins/geometry_checker/utils/qgsgeometrycheckerutils.h
Expand Up @@ -72,6 +72,14 @@ namespace QgsGeometryCheckerUtils
return ( dx * dx + dy * dy ) < tol * tol;
}

inline bool canDeleteVertex( const QgsAbstractGeometryV2* geom, int iPart, int iRing )
{
int nVerts = geom->vertexCount( iPart, iRing );
QgsPointV2 front = geom->vertexAt( QgsVertexId( iPart, iRing, 0 ) );
QgsPointV2 back = geom->vertexAt( QgsVertexId( iPart, iRing, nVerts - 1 ) );
bool closed = back == front;
return closed ? nVerts > 4 : nVerts > 2;
}
} // QgsGeometryCheckerUtils

#endif // QGS_GEOMETRYCHECKERUTILS_H

0 comments on commit 120bdb7

Please sign in to comment.