Skip to content
Permalink
Browse files

[FEATURE][expressions] If a feature is passed to a function

expecting geometry inputs, then use that feature's geometry
instead of throwing an error

eg

buffer(@atlas_feature,100)

or

buffer(get_feature('my_layer','id=54'))
  • Loading branch information
nyalldawson committed May 28, 2016
1 parent 497d6ef commit 7cab60bc4328e6cb4c57f8320c2d85d9383a2424
Showing with 35 additions and 1 deletion.
  1. +10 −1 src/core/qgsexpression.cpp
  2. +25 −0 tests/src/core/testqgsexpression.cpp
@@ -283,6 +283,15 @@ static QgsGeometry getGeometry( const QVariant& value, QgsExpression* parent )
{
if ( value.canConvert<QgsGeometry>() )
return value.value<QgsGeometry>();
else if ( value.canConvert<QgsFeature>() )
{
//try to grab geometry from feature
QgsFeature f = value.value<QgsFeature>();
if ( f.constGeometry() )
{
return *f.constGeometry();
}
}

parent->setEvalErrorString( "Cannot convert to QgsGeometry" );
return QgsGeometry();
@@ -1152,7 +1161,7 @@ static QVariant fcnWordwrap( const QVariantList& values, const QgsExpressionCont
static QVariant fcnLength( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
{
// two variants, one for geometry, one for string
if ( values.at( 0 ).canConvert<QgsGeometry>() )
if ( values.at( 0 ).canConvert<QgsGeometry>() || values.at( 0 ).canConvert<QgsFeature>() )
{
//geometry variant
QgsGeometry geom = getGeometry( values.at( 0 ), parent );
@@ -1548,6 +1548,31 @@ class TestQgsExpression: public QObject
QCOMPARE( out.toDouble(), result );
}

void implicit_feature_to_geometry()
{
// test implicit feature to geometry cast
QgsPolyline polyline;
polyline << QgsPoint( 0, 0 ) << QgsPoint( 10, 0 );
QgsFeature feat;
feat.setGeometry( QgsGeometry::fromPolyline( polyline ) );

QgsExpressionContext context;
context.setFeature( feat );
QgsExpression exp1( "length($currentfeature)" );
QVariant result = exp1.evaluate( &context );
QCOMPARE( result.toDouble(), 10. );

QgsExpression exp2( "x(end_point($currentfeature))" );
result = exp2.evaluate( &context );
QCOMPARE( result.toDouble(), 10. );

// feature without geometry
QgsFeature feat2;
context.setFeature( feat2 );
result = exp2.evaluate( &context );
QVERIFY( !result.isValid() );
}

void eval_geometry_calc()
{
QgsPolyline polyline, polygon_ring;

0 comments on commit 7cab60b

Please sign in to comment.
You can’t perform that action at this time.