Skip to content

Commit ecf1f5a

Browse files
authoredJan 25, 2017
[FEATURE] expression engine's is_layer_visible() (#4045)
1 parent a61b922 commit ecf1f5a

File tree

4 files changed

+136
-0
lines changed

4 files changed

+136
-0
lines changed
 
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "is_layer_visible",
3+
"type": "function",
4+
"description": "Returns true if a specified layer is visible.",
5+
"arguments": [
6+
{"arg":"layer", "description":"a string, representing either a layer name or layer ID"}
7+
],
8+
"examples": [
9+
{ "expression":"is_layer_visible('baseraster')", "returns":"True"}
10+
]
11+
}

‎src/core/qgsexpressioncontext.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include "qgsatlascomposition.h"
2828
#include "qgsapplication.h"
2929
#include "qgsmapsettings.h"
30+
#include "qgsmaplayerlistutils.h"
31+
3032
#include <QSettings>
3133
#include <QDir>
3234

@@ -644,6 +646,43 @@ class GetComposerItemVariables : public QgsScopedExpressionFunction
644646

645647
};
646648

649+
class GetLayerVisibility : public QgsScopedExpressionFunction
650+
{
651+
public:
652+
GetLayerVisibility( QList<QgsMapLayer*> layers )
653+
: QgsScopedExpressionFunction( QStringLiteral( "is_layer_visible" ), QgsExpression::ParameterList() << QgsExpression::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "General" ) )
654+
, mLayers( layers )
655+
{}
656+
657+
virtual QVariant func( const QVariantList& values, const QgsExpressionContext*, QgsExpression* ) override
658+
{
659+
if ( mLayers.isEmpty() )
660+
{
661+
return QVariant( false );
662+
}
663+
664+
QgsMapLayer* layer = _qgis_findLayer( mLayers, values.at( 0 ).toString() );
665+
if ( layer )
666+
{
667+
return QVariant( true );
668+
}
669+
else
670+
{
671+
return QVariant( false );
672+
}
673+
}
674+
675+
QgsScopedExpressionFunction* clone() const override
676+
{
677+
return new GetLayerVisibility( mLayers );
678+
}
679+
680+
private:
681+
682+
const QList<QgsMapLayer*> mLayers;
683+
684+
};
685+
647686
///@endcond
648687

649688
QgsExpressionContextScope* QgsExpressionContextUtils::projectScope( const QgsProject* project )
@@ -807,6 +846,8 @@ QgsExpressionContextScope* QgsExpressionContextUtils::mapSettingsScope( const Qg
807846
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_definition" ), mapSettings.destinationCrs().toProj4(), true ) );
808847
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_units" ), QgsUnitTypes::toString( mapSettings.mapUnits() ), true ) );
809848

849+
scope->addFunction( QStringLiteral( "is_layer_visible" ), new GetLayerVisibility( mapSettings.layers() ) );
850+
810851
return scope;
811852
}
812853

@@ -1013,6 +1054,7 @@ void QgsExpressionContextUtils::registerContextFunctions()
10131054
{
10141055
QgsExpression::registerFunction( new GetNamedProjectColor( nullptr ) );
10151056
QgsExpression::registerFunction( new GetComposerItemVariables( nullptr ) );
1057+
QgsExpression::registerFunction( new GetLayerVisibility( QList<QgsMapLayer*>() ) );
10161058
}
10171059

10181060
bool QgsScopedExpressionFunction::usesGeometry( const QgsExpression::NodeFunction* node ) const

‎src/core/qgsmaplayerlistutils.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,48 @@ inline QStringList _qgis_listQPointerToIDs( const QList< QPointer<QgsMapLayer> >
5151
return lst;
5252
}
5353

