Navigation Menu

Skip to content

Commit

Permalink
Merge pull request #8649 from qgis/expression_function_decode_uri
Browse files Browse the repository at this point in the history
Expression function `decode_uri`
  • Loading branch information
m-kuhn committed Dec 19, 2018
2 parents 56ca46e + 0896548 commit 0f037da
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 1 deletion.
12 changes: 12 additions & 0 deletions resources/function_help/json/decode_uri
@@ -0,0 +1,12 @@
{
"name": "decode_uri",
"type": "function",
"description": "Takes a layer and decodes the uri of the underlying data provider. It depends on the dataprovider, which data is available.",
"arguments": [ {"arg":"layer","description":"The layer for which the uri should be decoded."},
{"arg":"part","description":"The part of the uri to return. If unspecified, a map with all uri parts will be returned.","optional":true} ],
"examples": [ { "expression":"decode_uri(@layer)", "returns":"{'layerId': '0', 'layerName': '', 'path': '/home/qgis/shapefile.shp'}"},
{ "expression":"decode_uri(@layer)", "returns":"{'layerId': NULL, 'layerName': 'layer', 'path': '/home/qgis/geopackage.gpkg'}"},
{ "expression":"decode_uri(@layer, 'path')", "returns":"'C:\\\\my_data\\\\qgis\\\\shape.shp'"}
]
}

2 changes: 1 addition & 1 deletion resources/function_help/json/layer_property
Expand Up @@ -4,7 +4,7 @@
"description": "Returns a matching layer property or metadata value.",
"arguments": [
{"arg":"layer", "description":"a string, representing either a layer name or layer ID"},
{"arg":"property", "description":"a string corresponding to the property to return. Valid options are:<br /><ul><li>name: layer name</li><li>id: layer ID</li><li>title: metadata title string</li><li>abstract: metadata abstract string</li><li>keywords: metadata keywords</li><li>data_url: metadata URL</li><li>attribution: metadata attribution string</li><li>attribution_url: metadata attribution URL</li><li>source: layer source</li><li>min_scale: minimum display scale for layer</li><li>max_scale: maximum display scale for layer</li><li>crs: layer CRS</li><li>crs_definition: layer CRS full definition</li><li>crs_description: layer CRS description</li><li>extent: layer extent (as a geometry object)</li><li>type: layer type, e.g., Vector or Raster</li><li>storage_type: storage format (vector layers only)</li><li>geometry_type: geometry type, e.g., Point (vector layers only)</li><li>feature_count: approximate feature count for layer (vector layers only)</li></ul>"}
{"arg":"property", "description":"a string corresponding to the property to return. Valid options are:<br /><ul><li>name: layer name</li><li>id: layer ID</li><li>title: metadata title string</li><li>abstract: metadata abstract string</li><li>keywords: metadata keywords</li><li>data_url: metadata URL</li><li>attribution: metadata attribution string</li><li>attribution_url: metadata attribution URL</li><li>source: layer source</li><li>min_scale: minimum display scale for layer</li><li>max_scale: maximum display scale for layer</li><li>crs: layer CRS</li><li>crs_definition: layer CRS full definition</li><li>crs_description: layer CRS description</li><li>extent: layer extent (as a geometry object)</li><li>type: layer type, e.g., Vector or Raster</li><li>storage_type: storage format (vector layers only)</li><li>geometry_type: geometry type, e.g., Point (vector layers only)</li><li>feature_count: approximate feature count for layer (vector layers only)</li><li>path: File path to the layer data source. Only available for file based layers.</li></ul>"}
],
"examples": [
{ "expression":"layer_property('streets','title')", "returns":"'Basemap Streets'"},
Expand Down
43 changes: 43 additions & 0 deletions src/core/expression/qgsexpressionfunction.cpp
Expand Up @@ -46,6 +46,7 @@
#include "qgsfieldformatterregistry.h"
#include "qgsfieldformatter.h"
#include "qgsvectorlayerfeatureiterator.h"
#include "qgsproviderregistry.h"

const QString QgsExpressionFunction::helpText() const
{
Expand Down Expand Up @@ -4024,12 +4025,49 @@ static QVariant fcnGetLayerProperty( const QVariantList &values, const QgsExpres
return QgsWkbTypes::geometryDisplayString( vLayer->geometryType() );
else if ( QString::compare( layerProperty, QStringLiteral( "feature_count" ), Qt::CaseInsensitive ) == 0 )
return QVariant::fromValue( vLayer->featureCount() );
else if ( QString::compare( layerProperty, QStringLiteral( "path" ), Qt::CaseInsensitive ) == 0 )
{
if ( vLayer->dataProvider() )
{
const QVariantMap decodedUri = QgsProviderRegistry::instance()->decodeUri( layer->providerType(), layer->dataProvider()->dataSourceUri() );
return decodedUri.value( QStringLiteral( "path" ) );
}
}
}
}

return QVariant();
}

