Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FEATURE] New 'reverse' expression for reversing linestrings
  • Loading branch information
nyalldawson committed Nov 26, 2015
1 parent 4624fb8 commit da436f9
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 1 deletion.
7 changes: 7 additions & 0 deletions 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)'"}]
}
19 changes: 18 additions & 1 deletion src/core/qgsexpression.cpp
Expand Up @@ -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 );
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -2470,6 +2486,7 @@ const QList<QgsExpression::Function*>& 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" )
Expand Down
5 changes: 5 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -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)" );
Expand Down

0 comments on commit da436f9

Please sign in to comment.