Skip to content
Permalink
Browse files

[geometry snapper] Don't create invalid geometries with duplicate nodes

Fixes #15247
  • Loading branch information
nyalldawson committed Dec 3, 2017
1 parent 484a611 commit 113c21e8bfdd3a58086bf6455d41669c0281d9aa
Showing with 36 additions and 2 deletions.
  1. +8 −2 src/analysis/vector/qgsgeometrysnapper.cpp
  2. +28 −0 tests/src/analysis/testqgsgeometrysnapper.cpp
@@ -608,7 +608,11 @@ QgsGeometry QgsGeometrySnapper::snapGeometry( const QgsGeometry &geometry, doubl
return QgsGeometry( subjGeom );
//or for end point snapping
if ( mode == PreferClosestNoExtraVertices || mode == PreferNodesNoExtraVertices || mode == EndPointPreferClosest || mode == EndPointPreferNodes || mode == EndPointToEndPoint )
return QgsGeometry( subjGeom );
{
QgsGeometry result( subjGeom );
result.removeDuplicateNodes();
return result;
}

// SnapIndex for subject feature
std::unique_ptr< QgsSnapIndex > subjSnapIndex( new QgsSnapIndex( center, 10 * snapTolerance ) );
@@ -705,7 +709,9 @@ QgsGeometry QgsGeometrySnapper::snapGeometry( const QgsGeometry &geometry, doubl
}
}

return QgsGeometry( subjGeom );
QgsGeometry result( subjGeom );
result.removeDuplicateNodes();
return result;
}

int QgsGeometrySnapper::polyLineSize( const QgsAbstractGeometry *geom, int iPart, int iRing )
@@ -49,6 +49,7 @@ class TestQgsGeometrySnapper : public QObject
void endPointToEndPoint();
void internalSnapper();
void insertExtra();
void duplicateNodes();
};

void TestQgsGeometrySnapper::initTestCase()
@@ -584,6 +585,33 @@ void TestQgsGeometrySnapper::insertExtra()

}

void TestQgsGeometrySnapper::duplicateNodes()
{
// test that snapper does not result in duplicate nodes

QgsGeometry refGeom = QgsGeometry::fromWkt( QStringLiteral( "LineString(0 0, 20 0)" ) );
QgsFeature f1( 1 );
f1.setGeometry( refGeom );

QgsInternalGeometrySnapper snapper( 2, QgsGeometrySnapper::PreferNodes );
QgsGeometry result = snapper.snapFeature( f1 );
QCOMPARE( result.asWkt(), f1.geometry().asWkt() );

refGeom = QgsGeometry::fromWkt( QStringLiteral( "LineString(10 10, 19 0, 19.5 1, 20 0.1)" ) );
QgsFeature f2( 2 );
f2.setGeometry( refGeom );
result = snapper.snapFeature( f2 );
QCOMPARE( result.asWkt( 1 ), QStringLiteral( "LineString (10 10, 20 0)" ) );

snapper = QgsInternalGeometrySnapper( 2, QgsGeometrySnapper::PreferNodesNoExtraVertices );
result = snapper.snapFeature( f1 );
QCOMPARE( result.asWkt(), f1.geometry().asWkt() );

result = snapper.snapFeature( f2 );
QCOMPARE( result.asWkt( 1 ), QStringLiteral( "LineString (10 10, 20 0)" ) );

}


QGSTEST_MAIN( TestQgsGeometrySnapper )
#include "testqgsgeometrysnapper.moc"

0 comments on commit 113c21e

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