Skip to content

Commit

Permalink
[FEATURE] map_layers variable for layout map items
Browse files Browse the repository at this point in the history
Just like map_layers_ids, but returns direct layer values instead
of ids
  • Loading branch information
nyalldawson committed Aug 27, 2018
1 parent 367d0be commit 820c40a
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 11 deletions.
19 changes: 14 additions & 5 deletions src/core/layout/qgslayoutitemmap.cpp
Expand Up @@ -1155,18 +1155,27 @@ QgsExpressionContext QgsLayoutItemMap::createExpressionContext() const
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_definition" ), mapCrs.toProj4(), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_units" ), QgsUnitTypes::toString( mapCrs.mapUnits() ), true ) );

QVariantList layers_ids;
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layers_ids" ), layers_ids, true ) );
QVariantList layersIds;
QVariantList layers;
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layers_ids" ), layersIds, true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layers" ), layers, true ) );

context.appendScope( scope );

// The scope map_layers_ids has been added to the context, only now we can call layersToRender
// The scope map_layers_ids and map_layers variables have been added to the context, only now we can
// call layersToRender (just in case layersToRender relies on evaluating an expression which uses
// other variables contained within the map settings scope
const QList<QgsMapLayer *> layersInMap = layersToRender( &context );

layersIds.reserve( layersInMap.count() );
layers.reserve( layersInMap.count() );
for ( QgsMapLayer *layer : layersInMap )
{
layers_ids << layer->id();
layersIds << layer->id();
layers << QVariant::fromValue<QgsWeakMapLayerPointer>( QgsWeakMapLayerPointer( layer ) );
}
scope->setVariable( QStringLiteral( "map_layers_ids" ), layers_ids );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layers_ids" ), layersIds, true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layers" ), layers, true ) );

return context;
}
Expand Down
11 changes: 8 additions & 3 deletions src/core/qgsexpressioncontext.cpp
Expand Up @@ -995,13 +995,18 @@ QgsExpressionContextScope *QgsExpressionContextUtils::mapSettingsScope( const Qg
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_definition" ), mapSettings.destinationCrs().toProj4(), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_units" ), QgsUnitTypes::toString( mapSettings.mapUnits() ), true ) );

QVariantList layers_ids;
QVariantList layersIds;
QVariantList layers;
const QList<QgsMapLayer *> layersInMap = mapSettings.layers();
layersIds.reserve( layersInMap.count() );
layers.reserve( layersInMap.count() );
for ( QgsMapLayer *layer : layersInMap )
{
layers_ids << layer->id();
layersIds << layer->id();
layers << QVariant::fromValue<QgsWeakMapLayerPointer>( QgsWeakMapLayerPointer( layer ) );
}
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layers_ids" ), layers_ids, true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layers_ids" ), layersIds, true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layers" ), layers, true ) );

scope->addFunction( QStringLiteral( "is_layer_visible" ), new GetLayerVisibility( mapSettings.layers() ) );

Expand Down
10 changes: 7 additions & 3 deletions tests/src/core/testqgslayoutitem.cpp
Expand Up @@ -1432,11 +1432,15 @@ void TestQgsLayoutItem::itemVariablesFunction()
r = e4.evaluate( &c );
QCOMPARE( r.toString(), QString( "degrees" ) );

QgsVectorLayer *layer = new QgsVectorLayer( QStringLiteral( "Point?field=id_a:integer" ), QStringLiteral( "A" ), QStringLiteral( "memory" ) );
map->setLayers( QList<QgsMapLayer *>() << layer );
std::unique_ptr< QgsVectorLayer > layer = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "Point?field=id_a:integer" ), QStringLiteral( "A" ), QStringLiteral( "memory" ) );
std::unique_ptr< QgsVectorLayer > layer2 = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "Point?field=id_a:integer" ), QStringLiteral( "B" ), QStringLiteral( "memory" ) );
map->setLayers( QList<QgsMapLayer *>() << layer.get() << layer2.get() );
QgsExpression e5( QStringLiteral( "map_get( item_variables( 'Map_id' ), 'map_layers_ids' )" ) );
r = e5.evaluate( &c );
QCOMPARE( r.toStringList().join( ',' ), layer->id() );
QCOMPARE( r.toStringList().join( ',' ), QStringLiteral( "%1,%2" ).arg( layer->id(), layer2->id() ) );
e5 = QgsExpression( QStringLiteral( "array_foreach(map_get( item_variables( 'Map_id' ), 'map_layers' ), layer_property(@element, 'name'))" ) );
r = e5.evaluate( &c );
QCOMPARE( r.toStringList().join( ',' ), QStringLiteral( "A,B" ) );
}

void TestQgsLayoutItem::variables()
Expand Down

0 comments on commit 820c40a

Please sign in to comment.