static QVariant fcnDecodeUri( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
{
QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
if ( !layer )
{
parent->setEvalErrorString( QObject::tr( "Cannot find layer %1" ).arg( values.at( 0 ).toString() ) );
return QVariant();
}

if ( !layer->dataProvider() )
{
parent->setEvalErrorString( QObject::tr( "Layer %1 has invalid data provider" ).arg( layer->name() ) );
return QVariant();
}

const QString uriPart = values.at( 1 ).toString();

const QVariantMap decodedUri = QgsProviderRegistry::instance()->decodeUri( layer->providerType(), layer->dataProvider()->dataSourceUri() );

if ( !uriPart.isNull() )
{
return decodedUri.value( values.at( 1 ).toString() );
}
else
{
return decodedUri;
}
}

static QVariant fcnGetRasterBandStat( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
{
QString layerIdOrName = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
Expand Down Expand Up @@ -4906,6 +4944,11 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
// **General** functions
sFunctions
<< new QgsStaticExpressionFunction( QStringLiteral( "layer_property" ), 2, fcnGetLayerProperty, QStringLiteral( "General" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "decode_uri" ),
QgsExpressionFunction::ParameterList()
<< QgsExpressionFunction::Parameter( QStringLiteral( "layer" ) )
<< QgsExpressionFunction::Parameter( QStringLiteral( "part" ), true ),
fcnDecodeUri, QStringLiteral( "Map Layers" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "raster_statistic" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "layer" ) )
<< QgsExpressionFunction::Parameter( QStringLiteral( "band" ) )
<< QgsExpressionFunction::Parameter( QStringLiteral( "statistic" ) ), fcnGetRasterBandStat, QStringLiteral( "Rasters" ) );
Expand Down
2 changes: 2 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -1266,6 +1266,8 @@ class TestQgsExpression: public QObject
QTest::newRow( "layer_property storage_type" ) << QStringLiteral( "layer_property('%1','storage_type')" ).arg( mPointsLayer->name() ) << false << QVariant( "ESRI Shapefile" );
QTest::newRow( "layer_property geometry_type" ) << QStringLiteral( "layer_property('%1','geometry_type')" ).arg( mPointsLayer->name() ) << false << QVariant( "Point" );

QTest::newRow( "decode_uri shp path" ) << QStringLiteral( "array_last(string_to_array(replace(decode_uri('%1', 'path'), '\\\\', '/'), '/'))" ).arg( mPointsLayer->name() ) << false << QVariant( "points.shp" );

// raster_statistic tests
QTest::newRow( "raster_statistic no layer" ) << "raster_statistic('',1,'min')" << false << QVariant();
QTest::newRow( "raster_statistic bad layer" ) << "raster_statistic('bad',1,'min')" << false << QVariant();
Expand Down

0 comments on commit 0f037da

Please sign in to comment.