Skip to content

Commit

Permalink
get_features multi arg
Browse files Browse the repository at this point in the history
  • Loading branch information
roya0045 committed Dec 8, 2021
1 parent 3f00597 commit df07610
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 18 deletions.
19 changes: 15 additions & 4 deletions resources/function_help/json/get_feature
Expand Up @@ -3,8 +3,19 @@
"type": "function",
"groups": ["Record and Attributes"],
"description": "Returns the first feature of a layer matching a given attribute value.",
"arguments": [ {"arg":"layer","description":"layer name or ID"},
{"arg":"attribute","description":"attribute name"},
{"arg":"value","description":"attribute value to match"}],
"examples": [ { "expression":"get_feature('streets','name','main st')", "returns":"first feature found in \"streets\" layer with \"main st\" value in the \"name\" field"}]
"variants": [
{ "variant": "Single value variant",
"variant_description": "Along with the layer ID, a single column and value are specified.",
"arguments": [ {"arg":"layer","description":"layer name or ID"},
{"arg":"attribute","description":"attribute name to use for the match"},
{"arg":"value","description":"attribute value to match"}],
"examples": [ { "expression":"get_feature('streets','name','main st')", "returns":"first feature found in \"streets\" layer with \"main st\" value in the \"name\" field"} ]
},
{
"variant": "Map variant",
"variant_description": "Along with the layer ID, a map containing the columns (key) and their respective value to be used.",
"arguments": [ {"arg":"layer","description":"layer name or ID"},
{"arg":"map","description":"Map containing the column and value pairs to use"}],
"examples": [ { "expression":"get_feature('streets',map('name','main st','lane_num','4'))", "returns":"first feature found in \"streets\" layer with \"main st\" value in the \"name\" field and \"4\" value in the \"lane_num\" field"} ]
} ]
}
54 changes: 40 additions & 14 deletions src/core/expression/qgsexpressionfunction.cpp
Expand Up @@ -5475,25 +5475,51 @@ static QVariant fcnGetFeature( const QVariantList &values, const QgsExpressionCo
{
return QVariant();
}

QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
int attributeId = featureSource->fields().lookupField( attribute );
if ( attributeId == -1 )
QgsFeatureRequest req;
QString cacheValueKey;
if ( values.size() == 2 && values.at( 1 ).canConvert<QVariantMap>() )
{
return QVariant();
QVariantMap map= values.at( 1 ).toMap();

QMap <QString, QVariant>::const_iterator i = map.constBegin();
QString filterString;
for ( ; i != map.constEnd(); ++i )
{
if ( !filterString.isEmpty() )
{
filterString.append( " AND " );
}
filterString.append( QStringLiteral( "( %1 = %2 )" ).arg( QgsExpression::quotedColumnRef( i.key() ),
QgsExpression::quotedString( i.value()->toString() ) ) );
}
cacheValueKey = QStringLiteral( "getfeature:%1:%2" ).arg( featureSource->id(),
filterString );
if ( context && context->hasCachedValue( cacheValueKey ) )
{
return context->cachedValue( cacheValueKey );
}
req.setFilterExpression( filterString );
}
else
{
QString attribute = QgsExpressionUtils::getStringValue( values.at( 1 ), parent );
int attributeId = featureSource->fields().lookupField( attribute );
if ( attributeId == -1 )
{
return QVariant();
}

const QVariant &attVal = values.at( 2 );
const QVariant &attVal = values.at( 2 );

const QString cacheValueKey = QStringLiteral( "getfeature:%1:%2:%3" ).arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
if ( context && context->hasCachedValue( cacheValueKey ) )
{
return context->cachedValue( cacheValueKey );
}
cacheValueKey = QStringLiteral( "getfeature:%1:%2:%3" ).arg( featureSource->id(), QString::number( attributeId ), attVal.toString() );
if ( context && context->hasCachedValue( cacheValueKey ) )
{
return context->cachedValue( cacheValueKey );
}

QgsFeatureRequest req;
req.setFilterExpression( QStringLiteral( "%1=%2" ).arg( QgsExpression::quotedColumnRef( attribute ),
QgsExpression::quotedString( attVal.toString() ) ) );
req.setFilterExpression( QStringLiteral( "%1=%2" ).arg( QgsExpression::quotedColumnRef( attribute ),
QgsExpression::quotedString( attVal.toString() ) ) );
}
req.setLimit( 1 );
req.setTimeout( 10000 );
req.setRequestMayBeNested( true );
Expand Down
9 changes: 9 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -2246,6 +2246,15 @@ class TestQgsExpression: public QObject

// get_feature_by_id
QTest::newRow( "get_feature_by_id" ) << "get_feature_by_id('test', 1)" << true << 1;

// multi-param
QTest::newRow( "get_feature multi1" ) << "get_feature('test',map('col1','11','col2','test2'))" << true << 2;
QTest::newRow( "get_feature multi2" ) << "get_feature('test',map('col1','3','col2','test3'))" << true << 3;

// multi-param no match
QTest::newRow( "get_feature no match-multi1" ) << "get_feature('test',array('col1','col2'),'no match!')" << false << -1;
QTest::newRow( "get_feature no match-multi2" ) << "get_feature('test',array('col1','col2'),array('10','test3'))" << false << -1;

}

void eval_get_feature()
Expand Down

0 comments on commit df07610

Please sign in to comment.