Skip to content

Commit 2b54582

Browse files
committed
[FEATURE] New expression function 'extend'
Extends linestrings by a specified amount at the start and end of the line
1 parent ef34e39 commit 2b54582

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

resources/function_help/json/extend

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "extend",
3+
"type": "function",
4+
"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.",
5+
"arguments": [ {"arg":"geometry","description":"a (multi)linestring geometry"},
6+
{"arg":"start_distance","description":"distance to extend the start of the line"},
7+
{"arg":"end_distance","description":"distance to extend the end of the line."}],
8+
"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)"}]
9+
}
10+

src/core/qgsexpression.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -2460,6 +2460,17 @@ static QVariant fcnSingleSidedBuffer( const QVariantList& values, const QgsExpre
24602460
return result;
24612461
}
24622462

2463+
static QVariant fcnExtend( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
2464+
{
2465+
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
2466+
double distStart = getDoubleValue( values.at( 1 ), parent );
2467+
double distEnd = getDoubleValue( values.at( 2 ), parent );
2468+
2469+
QgsGeometry geom = fGeom.extendLine( distStart, distEnd );
2470+
QVariant result = !geom.isEmpty() ? QVariant::fromValue( geom ) : QVariant();
2471+
return result;
2472+
}
2473+
24632474
static QVariant fcnTranslate( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
24642475
{
24652476
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
@@ -3791,6 +3802,10 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
37913802
<< Parameter( QStringLiteral( "join" ), true, QgsGeometry::JoinStyleRound )
37923803
<< Parameter( QStringLiteral( "mitre_limit" ), true, 2.0 ),
37933804
fcnSingleSidedBuffer, QStringLiteral( "GeometryGroup" ) )
3805+
<< new StaticFunction( QStringLiteral( "extend" ), ParameterList() << Parameter( QStringLiteral( "geometry" ) )
3806+
<< Parameter( QStringLiteral( "start_distance" ) )
3807+
<< Parameter( QStringLiteral( "end_distance" ) ),
3808+
fcnExtend, QStringLiteral( "GeometryGroup" ) )
37943809
<< new StaticFunction( QStringLiteral( "centroid" ), 1, fcnCentroid, QStringLiteral( "GeometryGroup" ) )
37953810
<< new StaticFunction( QStringLiteral( "point_on_surface" ), 1, fcnPointOnSurface, QStringLiteral( "GeometryGroup" ) )
37963811
<< new StaticFunction( QStringLiteral( "reverse" ), 1, fcnReverse, QStringLiteral( "GeometryGroup" ) )

tests/src/core/testqgsexpression.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,10 @@ class TestQgsExpression: public QObject
699699
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))" );
700700
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))" );
701701
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))" );
702+
QTest::newRow( "extend not geom" ) << "extend('g', 1, 2)" << true << QVariant();
703+
QTest::newRow( "extend null" ) << "extend(NULL, 1, 2)" << false << QVariant();
704+
QTest::newRow( "extend point" ) << "extend(geom_from_wkt('POINT(1 2)'),1,2)" << false << QVariant();
705+
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)" );
702706
QTest::newRow( "start_point point" ) << "geom_to_wkt(start_point(geom_from_wkt('POINT(2 0)')))" << false << QVariant( "Point (2 0)" );
703707
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)" );
704708
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)" );

0 commit comments

Comments
 (0)