Skip to content

Commit

Permalink
Make @zoom_level and @vector_tile_zoom expression variables always
Browse files Browse the repository at this point in the history
available, not just for vector tile layers

These are generic properties related to the map scale only, so by
moving them up to the map settings level we then make it possible
to copy symbols from vector tiles to non-vector tile layers,
without breaking any nice symbology rules which utilise tile zoom
levels (such as those converted from mapbox styles)
  • Loading branch information
nyalldawson authored and github-actions[bot] committed Jan 24, 2022
1 parent 0480319 commit 6dfb467
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/core/expression/qgsexpression.cpp
Expand Up @@ -805,8 +805,8 @@ void QgsExpression::initVariableHelp()
sVariableHelpTexts()->insert( QStringLiteral( "animation_interval" ), QCoreApplication::translate( "variable_help", "Duration of the animation's overall temporal time range (as an interval value)" ) );

// vector tile layer variables
sVariableHelpTexts()->insert( QStringLiteral( "zoom_level" ), QCoreApplication::translate( "variable_help", "Zoom level of the tile that is being rendered (derived from the current map scale). Normally in interval [0, 20]." ) );
sVariableHelpTexts()->insert( QStringLiteral( "vector_tile_zoom" ), QCoreApplication::translate( "variable_help", "Exact zoom level of the tile that is being rendered (derived from the current map scale). Normally in interval [0, 20]. Unlike @zoom_level, this variable is a floating point value which can be used to interpolated values between two integer zoom levels." ) );
sVariableHelpTexts()->insert( QStringLiteral( "zoom_level" ), QCoreApplication::translate( "variable_help", "Vector tile zoom level of the map that is being rendered (derived from the current map scale). Normally in interval [0, 20]." ) );
sVariableHelpTexts()->insert( QStringLiteral( "vector_tile_zoom" ), QCoreApplication::translate( "variable_help", "Exact vector tile zoom level of the map that is being rendered (derived from the current map scale). Normally in interval [0, 20]. Unlike @zoom_level, this variable is a floating point value which can be used to interpolated values between two integer zoom levels." ) );

sVariableHelpTexts()->insert( QStringLiteral( "row_number" ), QCoreApplication::translate( "variable_help", "Stores the number of the current row." ) );
sVariableHelpTexts()->insert( QStringLiteral( "grid_number" ), QCoreApplication::translate( "variable_help", "Current grid annotation value." ) );
Expand Down
4 changes: 4 additions & 0 deletions src/core/expression/qgsexpressioncontextutils.cpp
Expand Up @@ -35,6 +35,7 @@
#include "qgsprojoperation.h"
#include "qgsmarkersymbol.h"
#include "qgstriangularmesh.h"
#include "qgsvectortileutils.h"

QgsExpressionContextScope *QgsExpressionContextUtils::globalScope()
{
Expand Down Expand Up @@ -437,6 +438,9 @@ QgsExpressionContextScope *QgsExpressionContextUtils::mapSettingsScope( const Qg
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_rotation" ), mapSettings.rotation(), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_scale" ), mapSettings.scale(), true ) );

scope->setVariable( QStringLiteral( "zoom_level" ), QgsVectorTileUtils::scaleToZoomLevel( mapSettings.scale(), 0, 99999 ), true );
scope->setVariable( QStringLiteral( "vector_tile_zoom" ), QgsVectorTileUtils::scaleToZoom( mapSettings.scale() ), true );

// IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
// (rationale is described in QgsLayoutItemMap::createExpressionContext() )

Expand Down
7 changes: 6 additions & 1 deletion src/core/layout/qgslayoutitemmap.cpp
Expand Up @@ -37,6 +37,7 @@
#include "qgscoordinatereferencesystemregistry.h"
#include "qgsprojoperation.h"
#include "qgslabelingresults.h"
#include "qgsvectortileutils.h"

#include <QPainter>
#include <QStyleOptionGraphicsItem>
Expand Down Expand Up @@ -1670,7 +1671,11 @@ QgsExpressionContext QgsLayoutItemMap::createExpressionContext() const

scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_id" ), id(), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_rotation" ), mMapRotation, true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_scale" ), scale(), true ) );
const double mapScale = scale();
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_scale" ), mapScale, true ) );

scope->setVariable( QStringLiteral( "zoom_level" ), QgsVectorTileUtils::scaleToZoomLevel( mapScale, 0, 99999 ), true );
scope->setVariable( QStringLiteral( "vector_tile_zoom" ), QgsVectorTileUtils::scaleToZoom( mapScale ), true );

QgsRectangle currentExtent( extent() );
scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent" ), QVariant::fromValue( QgsGeometry::fromRect( currentExtent ) ), true ) );
Expand Down
8 changes: 8 additions & 0 deletions tests/src/core/testqgsmapsettings.cpp
Expand Up @@ -492,6 +492,14 @@ void TestQgsMapSettings::testExpressionContext()
r = e.evaluate( &c );
QGSCOMPARENEAR( r.toDouble(), 247990, 10.0 );

e = QgsExpression( QStringLiteral( "@zoom_level" ) );
r = e.evaluate( &c );
QCOMPARE( r.toDouble(), 10.0 );

e = QgsExpression( QStringLiteral( "@vector_tile_zoom" ) );
r = e.evaluate( &c );
QGSCOMPARENEAR( r.toDouble(), 10.1385606747, 0.0001 );

// The old $scale function should silently map to @map_scale, so that older projects work without change
e = QgsExpression( QStringLiteral( "$scale" ) );
r = e.evaluate( &c );
Expand Down

0 comments on commit 6dfb467

Please sign in to comment.