Skip to content

Commit d5647bc

Browse files
committed
[FEATURE] Add wedge_buffer expression function
Returns a wedge shaped buffer originating from a point geometry, with arguments for azimuth, buffer width (in degrees), outer radius and inner radius.
1 parent 2850b30 commit d5647bc

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "wedge_buffer",
3+
"type": "function",
4+
"description": "Returns a wedge shaped buffer originating from a point geometry.",
5+
"arguments": [ {"arg":"center","description":"center point (origin) of buffer. Must be a point geometry."},
6+
{"arg":"azimuth","description":"angle (in degrees) for the middle of the wedge to point."},
7+
{"arg":"width","description":"buffer width (in degrees). Note that the wedge will extend to half of the angular width either side of the azimuth direction."},
8+
{"arg":"outer_radius","description":"outer radius for buffers"},
9+
{"arg":"inner_radius","optional":true,"default":"0.0","description":"optional inner radius for buffers"}],
10+
"examples": [ { "expression":"wedge_buffer(center:=geom_from_wkt('POINT(1 2)'),azimuth:=90,width:=180,outer_radius:=1)", "returns":"A wedge shaped buffer centered on the point (1,2), facing to the East, with a width of 180 degrees and outer radius of 1."}]
11+
}
12+

src/core/expression/qgsexpressionfunction.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2492,6 +2492,26 @@ static QVariant fcnBuffer( const QVariantList &values, const QgsExpressionContex
24922492
return result;
24932493
}
24942494

2495+
static QVariant fcnWedgeBuffer( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
2496+
{
2497+
QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
2498+
const QgsPoint *pt = qgsgeometry_cast<const QgsPoint *>( fGeom.constGet() );
2499+
if ( !pt )
2500+
{
2501+
parent->setEvalErrorString( QObject::tr( "Function `wedge_buffer` requires a point value for the center." ) );
2502+
return QVariant();
2503+
}
2504+
2505+
double azimuth = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
2506+
double width = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
2507+
double outerRadius = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent );
2508+
double innerRadius = QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent );
2509+
2510+
QgsGeometry geom = QgsGeometry::createWedgeBuffer( *pt, azimuth, width, outerRadius, innerRadius );
2511+
QVariant result = !geom.isNull() ? QVariant::fromValue( geom ) : QVariant();
2512+
return result;
2513+
}
2514+
24952515
static QVariant fcnOffsetCurve( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
24962516
{
24972517
QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
@@ -4272,6 +4292,11 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
42724292
<< new QgsStaticExpressionFunction( QStringLiteral( "within" ), 2, fcnWithin, QStringLiteral( "GeometryGroup" ) )
42734293
<< new QgsStaticExpressionFunction( QStringLiteral( "translate" ), 3, fcnTranslate, QStringLiteral( "GeometryGroup" ) )
42744294
<< new QgsStaticExpressionFunction( QStringLiteral( "buffer" ), -1, fcnBuffer, QStringLiteral( "GeometryGroup" ) )
4295+
<< new QgsStaticExpressionFunction( QStringLiteral( "wedge_buffer" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "center" ) )
4296+
<< QgsExpressionFunction::Parameter( QStringLiteral( "azimuth" ) )
4297+
<< QgsExpressionFunction::Parameter( QStringLiteral( "width" ) )
4298+
<< QgsExpressionFunction::Parameter( QStringLiteral( "outer_radius" ) )
4299+
<< QgsExpressionFunction::Parameter( QStringLiteral( "inner_radius" ), true, 0.0 ), fcnWedgeBuffer, QStringLiteral( "GeometryGroup" ) )
42754300
<< new QgsStaticExpressionFunction( QStringLiteral( "offset_curve" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ) )
42764301
<< QgsExpressionFunction::Parameter( QStringLiteral( "distance" ) )
42774302
<< QgsExpressionFunction::Parameter( QStringLiteral( "segments" ), true, 8.0 )

tests/src/core/testqgsexpression.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,10 @@ class TestQgsExpression: public QObject
814814
QTest::newRow( "offset_curve line" ) << "geom_to_wkt(offset_curve(geom_from_wkt('LineString(0 0, 10 0)'),1,segments:=4))" << false << QVariant( "LineString (0 1, 10 1)" );
815815
QTest::newRow( "offset_curve line miter" ) << "geom_to_wkt(offset_curve(geometry:=geom_from_wkt('LineString(0 0, 10 0)'),distance:=-1,join:=2,miter_limit:=1))" << false << QVariant( "LineString (10 -1, 0 -1)" );
816816
QTest::newRow( "offset_curve line bevel" ) << "geom_to_wkt(offset_curve(geometry:=geom_from_wkt('LineString(0 0, 10 0, 10 10)'),distance:=1,join:=3))" << false << QVariant( "LineString (0 1, 9 1, 9 10)" );
817+
QTest::newRow( "wedge_buffer not geom" ) << "wedge_buffer('g', 0, 45, 1)" << true << QVariant();
818+
QTest::newRow( "wedge_buffer null" ) << "wedge_buffer(NULL, 0, 45, 1)" << false << QVariant();
819+
QTest::newRow( "wedge_buffer point" ) << "geom_to_wkt(wedge_buffer(center:=geom_from_wkt('POINT(1 2)'),azimuth:=90,width:=180,outer_radius:=1))" << false << QVariant( QStringLiteral( "CurvePolygon (CompoundCurve (CircularString (1 3, 2 2, 1 1),(1 1, 1 2),(1 2, 1 3)))" ) );
820+
QTest::newRow( "wedge_buffer point inner" ) << "geom_to_wkt(wedge_buffer(center:=geom_from_wkt('POINT(1 2)'),azimuth:=90,width:=180,outer_radius:=2,inner_radius:=1))" << false << QVariant( QStringLiteral( "CurvePolygon (CompoundCurve (CircularString (1 4, 3 2, 1 0),(1 0, 1 1),CircularString (1 1, 0 2, 1 3),(1 3, 1 4)))" ) );
817821
QTest::newRow( "single_sided_buffer not geom" ) << "single_sided_buffer('g', 5)" << true << QVariant();
818822
QTest::newRow( "single_sided_buffer null" ) << "single_sided_buffer(NULL, 5)" << false << QVariant();
819823
QTest::newRow( "single_sided_buffer point" ) << "single_sided_buffer(geom_from_wkt('POINT(1 2)'),5)" << false << QVariant();
@@ -1261,9 +1265,9 @@ class TestQgsExpression: public QObject
12611265

12621266
void run_evaluation_test( QgsExpression &exp, bool evalError, QVariant &expected )
12631267
{
1264-
QCOMPARE( exp.hasParserError(), false );
12651268
if ( exp.hasParserError() )
12661269
qDebug() << exp.parserErrorString();
1270+
QCOMPARE( exp.hasParserError(), false );
12671271

12681272
QVariant result = exp.evaluate();
12691273
if ( exp.hasEvalError() )

0 commit comments

Comments
 (0)