Skip to content

Commit da436f9

Browse files
committed
[FEATURE] New 'reverse' expression for reversing linestrings
1 parent 4624fb8 commit da436f9

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

resources/function_help/json/reverse

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "reverse",
3+
"type": "function",
4+
"description": "Reverses the direction of a line string by reversing the order of its vertices.",
5+
"arguments": [ {"arg":"geom","description":"a geometry"}],
6+
"examples": [ { "expression":"geom_to_wkt(reverse(geom_from_wkt('LINESTRING(0 0, 1 1, 2 2)')))", "returns":"'LINESTRING(2 2, 1 1, 0 0)'"}]
7+
}

src/core/qgsexpression.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1725,6 +1725,22 @@ static QVariant fcnDifference( const QVariantList& values, const QgsExpressionCo
17251725
delete geom;
17261726
return result;
17271727
}
1728+
1729+
static QVariant fcnReverse( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
1730+
{
1731+
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1732+
if ( fGeom.isEmpty() )
1733+
return QVariant();
1734+
1735+
QgsCurveV2* curve = dynamic_cast< QgsCurveV2* >( fGeom.geometry() );
1736+
if ( !curve )
1737+
return QVariant();
1738+
1739+
QgsCurveV2* reversed = curve->reversed();
1740+
QVariant result = reversed ? QVariant::fromValue( QgsGeometry( reversed ) ) : QVariant();
1741+
return result;
1742+
}
1743+
17281744
static QVariant fcnDistance( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
17291745
{
17301746
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
@@ -2333,7 +2349,7 @@ const QStringList& QgsExpression::BuiltinFunctions()
23332349
<< "geom_from_gml" << "geomFromGML" << "intersects_bbox" << "bbox"
23342350
<< "disjoint" << "intersects" << "touches" << "crosses" << "contains"
23352351
<< "relate"
2336-
<< "overlaps" << "within" << "buffer" << "centroid" << "bounds"
2352+
<< "overlaps" << "within" << "buffer" << "centroid" << "bounds" << "reverse"
23372353
<< "bounds_width" << "bounds_height" << "convex_hull" << "difference"
23382354
<< "distance" << "intersection" << "sym_difference" << "combine"
23392355
<< "union" << "geom_to_wkt" << "geomToWKT" << "geometry"
@@ -2470,6 +2486,7 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
24702486
<< new StaticFunction( "within", 2, fcnWithin, "GeometryGroup" )
24712487
<< new StaticFunction( "buffer", -1, fcnBuffer, "GeometryGroup" )
24722488
<< new StaticFunction( "centroid", 1, fcnCentroid, "GeometryGroup" )
2489+
<< new StaticFunction( "reverse", 1, fcnReverse, "GeometryGroup" )
24732490
<< new StaticFunction( "bounds", 1, fcnBounds, "GeometryGroup" )
24742491
<< new StaticFunction( "num_points", 1, fcnGeomNumPoints, "GeometryGroup" )
24752492
<< new StaticFunction( "bounds_width", 1, fcnBoundsWidth, "GeometryGroup" )

tests/src/core/testqgsexpression.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,11 @@ class TestQgsExpression: public QObject
442442
QTest::newRow( "end_point multipoint" ) << "geom_to_wkt(end_point(geom_from_wkt('MULTIPOINT((3 3), (1 1), (2 2))')))" << false << QVariant( "Point (2 2)" );
443443
QTest::newRow( "end_point line" ) << "geom_to_wkt(end_point(geom_from_wkt('LINESTRING(4 1, 1 1, 2 2)')))" << false << QVariant( "Point (2 2)" );
444444
QTest::newRow( "end_point polygon" ) << "geom_to_wkt(end_point(geom_from_wkt('POLYGON((-1 -1, 4 0, 4 2, 0 2, -1 -1))')))" << false << QVariant( "Point (-1 -1)" );
445+
QTest::newRow( "reverse not geom" ) << "reverse('g')" << true << QVariant();
446+
QTest::newRow( "reverse null" ) << "reverse(NULL)" << false << QVariant();
447+
QTest::newRow( "reverse point" ) << "reverse(geom_from_wkt('POINT(1 2)'))" << false << QVariant();
448+
QTest::newRow( "reverse polygon" ) << "reverse(geom_from_wkt('POLYGON((-1 -1, 4 0, 4 2, 0 2, -1 -1))'))" << false << QVariant();
449+
QTest::newRow( "reverse line" ) << "geom_to_wkt(reverse(geom_from_wkt('LINESTRING(0 0, 1 1, 2 2)')))" << false << QVariant( "LineString (2 2, 1 1, 0 0)" );
445450
QTest::newRow( "make_point" ) << "geom_to_wkt(make_point(2.2,4.4))" << false << QVariant( "Point (2.2 4.4)" );
446451
QTest::newRow( "make_point z" ) << "geom_to_wkt(make_point(2.2,4.4,5.5))" << false << QVariant( "PointZ (2.2 4.4 5.5)" );
447452
QTest::newRow( "make_point zm" ) << "geom_to_wkt(make_point(2.2,4.4,5.5,6.6))" << false << QVariant( "PointZM (2.2 4.4 5.5 6.6)" );

0 commit comments

Comments
 (0)