Skip to content

Commit

Permalink
[geometry snapper] Don't create invalid geometries with duplicate nodes
Browse files Browse the repository at this point in the history
Fixes #15247
  • Loading branch information
nyalldawson committed Dec 3, 2017
1 parent 484a611 commit 113c21e
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/analysis/vector/qgsgeometrysnapper.cpp
Expand Up @@ -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 ) );
Expand Down Expand Up @@ -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 )
Expand Down
28 changes: 28 additions & 0 deletions tests/src/analysis/testqgsgeometrysnapper.cpp
Expand Up @@ -49,6 +49,7 @@ class TestQgsGeometrySnapper : public QObject
void endPointToEndPoint();
void internalSnapper();
void insertExtra();
void duplicateNodes();
};

void TestQgsGeometrySnapper::initTestCase()
Expand Down Expand Up @@ -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.