From cb7838badc85d423be1281e8e66788d9070d6b12 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 22 Jan 2019 11:53:35 +1000 Subject: [PATCH] Silently alias old "$scale" expression function to "@map_scale" (when available) Allows older projects to open without change. We still hide $scale from the builder UI, as we eventually want to clamp out its use. --- src/core/expression/qgsexpressionfunction.cpp | 21 +++++- tests/src/core/testqgsmapsettings.cpp | 67 +++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index dbadf4e5d6b..21a87e5b237 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -889,6 +889,22 @@ static QVariant fcnAggregateArray( const QVariantList &values, const QgsExpressi return fcnAggregateGeneric( QgsAggregateCalculator::ArrayAggregate, values, QgsAggregateCalculator::AggregateParameters(), context, parent ); } +static QVariant fcnMapScale( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) +{ + if ( !context ) + return QVariant(); + + QVariant scale = context->variable( QStringLiteral( "map_scale" ) ); + bool ok = false; + if ( !scale.isValid() || scale.isNull() ) + return QVariant(); + + const double v = scale.toDouble( &ok ); + if ( ok ) + return v; + return QVariant(); +} + static QVariant fcnClamp( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) { double minValue = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent ); @@ -4877,7 +4893,10 @@ const QList &QgsExpression::Functions() << new QgsStaticExpressionFunction( QStringLiteral( "color_part" ), 2, fncColorPart, QStringLiteral( "Color" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "darker" ), 2, fncDarker, QStringLiteral( "Color" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "lighter" ), 2, fncLighter, QStringLiteral( "Color" ) ) - << new QgsStaticExpressionFunction( QStringLiteral( "set_color_part" ), 3, fncSetColorPart, QStringLiteral( "Color" ) ); + << new QgsStaticExpressionFunction( QStringLiteral( "set_color_part" ), 3, fncSetColorPart, QStringLiteral( "Color" ) ) + + // deprecated stuff - hidden from users + << new QgsStaticExpressionFunction( QStringLiteral( "$scale" ), QgsExpressionFunction::ParameterList(), fcnMapScale, QStringLiteral( "deprecated" ) ); QgsStaticExpressionFunction *geomFunc = new QgsStaticExpressionFunction( QStringLiteral( "$geometry" ), 0, fcnGeometry, QStringLiteral( "GeometryGroup" ), QString(), true ); geomFunc->setIsStatic( false ); diff --git a/tests/src/core/testqgsmapsettings.cpp b/tests/src/core/testqgsmapsettings.cpp index 26cb6200d9c..30e44e14255 100644 --- a/tests/src/core/testqgsmapsettings.cpp +++ b/tests/src/core/testqgsmapsettings.cpp @@ -46,6 +46,7 @@ class TestQgsMapSettings: public QObject void testXmlReadWrite(); void testSetLayers(); void testLabelBoundary(); + void testExpressionContext(); private: QString toString( const QPolygonF &p, int decimalPlaces = 2 ) const; @@ -376,5 +377,71 @@ void TestQgsMapSettings::testLabelBoundary() QCOMPARE( ms.labelBoundaryGeometry().asWkt(), QStringLiteral( "Polygon ((0 0, 1 0, 1 1, 0 1, 0 0))" ) ); } +void TestQgsMapSettings::testExpressionContext() +{ + QgsMapSettings ms; + QgsExpressionContext c; + QVariant r; + + ms.setOutputSize( QSize( 5000, 5000 ) ); + ms.setExtent( QgsRectangle( -1, 0, 2, 2 ) ); + ms.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ) ); + ms.setRotation( -32 ); + c << QgsExpressionContextUtils::mapSettingsScope( ms ); + + QgsExpression e( QStringLiteral( "@map_scale" ) ); + r = e.evaluate( &c ); + QGSCOMPARENEAR( r.toDouble(), 247990, 10 ); + + // 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 ); + QGSCOMPARENEAR( r.toDouble(), 247990, 10 ); + + // no map settings scope -- $scale is meaningless + e = QgsExpression( QStringLiteral( "$scale" ) ); + r = e.evaluate( nullptr ); + QVERIFY( !r.isValid() ); + + e = QgsExpression( QStringLiteral( "@map_id" ) ); + r = e.evaluate( &c ); + QCOMPARE( r.toString(), QStringLiteral( "canvas" ) ); + + e = QgsExpression( QStringLiteral( "@map_rotation" ) ); + r = e.evaluate( &c ); + QCOMPARE( r.toDouble(), -32.0 ); + + ms.setRotation( 0 ); + c << QgsExpressionContextUtils::mapSettingsScope( ms ); + + e = QgsExpression( QStringLiteral( "geom_to_wkt( @map_extent )" ) ); + r = e.evaluate( &c ); + QCOMPARE( r.toString(), QStringLiteral( "Polygon ((-1 -0.5, 2 -0.5, 2 2.5, -1 2.5, -1 -0.5))" ) ); + + e = QgsExpression( QStringLiteral( "@map_extent_width" ) ); + r = e.evaluate( &c ); + QCOMPARE( r.toDouble(), 3 ); + + e = QgsExpression( QStringLiteral( "@map_extent_height" ) ); + r = e.evaluate( &c ); + QCOMPARE( r.toDouble(), 3 ); + + e = QgsExpression( QStringLiteral( "geom_to_wkt( @map_extent_center )" ) ); + r = e.evaluate( &c ); + QCOMPARE( r.toString(), QStringLiteral( "Point (0.5 1)" ) ); + + e = QgsExpression( QStringLiteral( "@map_crs" ) ); + r = e.evaluate( &c ); + QCOMPARE( r.toString(), QStringLiteral( "EPSG:4326" ) ); + + e = QgsExpression( QStringLiteral( "@map_crs_definition" ) ); + r = e.evaluate( &c ); + QCOMPARE( r.toString(), QStringLiteral( "+proj=longlat +datum=WGS84 +no_defs" ) ); + + e = QgsExpression( QStringLiteral( "@map_units" ) ); + r = e.evaluate( &c ); + QCOMPARE( r.toString(), QStringLiteral( "degrees" ) ); +} + QGSTEST_MAIN( TestQgsMapSettings ) #include "testqgsmapsettings.moc"