diff --git a/src/core/geometry/qgsmultipoint.cpp b/src/core/geometry/qgsmultipoint.cpp index 21e7d788045..8ebbbe8d10e 100644 --- a/src/core/geometry/qgsmultipoint.cpp +++ b/src/core/geometry/qgsmultipoint.cpp @@ -182,6 +182,20 @@ double QgsMultiPoint::segmentLength( QgsVertexId ) const return 0.0; } +void QgsMultiPoint::filterVertices( const std::function &filter ) +{ + mGeometries.erase( std::remove_if( mGeometries.begin(), mGeometries.end(), // clazy:exclude=detaching-member + [&filter]( const QgsAbstractGeometry * part ) + { + if ( const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( part ) ) + { + return !filter( *point ); + } + else + return true; + } ), mGeometries.end() ); // clazy:exclude=detaching-member +} + bool QgsMultiPoint::wktOmitChildType() const { return true; diff --git a/src/core/geometry/qgsmultipoint.h b/src/core/geometry/qgsmultipoint.h index af0df96ad77..49709f77101 100644 --- a/src/core/geometry/qgsmultipoint.h +++ b/src/core/geometry/qgsmultipoint.h @@ -47,6 +47,7 @@ class CORE_EXPORT QgsMultiPoint: public QgsGeometryCollection double segmentLength( QgsVertexId startVertex ) const override; #ifndef SIP_RUN + void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override; /** * Cast the \a geom to a QgsLineString. diff --git a/tests/src/core/testqgsgeometry.cpp b/tests/src/core/testqgsgeometry.cpp index 9863c0ca235..4b3e0aa8c10 100644 --- a/tests/src/core/testqgsgeometry.cpp +++ b/tests/src/core/testqgsgeometry.cpp @@ -4538,7 +4538,7 @@ void TestQgsGeometry::lineString() filterLine.filterVertices( filter ); // no crash filterLine.setPoints( QgsPointSequence() << QgsPoint( 11, 2, 3, 4, QgsWkbTypes::PointZM ) << QgsPoint( 1, 2, 3, 4, QgsWkbTypes::PointZM ) << QgsPoint( 4, 12, 13, 14, QgsWkbTypes::PointZM ) << QgsPoint( 111, 12, 23, 24, QgsWkbTypes::PointZM ) ); filterLine.filterVertices( filter ); - QCOMPARE( swapLine.asWkt( 2 ), QStringLiteral( "LineStringZM (2 11 3 4, 12 11 13 14, 12 111 23 24)" ) ); + QCOMPARE( filterLine.asWkt( 2 ), QStringLiteral( "LineStringZM (1 2 3 4, 4 12 13 14)" ) ); } void TestQgsGeometry::polygon() @@ -11583,6 +11583,20 @@ void TestQgsGeometry::multiPoint() mp.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 10, 1, 4, 8 ) ); QVERIFY( !mp.removeDuplicateNodes() ); QCOMPARE( mp.numGeometries(), 2 ); + + // filter vertex + QgsMultiPoint filterPoint; + auto filter = []( const QgsPoint & point )-> bool + { + return point.x() < 5; + }; + filterPoint.filterVertices( filter ); // no crash + filterPoint.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) ); + filterPoint.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 3, 0, 4, 8 ) ); + filterPoint.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 1, 0, 4, 8 ) ); + filterPoint.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 11, 0, 4, 8 ) ); + filterPoint.filterVertices( filter ); + QCOMPARE( filterPoint.asWkt( 2 ), QStringLiteral( "MultiPointZM ((3 0 4 8),(1 0 4 8))" ) ); } void TestQgsGeometry::multiLineString()