54+
inline static QgsMapLayer* _qgis_findLayer( const QList< QgsMapLayer*> layers, const QString& identifier )
55+
{
56+
QgsMapLayer* matchId = nullptr;
57+
QgsMapLayer* matchName = nullptr;
58+
QgsMapLayer* matchNameInsensitive = nullptr;
59+
60+
// Look for match against layer IDs
61+
Q_FOREACH ( QgsMapLayer* layer, layers )
62+
{
63+
if ( !matchId && layer->id() == identifier )
64+
{
65+
matchId = layer;
66+
break;
67+
}
68+
if ( !matchName && layer->name() == identifier )
69+
{
70+
matchName = layer;
71+
}
72+
if ( !matchNameInsensitive && QString::compare( layer->name(), identifier, Qt::CaseInsensitive ) == 0 )
73+
{
74+
matchNameInsensitive = layer;
75+
}
76+
}
77+
78+
if ( matchId )
79+
{
80+
return matchId;
81+
}
82+
else if ( matchName )
83+
{
84+
return matchName;
85+
}
86+
else if ( matchNameInsensitive )
87+
{
88+
return matchNameInsensitive;
89+
}
90+
else
91+
{
92+
return nullptr;
93+
}
94+
}
95+
5496
///@endcond
5597

5698
#endif // QGSMAPLAYERLISTUTILS_H

‎tests/src/core/testqgsmapsettings.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <math.h>
1919

2020
//header for class being tested
21+
#include "qgsexpression.h"
22+
#include "qgsexpressioncontext.h"
2123
#include "qgsrectangle.h"
2224
#include "qgsmapsettings.h"
2325
#include "qgspoint.h"
@@ -34,6 +36,7 @@ class TestQgsMapSettings: public QObject
3436
void visibleExtent();
3537
void mapUnitsPerPixel();
3638
void visiblePolygon();
39+
void testIsLayerVisible();
3740
void testMapLayerListUtils();
3841
private:
3942
QString toString( const QPolygonF& p, int decimalPlaces = 2 ) const;
@@ -149,6 +152,38 @@ void TestQgsMapSettings::visiblePolygon()
149152
QString( "32.32 28.03,103.03 -42.67,67.67 -78.03,-3.03 -7.32" ) );
150153
}
151154

155+
void TestQgsMapSettings::testIsLayerVisible()
156+
{
157+
QgsVectorLayer* vlA = new QgsVectorLayer( "Point", "a", "memory" );
158+
QgsVectorLayer* vlB = new QgsVectorLayer( "Point", "b", "memory" );
159+
160+
QList<QgsMapLayer*> layers;
161+
layers << vlA << vlB;
162+
163+
QgsMapSettings ms;
164+
ms.setLayers( layers );
165+
QgsExpressionContext context;
166+
context << QgsExpressionContextUtils::mapSettingsScope( ms );
167+
168+
// test checking for visible layer by id
169+
QgsExpression e( QString( "is_layer_visible( '%1' )" ).arg( vlA-> id() ) );
170+
QVariant r = e.evaluate( &context );
171+
QCOMPARE( r.toBool(), true );
172+
173+
// test checking for visible layer by name
174+
QgsExpression e2( QString( "is_layer_visible( '%1' )" ).arg( vlB-> name() ) );
175+
r = e2.evaluate( &context );
176+
QCOMPARE( r.toBool(), true );
177+
178+
// test checking for non-existant layer
179+
QgsExpression e3( QString( "is_layer_visible( 'non matching name' )" ) );
180+
r = e3.evaluate( &context );
181+
QCOMPARE( r.toBool(), false );
182+
183+
delete vlA;
184+
delete vlB;
185+
}
186+
152187
void TestQgsMapSettings::testMapLayerListUtils()
153188
{
154189
QgsVectorLayer* vlA = new QgsVectorLayer( "Point", "a", "memory" );
@@ -157,6 +192,12 @@ void TestQgsMapSettings::testMapLayerListUtils()
157192
QList<QgsMapLayer*> listRawSource;
158193
listRawSource << vlA << vlB;
159194

195+
QgsMapLayer* l = _qgis_findLayer( listRawSource, QStringLiteral( "a" ) );
196+
QCOMPARE( l, vlA );
197+
198+
l = _qgis_findLayer( listRawSource, QStringLiteral( "z" ) );
199+
QCOMPARE( !l, true );
200+
160201
QList< QPointer<QgsMapLayer> > listQPointer = _qgis_listRawToQPointer( listRawSource );
161202

162203
QCOMPARE( listQPointer.count(), 2 );

0 commit comments

Comments
 (0)
Please sign in to comment.