From 2bd635461a79d98a3c1c3ae505fb70b79168577c Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 27 Sep 2024 08:49:42 +0200 Subject: [PATCH] [mvt] fix opacity incorrectly for low scale (#58882) * [mvt] fix opacity incorrectly for low scale if the opactiy was defined by expression on the lower scale bound, it was incorrectly set to 0 * simplify test --- .../vectortile/qgsmapboxglstyleconverter.cpp | 22 +++++++++++++------ tests/src/python/test_qgsmapboxglconverter.py | 12 ++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/core/vectortile/qgsmapboxglstyleconverter.cpp b/src/core/vectortile/qgsmapboxglstyleconverter.cpp index af2d74e50156..229b4334d367 100644 --- a/src/core/vectortile/qgsmapboxglstyleconverter.cpp +++ b/src/core/vectortile/qgsmapboxglstyleconverter.cpp @@ -2458,10 +2458,12 @@ QgsProperty QgsMapBoxGlStyleConverter::parseInterpolateByZoom( const QVariantMap QString scaleExpression; if ( stops.size() <= 2 ) { - scaleExpression = interpolateExpression( stops.value( 0 ).toList().value( 0 ).toDouble(), - stops.last().toList().value( 0 ).toDouble(), - stops.value( 0 ).toList().value( 1 ), - stops.last().toList().value( 1 ), base, multiplier, &context ); + scaleExpression = interpolateExpression( + stops.value( 0 ).toList().value( 0 ).toDouble(), // zoomMin + stops.last().toList().value( 0 ).toDouble(), // zoomMax + stops.value( 0 ).toList().value( 1 ), // valueMin + stops.last().toList().value( 1 ), // valueMax + base, multiplier, &context ); } else { @@ -2532,10 +2534,16 @@ QString QgsMapBoxGlStyleConverter::parseOpacityStops( double base, const QVarian base, 1, &context ) ); } + + bool numeric = false; + const QVariant vv = stops.last().toList().value( 1 ); + double dv = vv.toDouble( &numeric ); + caseString += QStringLiteral( " WHEN @vector_tile_zoom >= %1 " - "THEN set_color_part(@symbol_color, 'alpha', %2) END" ) - .arg( stops.last().toList().value( 0 ).toString() ) - .arg( stops.last().toList().value( 1 ).toDouble() * maxOpacity ); + "THEN set_color_part(@symbol_color, 'alpha', %2) END" ).arg( + stops.last().toList().value( 0 ).toString(), + numeric ? QString::number( dv * maxOpacity ) : QString( "(%1) * %2" ).arg( parseValue( vv, context ) ).arg( maxOpacity ) + ); return caseString; } diff --git a/tests/src/python/test_qgsmapboxglconverter.py b/tests/src/python/test_qgsmapboxglconverter.py index c0175a6a3858..0cfcd343f2c3 100644 --- a/tests/src/python/test_qgsmapboxglconverter.py +++ b/tests/src/python/test_qgsmapboxglconverter.py @@ -385,6 +385,18 @@ def testInterpolateOpacityByZoom(self): conversion_context).expressionString(), "set_color_part(@symbol_color, 'alpha', 25.5)") + self.assertEqual(QgsMapBoxGlStyleConverter.parseInterpolateOpacityByZoom({'base': 2, + 'stops': [ + [10, 0], + [11, ["match", ["get", "class"], ["path"], 0.5, 0]], + [13, ["match", ["get", "class"], ["path"], 1, 0.5]]] + }, 255, + conversion_context).expressionString(), + ('''CASE WHEN @vector_tile_zoom < 10 THEN set_color_part(@symbol_color, 'alpha', 0) ''' + '''WHEN @vector_tile_zoom >= 10 AND @vector_tile_zoom < 11 THEN set_color_part(@symbol_color, 'alpha', ((0) * 255) + ((2^(@vector_tile_zoom - 10) - 1) / (2^(11 - 10) - 1)) * (((CASE WHEN "class" = 'path' THEN 0.5 ELSE 0 END) * 255) - ((0) * 255))) ''' + '''WHEN @vector_tile_zoom >= 11 AND @vector_tile_zoom < 13 THEN set_color_part(@symbol_color, 'alpha', ((CASE WHEN "class" = 'path' THEN 0.5 ELSE 0 END) * 255) + ((2^(@vector_tile_zoom - 11) - 1) / (2^(13 - 11) - 1)) * (((CASE WHEN "class" = 'path' THEN 1 ELSE 0.5 END) * 255) - ((CASE WHEN "class" = 'path' THEN 0.5 ELSE 0 END) * 255))) ''' + '''WHEN @vector_tile_zoom >= 13 THEN set_color_part(@symbol_color, 'alpha', (CASE WHEN "class" = 'path' THEN 1 ELSE 0.5 END) * 255) END''')) + def testInterpolateListByZoom(self): conversion_context = QgsMapBoxGlStyleConversionContext() prop, default_color, default_val = QgsMapBoxGlStyleConverter.parseInterpolateListByZoom([