Skip to content

Commit

Permalink
[FEATURE] New expression function 'extend'
Browse files Browse the repository at this point in the history
Extends linestrings by a specified amount at the start and
end of the line
  • Loading branch information
nyalldawson committed Oct 30, 2016
1 parent ef34e39 commit 2b54582
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 0 deletions.
10 changes: 10 additions & 0 deletions resources/function_help/json/extend
@@ -0,0 +1,10 @@
{
"name": "extend",
"type": "function",
"description": "Extends the start and end of a linestring geometry by a specified amount. Lines are extended using the bearing of the first and last segment in the line. Distances are in the Spatial Reference System of this geometry.",
"arguments": [ {"arg":"geometry","description":"a (multi)linestring geometry"},
{"arg":"start_distance","description":"distance to extend the start of the line"},
{"arg":"end_distance","description":"distance to extend the end of the line."}],
"examples": [ { "expression":"geom_to_wkt(extend(geom_from_wkt('LineString(0 0, 1 0, 1 1)'),1,2))", "returns":"LineString (-1 0, 1 0, 1 3)"}]
}

15 changes: 15 additions & 0 deletions src/core/qgsexpression.cpp
Expand Up @@ -2460,6 +2460,17 @@ static QVariant fcnSingleSidedBuffer( const QVariantList& values, const QgsExpre
return result;
}

static QVariant fcnExtend( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
{
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
double distStart = getDoubleValue( values.at( 1 ), parent );
double distEnd = getDoubleValue( values.at( 2 ), parent );

QgsGeometry geom = fGeom.extendLine( distStart, distEnd );
QVariant result = !geom.isEmpty() ? QVariant::fromValue( geom ) : QVariant();
return result;
}

static QVariant fcnTranslate( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
{
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
Expand Down Expand Up @@ -3791,6 +3802,10 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
<< Parameter( QStringLiteral( "join" ), true, QgsGeometry::JoinStyleRound )
<< Parameter( QStringLiteral( "mitre_limit" ), true, 2.0 ),
fcnSingleSidedBuffer, QStringLiteral( "GeometryGroup" ) )
<< new StaticFunction( QStringLiteral( "extend" ), ParameterList() << Parameter( QStringLiteral( "geometry" ) )
<< Parameter( QStringLiteral( "start_distance" ) )
<< Parameter( QStringLiteral( "end_distance" ) ),
fcnExtend, QStringLiteral( "GeometryGroup" ) )
<< new StaticFunction( QStringLiteral( "centroid" ), 1, fcnCentroid, QStringLiteral( "GeometryGroup" ) )
<< new StaticFunction( QStringLiteral( "point_on_surface" ), 1, fcnPointOnSurface, QStringLiteral( "GeometryGroup" ) )
<< new StaticFunction( QStringLiteral( "reverse" ), 1, fcnReverse, QStringLiteral( "GeometryGroup" ) )
Expand Down
4 changes: 4 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -699,6 +699,10 @@ class TestQgsExpression: public QObject
QTest::newRow( "single_sided_buffer line" ) << "geom_to_wkt(single_sided_buffer(geom_from_wkt('LineString(0 0, 10 0)'),1,segments:=4))" << false << QVariant( "Polygon ((10 0, 0 0, 0 1, 10 1, 10 0))" );
QTest::newRow( "single_sided_buffer line mitre" ) << "geom_to_wkt(single_sided_buffer(geometry:=geom_from_wkt('LineString(0 0, 10 0)'),distance:=-1,join:=2,mitre_limit:=1))" << false << QVariant( "Polygon ((0 0, 10 0, 10 -1, 0 -1, 0 0))" );
QTest::newRow( "single_sided_buffer line bevel" ) << "geom_to_wkt(single_sided_buffer(geometry:=geom_from_wkt('LineString(0 0, 10 0, 10 10)'),distance:=1,join:=3))" << false << QVariant( "Polygon ((10 10, 10 0, 0 0, 0 1, 9 1, 9 10, 10 10))" );
QTest::newRow( "extend not geom" ) << "extend('g', 1, 2)" << true << QVariant();
QTest::newRow( "extend null" ) << "extend(NULL, 1, 2)" << false << QVariant();
QTest::newRow( "extend point" ) << "extend(geom_from_wkt('POINT(1 2)'),1,2)" << false << QVariant();
QTest::newRow( "extend line" ) << "geom_to_wkt(extend(geom_from_wkt('LineString(0 0, 1 0, 1 1)'),1,2))" << false << QVariant( "LineString (-1 0, 1 0, 1 3)" );
QTest::newRow( "start_point point" ) << "geom_to_wkt(start_point(geom_from_wkt('POINT(2 0)')))" << false << QVariant( "Point (2 0)" );
QTest::newRow( "start_point multipoint" ) << "geom_to_wkt(start_point(geom_from_wkt('MULTIPOINT((3 3), (1 1), (2 2))')))" << false << QVariant( "Point (3 3)" );
QTest::newRow( "start_point line" ) << "geom_to_wkt(start_point(geom_from_wkt('LINESTRING(4 1, 1 1, 2 2)')))" << false << QVariant( "Point (4 1)" );
Expand Down

0 comments on commit 2b54582

Please sign in to comment.