diff --git a/resources/function_help/json/reverse b/resources/function_help/json/reverse new file mode 100644 index 00000000000..09ea7ae5879 --- /dev/null +++ b/resources/function_help/json/reverse @@ -0,0 +1,7 @@ +{ + "name": "reverse", + "type": "function", + "description": "Reverses the direction of a line string by reversing the order of its vertices.", + "arguments": [ {"arg":"geom","description":"a geometry"}], + "examples": [ { "expression":"geom_to_wkt(reverse(geom_from_wkt('LINESTRING(0 0, 1 1, 2 2)')))", "returns":"'LINESTRING(2 2, 1 1, 0 0)'"}] +} diff --git a/src/core/qgsexpression.cpp b/src/core/qgsexpression.cpp index 68a6b6004c3..6b065a63a16 100644 --- a/src/core/qgsexpression.cpp +++ b/src/core/qgsexpression.cpp @@ -1725,6 +1725,22 @@ static QVariant fcnDifference( const QVariantList& values, const QgsExpressionCo delete geom; return result; } + +static QVariant fcnReverse( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent ) +{ + QgsGeometry fGeom = getGeometry( values.at( 0 ), parent ); + if ( fGeom.isEmpty() ) + return QVariant(); + + QgsCurveV2* curve = dynamic_cast< QgsCurveV2* >( fGeom.geometry() ); + if ( !curve ) + return QVariant(); + + QgsCurveV2* reversed = curve->reversed(); + QVariant result = reversed ? QVariant::fromValue( QgsGeometry( reversed ) ) : QVariant(); + return result; +} + static QVariant fcnDistance( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent ) { QgsGeometry fGeom = getGeometry( values.at( 0 ), parent ); @@ -2333,7 +2349,7 @@ const QStringList& QgsExpression::BuiltinFunctions() << "geom_from_gml" << "geomFromGML" << "intersects_bbox" << "bbox" << "disjoint" << "intersects" << "touches" << "crosses" << "contains" << "relate" - << "overlaps" << "within" << "buffer" << "centroid" << "bounds" + << "overlaps" << "within" << "buffer" << "centroid" << "bounds" << "reverse" << "bounds_width" << "bounds_height" << "convex_hull" << "difference" << "distance" << "intersection" << "sym_difference" << "combine" << "union" << "geom_to_wkt" << "geomToWKT" << "geometry" @@ -2470,6 +2486,7 @@ const QList& QgsExpression::Functions() << new StaticFunction( "within", 2, fcnWithin, "GeometryGroup" ) << new StaticFunction( "buffer", -1, fcnBuffer, "GeometryGroup" ) << new StaticFunction( "centroid", 1, fcnCentroid, "GeometryGroup" ) + << new StaticFunction( "reverse", 1, fcnReverse, "GeometryGroup" ) << new StaticFunction( "bounds", 1, fcnBounds, "GeometryGroup" ) << new StaticFunction( "num_points", 1, fcnGeomNumPoints, "GeometryGroup" ) << new StaticFunction( "bounds_width", 1, fcnBoundsWidth, "GeometryGroup" ) diff --git a/tests/src/core/testqgsexpression.cpp b/tests/src/core/testqgsexpression.cpp index 50c757c6481..00590e54118 100644 --- a/tests/src/core/testqgsexpression.cpp +++ b/tests/src/core/testqgsexpression.cpp @@ -442,6 +442,11 @@ class TestQgsExpression: public QObject 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)" ); 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)" ); 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)" ); + QTest::newRow( "reverse not geom" ) << "reverse('g')" << true << QVariant(); + QTest::newRow( "reverse null" ) << "reverse(NULL)" << false << QVariant(); + QTest::newRow( "reverse point" ) << "reverse(geom_from_wkt('POINT(1 2)'))" << false << QVariant(); + QTest::newRow( "reverse polygon" ) << "reverse(geom_from_wkt('POLYGON((-1 -1, 4 0, 4 2, 0 2, -1 -1))'))" << false << QVariant(); + 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)" ); QTest::newRow( "make_point" ) << "geom_to_wkt(make_point(2.2,4.4))" << false << QVariant( "Point (2.2 4.4)" ); 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)" ); 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)" );