From 6021e6d2fe27b42b88e54d752d4b37bfe28a15f1 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 17 Jul 2024 15:44:18 +0200 Subject: [PATCH 1/9] [mvt] fix brush when color is data defined --- src/core/vectortile/qgsmapboxglstyleconverter.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/vectortile/qgsmapboxglstyleconverter.cpp b/src/core/vectortile/qgsmapboxglstyleconverter.cpp index 274bc02db802..1d374c9cdb40 100644 --- a/src/core/vectortile/qgsmapboxglstyleconverter.cpp +++ b/src/core/vectortile/qgsmapboxglstyleconverter.cpp @@ -229,6 +229,8 @@ bool QgsMapBoxGlStyleConverter::parseFillLayer( const QVariantMap &jsonLayer, Qg QgsPropertyCollection ddProperties; QgsPropertyCollection ddRasterProperties; + bool colorIsDataDefined = false; + std::unique_ptr< QgsSymbol > symbol( std::make_unique< QgsFillSymbol >() ); // fill color @@ -244,6 +246,7 @@ bool QgsMapBoxGlStyleConverter::parseFillLayer( const QVariantMap &jsonLayer, Qg case QMetaType::Type::QVariantList: case QMetaType::Type::QStringList: + colorIsDataDefined = true; ddProperties.setProperty( QgsSymbolLayer::Property::FillColor, parseValueList( jsonFillColor.toList(), PropertyType::Color, context, 1, 255, &fillColor ) ); break; @@ -453,7 +456,7 @@ bool QgsMapBoxGlStyleConverter::parseFillLayer( const QVariantMap &jsonLayer, Qg fillSymbol->setStrokeStyle( Qt::NoPen ); } - if ( fillColor.isValid() ) + if ( fillColor.isValid() || colorIsDataDefined ) { fillSymbol->setFillColor( fillColor ); } From 96ca44980e76b141ef65003c148a51878c536d00 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 17 Jul 2024 17:16:50 +0200 Subject: [PATCH 2/9] fix match expression when single value is provided --- src/core/vectortile/qgsmapboxglstyleconverter.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/vectortile/qgsmapboxglstyleconverter.cpp b/src/core/vectortile/qgsmapboxglstyleconverter.cpp index 1d374c9cdb40..faeff57c1d5d 100644 --- a/src/core/vectortile/qgsmapboxglstyleconverter.cpp +++ b/src/core/vectortile/qgsmapboxglstyleconverter.cpp @@ -2682,7 +2682,12 @@ QgsProperty QgsMapBoxGlStyleConverter::parseMatchList( const QVariantList &json, for ( int i = 2; i < json.length() - 1; i += 2 ) { - const QVariantList keys = json.value( i ).toList(); + QVariantList keys; + QVariant variantKeys = json.value( i ); + if ( variantKeys.canConvert< QVariantList >() ) + keys = variantKeys.toList(); + else + keys = {variantKeys}; QStringList matchString; for ( const QVariant &key : keys ) From d723e6b702bcb3ed81662ece6d8d2298eb059c67 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 18 Jul 2024 07:58:31 +0200 Subject: [PATCH 3/9] do not set an invalid color --- src/core/vectortile/qgsmapboxglstyleconverter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/vectortile/qgsmapboxglstyleconverter.cpp b/src/core/vectortile/qgsmapboxglstyleconverter.cpp index faeff57c1d5d..16916a7be39f 100644 --- a/src/core/vectortile/qgsmapboxglstyleconverter.cpp +++ b/src/core/vectortile/qgsmapboxglstyleconverter.cpp @@ -456,11 +456,11 @@ bool QgsMapBoxGlStyleConverter::parseFillLayer( const QVariantMap &jsonLayer, Qg fillSymbol->setStrokeStyle( Qt::NoPen ); } - if ( fillColor.isValid() || colorIsDataDefined ) + if ( fillColor.isValid() ) { fillSymbol->setFillColor( fillColor ); } - else + else if ( !colorIsDataDefined ) { fillSymbol->setBrushStyle( Qt::NoBrush ); } From 4dd28bfff3f6c3d1f6a6c5be6b302b33843b02f0 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 19 Jul 2024 08:35:16 +0200 Subject: [PATCH 4/9] add test for MVT conversion --- tests/src/python/test_qgsmapboxglconverter.py | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/tests/src/python/test_qgsmapboxglconverter.py b/tests/src/python/test_qgsmapboxglconverter.py index 7ffd08900411..d5e720bf52ef 100644 --- a/tests/src/python/test_qgsmapboxglconverter.py +++ b/tests/src/python/test_qgsmapboxglconverter.py @@ -179,6 +179,47 @@ def testParseMatchList(self): 'CASE WHEN "type" IN (\'Normal\') THEN 0.625 WHEN "type" IN (\'Index\') THEN 1.25 ELSE 0.5 END') self.assertEqual(default_number, 0.5) + res, default_color, default_number = QgsMapBoxGlStyleConverter.parseMatchList([ + "match", + [ + "get", + "luminosity" + ], + -15, + "rgb(200,210,213)", + -14, + "rgb(203,213,216)", + -13, + "rgb(207,215,218)", + -12, + "rgb(210,218,221)", + -11, + "rgb(213,221,224)", + -10, + "rgb(217,224,226)", + -9, + "rgb(220,227,229)", + -8, + "rgb(224,230,231)", + -7, + "rgb(227,232,234)", + -6, + "rgb(231,235,237)", + -5, + "rgb(234,238,239)", + -4, + "rgb(238,241,242)", + -3, + "rgb(241,244,245)", + -2, + "rgb(245,247,247)", + -1, + "rgb(248,249,250)", + "rgb(252, 252, 252)" + ], QgsMapBoxGlStyleConverter.PropertyType.Numeric, conversion_context, 2.5, 200) + self.assertEqual(res.asExpression(), 'CASE WHEN "luminosity" IN (-15) THEN 0 WHEN "luminosity" IN (-14) THEN 0 WHEN "luminosity" IN (-13) THEN 0 WHEN "luminosity" IN (-12) THEN 0 WHEN "luminosity" IN (-11) THEN 0 WHEN "luminosity" IN (-10) THEN 0 WHEN "luminosity" IN (-9) THEN 0 WHEN "luminosity" IN (-8) THEN 0 WHEN "luminosity" IN (-7) THEN 0 WHEN "luminosity" IN (-6) THEN 0 WHEN "luminosity" IN (-5) THEN 0 WHEN "luminosity" IN (-4) THEN 0 WHEN "luminosity" IN (-3) THEN 0 WHEN "luminosity" IN (-2) THEN 0 WHEN "luminosity" IN (-1) THEN 0 ELSE 0 END') + self.assertEqual(default_number, 0.0) + def testParseValueList(self): conversion_context = QgsMapBoxGlStyleConversionContext() res, default_color, default_number = QgsMapBoxGlStyleConverter.parseValueList([ @@ -1293,6 +1334,74 @@ def testFillOpacityWithStops(self): prop = dd_props.property(QgsSymbolLayer.Property.PropertyFillColor) self.assertEqual(prop.asExpression(), 'CASE WHEN @vector_tile_zoom < 0 THEN color_hsla(66, 25, 85, 255) WHEN @vector_tile_zoom >= 0 AND @vector_tile_zoom < 8 THEN color_hsla(66, 25, 85, 255) WHEN @vector_tile_zoom >= 8 AND @vector_tile_zoom < 14 THEN color_hsla(66, 25, 85, 255) WHEN @vector_tile_zoom >= 14 AND @vector_tile_zoom < 15 THEN color_hsla(66, scale_linear(@vector_tile_zoom,14,15,25,21), scale_linear(@vector_tile_zoom,14,15,85,90), 255) WHEN @vector_tile_zoom >= 15 AND @vector_tile_zoom < 17 THEN color_hsla(scale_linear(@vector_tile_zoom,15,17,66,67), scale_linear(@vector_tile_zoom,15,17,21,23), scale_linear(@vector_tile_zoom,15,17,90,93), 255) WHEN @vector_tile_zoom >= 17 THEN color_hsla(67, 23, 93, 255) ELSE color_hsla(67, 23, 93, 255) END') + def testFillColorDDHasBrush(self): + context = QgsMapBoxGlStyleConversionContext() + # from https://vectortiles.geo.admin.ch/styles/ch.swisstopo.basemap.vt/style.json + style = { + "id": "building_fill", + "type": "fill", + "source": "base_v1.0.0", + "source-layer": "building", + "minzoom": 14.0, + "layout": { + "visibility": "visible" + }, + "paint": { + "fill-color": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 14, + [ + "match", + [ + "get", + "class" + ], + [ + "roof", + "cooling_tower" + ], + "rgb(210, 210, 214)", + "rgba(184, 184, 188, 1)" + ], + 16, + [ + "match", + [ + "get", + "class" + ], + [ + "roof", + "cooling_tower" + ], + "rgb(210, 210, 214)", + "rgba(184, 184, 188, 1)" + ] + ], + "fill-opacity": 1 + }, + "filter": [ + "all", + [ + "!=", + "class", + "covered_bridge" + ] + ] + } + has_renderer, renderer = QgsMapBoxGlStyleConverter.parseFillLayer(style, context) + self.assertTrue(has_renderer) + self.assertEqual(renderer.symbol()[0].brushStyle(), Qt.BrushStyle.SolidPattern) + dd_props = renderer.symbol()[0].dataDefinedProperties() + prop = dd_props.property(QgsSymbolLayer.Property.PropertyFillColor) + self.assertEqual(prop.asExpression(), 'CASE WHEN @vector_tile_zoom >= 14 AND @vector_tile_zoom < 16 THEN color_hsla(color_part(CASE WHEN "class" IN (\'roof\', \'cooling_tower\') THEN color_rgba(210,210,214,255) ELSE color_rgba(184,184,188,255) END,\'hsl_hue\'), color_part(CASE WHEN "class" IN (\'roof\', \'cooling_tower\') THEN color_rgba(210,210,214,255) ELSE color_rgba(184,184,188,255) END,\'hsl_saturation\'), color_part(CASE WHEN "class" IN (\'roof\', \'cooling_tower\') THEN color_rgba(210,210,214,255) ELSE color_rgba(184,184,188,255) END,\'lightness\'), color_part(CASE WHEN "class" IN (\'roof\', \'cooling_tower\') THEN color_rgba(210,210,214,255) ELSE color_rgba(184,184,188,255) END,\'alpha\')) WHEN @vector_tile_zoom >= 16 THEN color_hsla(color_part(CASE WHEN "class" IN (\'roof\', \'cooling_tower\') THEN color_rgba(210,210,214,255) ELSE color_rgba(184,184,188,255) END,\'hsl_hue\'), color_part(CASE WHEN "class" IN (\'roof\', \'cooling_tower\') THEN color_rgba(210,210,214,255) ELSE color_rgba(184,184,188,255) END,\'hsl_saturation\'), color_part(CASE WHEN "class" IN (\'roof\', \'cooling_tower\') THEN color_rgba(210,210,214,255) ELSE color_rgba(184,184,188,255) END,\'lightness\'), color_part(CASE WHEN "class" IN (\'roof\', \'cooling_tower\') THEN color_rgba(210,210,214,255) ELSE color_rgba(184,184,188,255) END,\'alpha\')) ELSE color_hsla(color_part(CASE WHEN "class" IN (\'roof\', \'cooling_tower\') THEN color_rgba(210,210,214,255) ELSE color_rgba(184,184,188,255) END,\'hsl_hue\'), color_part(CASE WHEN "class" IN (\'roof\', \'cooling_tower\') THEN color_rgba(210,210,214,255) ELSE color_rgba(184,184,188,255) END,\'hsl_saturation\'), color_part(CASE WHEN "class" IN (\'roof\', \'cooling_tower\') THEN color_rgba(210,210,214,255) ELSE color_rgba(184,184,188,255) END,\'lightness\'), color_part(CASE WHEN "class" IN (\'roof\', \'cooling_tower\') THEN color_rgba(210,210,214,255) ELSE color_rgba(184,184,188,255) END,\'alpha\')) END') + if __name__ == '__main__': unittest.main() From 0c0b085621fe85b7107867d35d50efcfefb42921 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 23 Jul 2024 15:20:38 +0200 Subject: [PATCH 5/9] fix parseArray stops are open on both ends --- .../vectortile/qgsmapboxglstyleconverter.cpp | 51 +++++++++---------- tests/src/python/test_qgsmapboxglconverter.py | 4 +- 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/src/core/vectortile/qgsmapboxglstyleconverter.cpp b/src/core/vectortile/qgsmapboxglstyleconverter.cpp index 16916a7be39f..12aa53f892cd 100644 --- a/src/core/vectortile/qgsmapboxglstyleconverter.cpp +++ b/src/core/vectortile/qgsmapboxglstyleconverter.cpp @@ -2462,43 +2462,40 @@ QString QgsMapBoxGlStyleConverter::parseArrayStops( const QVariantList &stops, Q if ( stops.length() < 2 ) return QString(); - QString caseString = QStringLiteral( "CASE " ); + QString caseString = QStringLiteral( "CASE" ); - for ( int i = 0; i < stops.length() - 1; ++i ) + for ( int i = 0; i < stops.length(); ++i ) { - // bottom zoom and value - const QVariant bz = stops.value( i ).toList().value( 0 ); - const QList bv = stops.value( i ).toList().value( 1 ).toList(); - QStringList bl; + caseString += QLatin1String( " WHEN " ); + QStringList conditions; + if ( i > 0 ) + { + const QVariant bottomZoom = stops.value( i ).toList().value( 0 ); + conditions << QStringLiteral( "@vector_tile_zoom > %1" ).arg( bottomZoom.toString() ); + } + if ( i < stops.length() - 1 ) + { + const QVariant topZoom = stops.value( i + 1 ).toList().value( 0 ); + conditions << QStringLiteral( "@vector_tile_zoom <= %1" ).arg( topZoom.toString() ); + } + + const QVariantList values = stops.value( i ).toList().value( 1 ).toList(); + QStringList valuesFixed; bool ok = false; - for ( const QVariant &value : bv ) + for ( const QVariant &value : values ) { const double number = value.toDouble( &ok ); if ( ok ) - bl << QString::number( number * multiplier ); + valuesFixed << QString::number( number * multiplier ); } // top zoom and value - const QVariant tz = stops.value( i + 1 ).toList().value( 0 ); - caseString += QStringLiteral( "WHEN @vector_tile_zoom > %1 AND @vector_tile_zoom <= %2 " - "THEN array(%3) " ).arg( bz.toString(), - tz.toString(), - bl.join( ',' ) ); + caseString += QStringLiteral( "%1 THEN array(%3)" ).arg( + conditions.join( QStringLiteral( " AND " ) ), + valuesFixed.join( ',' ) + ); } - const QVariant lz = stops.value( stops.length() - 1 ).toList().value( 0 ); - const QList lv = stops.value( stops.length() - 1 ).toList().value( 1 ).toList(); - QStringList ll; - bool ok = false; - for ( const QVariant &value : lv ) - { - const double number = value.toDouble( &ok ); - if ( ok ) - ll << QString::number( number * multiplier ); - } - caseString += QStringLiteral( "WHEN @vector_tile_zoom > %1 " - "THEN array(%2) " ).arg( lz.toString(), - ll.join( ',' ) ); - caseString += QLatin1String( "END" ); + caseString += QLatin1String( " END" ); return caseString; } diff --git a/tests/src/python/test_qgsmapboxglconverter.py b/tests/src/python/test_qgsmapboxglconverter.py index d5e720bf52ef..a008691f2ab8 100644 --- a/tests/src/python/test_qgsmapboxglconverter.py +++ b/tests/src/python/test_qgsmapboxglconverter.py @@ -790,11 +790,11 @@ def testParseArrayStops(self): exp = QgsMapBoxGlStyleConverter.parseArrayStops([[0, [0, 1]], [2, [3, 4]]], conversion_context, 1) self.assertEqual(exp, - 'CASE WHEN @vector_tile_zoom > 0 AND @vector_tile_zoom <= 2 THEN array(0,1) WHEN @vector_tile_zoom > 2 THEN array(3,4) END') + 'CASE @vector_tile_zoom <= 2 THEN array(0,1) WHEN @vector_tile_zoom > 2 THEN array(3,4) END') exp = QgsMapBoxGlStyleConverter.parseArrayStops([[0, [0, 1]], [2, [3, 4]]], conversion_context, 2) self.assertEqual(exp, - 'CASE WHEN @vector_tile_zoom > 0 AND @vector_tile_zoom <= 2 THEN array(0,2) WHEN @vector_tile_zoom > 2 THEN array(6,8) END') + 'CASE @vector_tile_zoom <= 2 THEN array(0,2) WHEN @vector_tile_zoom > 2 THEN array(6,8) END') def testParseLineDashArray(self): conversion_context = QgsMapBoxGlStyleConversionContext() From 0497c5704db56eca1f24cabd49104dfb57a824ca Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 24 Jul 2024 08:07:57 +0200 Subject: [PATCH 6/9] fix test --- tests/src/python/test_qgsmapboxglconverter.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/src/python/test_qgsmapboxglconverter.py b/tests/src/python/test_qgsmapboxglconverter.py index a008691f2ab8..554eca0d440e 100644 --- a/tests/src/python/test_qgsmapboxglconverter.py +++ b/tests/src/python/test_qgsmapboxglconverter.py @@ -790,11 +790,11 @@ def testParseArrayStops(self): exp = QgsMapBoxGlStyleConverter.parseArrayStops([[0, [0, 1]], [2, [3, 4]]], conversion_context, 1) self.assertEqual(exp, - 'CASE @vector_tile_zoom <= 2 THEN array(0,1) WHEN @vector_tile_zoom > 2 THEN array(3,4) END') + 'CASE WHEN @vector_tile_zoom <= 2 THEN array(0,1) WHEN @vector_tile_zoom > 2 THEN array(3,4) END') exp = QgsMapBoxGlStyleConverter.parseArrayStops([[0, [0, 1]], [2, [3, 4]]], conversion_context, 2) self.assertEqual(exp, - 'CASE @vector_tile_zoom <= 2 THEN array(0,2) WHEN @vector_tile_zoom > 2 THEN array(6,8) END') + 'CASE WHEN @vector_tile_zoom <= 2 THEN array(0,2) WHEN @vector_tile_zoom > 2 THEN array(6,8) END') def testParseLineDashArray(self): conversion_context = QgsMapBoxGlStyleConversionContext() @@ -827,7 +827,7 @@ def testParseLineDashArray(self): self.assertEqual(dd_properties.property(QgsSymbolLayer.Property.PropertyStrokeWidth).asExpression(), "CASE WHEN @vector_tile_zoom >= 10 AND @vector_tile_zoom <= 11 THEN (1.5) + ((1.2^(@vector_tile_zoom - 10) - 1) / (1.2^(11 - 10) - 1)) * ((2) - (1.5)) WHEN @vector_tile_zoom > 11 AND @vector_tile_zoom <= 12 THEN (2) + ((1.2^(@vector_tile_zoom - 11) - 1) / (1.2^(12 - 11) - 1)) * ((3) - (2)) WHEN @vector_tile_zoom > 12 AND @vector_tile_zoom <= 13 THEN (3) + ((1.2^(@vector_tile_zoom - 12) - 1) / (1.2^(13 - 12) - 1)) * ((5) - (3)) WHEN @vector_tile_zoom > 13 AND @vector_tile_zoom <= 14 THEN (5) + ((1.2^(@vector_tile_zoom - 13) - 1) / (1.2^(14 - 13) - 1)) * ((6) - (5)) WHEN @vector_tile_zoom > 14 AND @vector_tile_zoom <= 16 THEN (6) + ((1.2^(@vector_tile_zoom - 14) - 1) / (1.2^(16 - 14) - 1)) * ((10) - (6)) WHEN @vector_tile_zoom > 16 AND @vector_tile_zoom <= 17 THEN (10) + ((1.2^(@vector_tile_zoom - 16) - 1) / (1.2^(17 - 16) - 1)) * ((12) - (10)) WHEN @vector_tile_zoom > 17 THEN 12 END") self.assertEqual(dd_properties.property(QgsSymbolLayer.Property.PropertyCustomDash).asExpression(), - "array_to_string(array_foreach(CASE WHEN @vector_tile_zoom > 10 AND @vector_tile_zoom <= 17 THEN array(1,1) WHEN @vector_tile_zoom > 17 THEN array(0.3,0.2) END,@element * (CASE WHEN @vector_tile_zoom >= 10 AND @vector_tile_zoom <= 11 THEN (1.5) + ((1.2^(@vector_tile_zoom - 10) - 1) / (1.2^(11 - 10) - 1)) * ((2) - (1.5)) WHEN @vector_tile_zoom > 11 AND @vector_tile_zoom <= 12 THEN (2) + ((1.2^(@vector_tile_zoom - 11) - 1) / (1.2^(12 - 11) - 1)) * ((3) - (2)) WHEN @vector_tile_zoom > 12 AND @vector_tile_zoom <= 13 THEN (3) + ((1.2^(@vector_tile_zoom - 12) - 1) / (1.2^(13 - 12) - 1)) * ((5) - (3)) WHEN @vector_tile_zoom > 13 AND @vector_tile_zoom <= 14 THEN (5) + ((1.2^(@vector_tile_zoom - 13) - 1) / (1.2^(14 - 13) - 1)) * ((6) - (5)) WHEN @vector_tile_zoom > 14 AND @vector_tile_zoom <= 16 THEN (6) + ((1.2^(@vector_tile_zoom - 14) - 1) / (1.2^(16 - 14) - 1)) * ((10) - (6)) WHEN @vector_tile_zoom > 16 AND @vector_tile_zoom <= 17 THEN (10) + ((1.2^(@vector_tile_zoom - 16) - 1) / (1.2^(17 - 16) - 1)) * ((12) - (10)) WHEN @vector_tile_zoom > 17 THEN 12 END)), ';')") + "array_to_string(array_foreach(CASE WHEN @vector_tile_zoom <= 17 THEN array(1,1) WHEN @vector_tile_zoom > 17 THEN array(0.3,0.2) END,@element * (CASE WHEN @vector_tile_zoom >= 10 AND @vector_tile_zoom <= 11 THEN (1.5) + ((1.2^(@vector_tile_zoom - 10) - 1) / (1.2^(11 - 10) - 1)) * ((2) - (1.5)) WHEN @vector_tile_zoom > 11 AND @vector_tile_zoom <= 12 THEN (2) + ((1.2^(@vector_tile_zoom - 11) - 1) / (1.2^(12 - 11) - 1)) * ((3) - (2)) WHEN @vector_tile_zoom > 12 AND @vector_tile_zoom <= 13 THEN (3) + ((1.2^(@vector_tile_zoom - 12) - 1) / (1.2^(13 - 12) - 1)) * ((5) - (3)) WHEN @vector_tile_zoom > 13 AND @vector_tile_zoom <= 14 THEN (5) + ((1.2^(@vector_tile_zoom - 13) - 1) / (1.2^(14 - 13) - 1)) * ((6) - (5)) WHEN @vector_tile_zoom > 14 AND @vector_tile_zoom <= 16 THEN (6) + ((1.2^(@vector_tile_zoom - 14) - 1) / (1.2^(16 - 14) - 1)) * ((10) - (6)) WHEN @vector_tile_zoom > 16 AND @vector_tile_zoom <= 17 THEN (10) + ((1.2^(@vector_tile_zoom - 16) - 1) / (1.2^(17 - 16) - 1)) * ((12) - (10)) WHEN @vector_tile_zoom > 17 THEN 12 END)), ';')") def testParseLineDashArrayOddNumber(self): conversion_context = QgsMapBoxGlStyleConversionContext() From 884861602d149f26d117b64d32f30c81b34547a9 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 24 Jul 2024 11:32:04 +0200 Subject: [PATCH 7/9] set transparent color as fallback Co-authored-by: Mathieu Pellerin --- src/core/vectortile/qgsmapboxglstyleconverter.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/vectortile/qgsmapboxglstyleconverter.cpp b/src/core/vectortile/qgsmapboxglstyleconverter.cpp index 12aa53f892cd..2f2c489fa5ef 100644 --- a/src/core/vectortile/qgsmapboxglstyleconverter.cpp +++ b/src/core/vectortile/qgsmapboxglstyleconverter.cpp @@ -460,7 +460,11 @@ bool QgsMapBoxGlStyleConverter::parseFillLayer( const QVariantMap &jsonLayer, Qg { fillSymbol->setFillColor( fillColor ); } - else if ( !colorIsDataDefined ) + else if ( colorIsDataDefined ) + { + fillSymbol->setFillColor( QColor( Qt::transparent ) ); + } + else { fillSymbol->setBrushStyle( Qt::NoBrush ); } From 8547fa56ee821e85f34490f7bd1555f2cfcba454 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 24 Jul 2024 11:38:22 +0200 Subject: [PATCH 8/9] test for colors --- tests/src/python/test_qgsmapboxglconverter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/python/test_qgsmapboxglconverter.py b/tests/src/python/test_qgsmapboxglconverter.py index 554eca0d440e..502bed4dcb56 100644 --- a/tests/src/python/test_qgsmapboxglconverter.py +++ b/tests/src/python/test_qgsmapboxglconverter.py @@ -216,8 +216,8 @@ def testParseMatchList(self): -1, "rgb(248,249,250)", "rgb(252, 252, 252)" - ], QgsMapBoxGlStyleConverter.PropertyType.Numeric, conversion_context, 2.5, 200) - self.assertEqual(res.asExpression(), 'CASE WHEN "luminosity" IN (-15) THEN 0 WHEN "luminosity" IN (-14) THEN 0 WHEN "luminosity" IN (-13) THEN 0 WHEN "luminosity" IN (-12) THEN 0 WHEN "luminosity" IN (-11) THEN 0 WHEN "luminosity" IN (-10) THEN 0 WHEN "luminosity" IN (-9) THEN 0 WHEN "luminosity" IN (-8) THEN 0 WHEN "luminosity" IN (-7) THEN 0 WHEN "luminosity" IN (-6) THEN 0 WHEN "luminosity" IN (-5) THEN 0 WHEN "luminosity" IN (-4) THEN 0 WHEN "luminosity" IN (-3) THEN 0 WHEN "luminosity" IN (-2) THEN 0 WHEN "luminosity" IN (-1) THEN 0 ELSE 0 END') + ], QgsMapBoxGlStyleConverter.PropertyType.Color, conversion_context, 2.5, 200) + self.assertEqual(res.asExpression(), 'CASE WHEN "luminosity" IN (-15) THEN \'#c8d2d5\' WHEN "luminosity" IN (-14) THEN \'#cbd5d8\' WHEN "luminosity" IN (-13) THEN \'#cfd7da\' WHEN "luminosity" IN (-12) THEN \'#d2dadd\' WHEN "luminosity" IN (-11) THEN \'#d5dde0\' WHEN "luminosity" IN (-10) THEN \'#d9e0e2\' WHEN "luminosity" IN (-9) THEN \'#dce3e5\' WHEN "luminosity" IN (-8) THEN \'#e0e6e7\' WHEN "luminosity" IN (-7) THEN \'#e3e8ea\' WHEN "luminosity" IN (-6) THEN \'#e7ebed\' WHEN "luminosity" IN (-5) THEN \'#eaeeef\' WHEN "luminosity" IN (-4) THEN \'#eef1f2\' WHEN "luminosity" IN (-3) THEN \'#f1f4f5\' WHEN "luminosity" IN (-2) THEN \'#f5f7f7\' WHEN "luminosity" IN (-1) THEN \'#f8f9fa\' ELSE \'#fcfcfc\' END') self.assertEqual(default_number, 0.0) def testParseValueList(self): From 98924d7608b97965b916cc056008f6d0ed4a0819 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 24 Jul 2024 13:56:51 +0200 Subject: [PATCH 9/9] add tolerance --- tests/src/python/test_qgsmapboxglconverter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/src/python/test_qgsmapboxglconverter.py b/tests/src/python/test_qgsmapboxglconverter.py index 502bed4dcb56..d5cc9388de3b 100644 --- a/tests/src/python/test_qgsmapboxglconverter.py +++ b/tests/src/python/test_qgsmapboxglconverter.py @@ -30,6 +30,7 @@ ) import unittest from qgis.testing import start_app, QgisTestCase +from qgis.core import qgsDoubleNear from utilities import getTestFont, unitTestDataPath @@ -218,7 +219,7 @@ def testParseMatchList(self): "rgb(252, 252, 252)" ], QgsMapBoxGlStyleConverter.PropertyType.Color, conversion_context, 2.5, 200) self.assertEqual(res.asExpression(), 'CASE WHEN "luminosity" IN (-15) THEN \'#c8d2d5\' WHEN "luminosity" IN (-14) THEN \'#cbd5d8\' WHEN "luminosity" IN (-13) THEN \'#cfd7da\' WHEN "luminosity" IN (-12) THEN \'#d2dadd\' WHEN "luminosity" IN (-11) THEN \'#d5dde0\' WHEN "luminosity" IN (-10) THEN \'#d9e0e2\' WHEN "luminosity" IN (-9) THEN \'#dce3e5\' WHEN "luminosity" IN (-8) THEN \'#e0e6e7\' WHEN "luminosity" IN (-7) THEN \'#e3e8ea\' WHEN "luminosity" IN (-6) THEN \'#e7ebed\' WHEN "luminosity" IN (-5) THEN \'#eaeeef\' WHEN "luminosity" IN (-4) THEN \'#eef1f2\' WHEN "luminosity" IN (-3) THEN \'#f1f4f5\' WHEN "luminosity" IN (-2) THEN \'#f5f7f7\' WHEN "luminosity" IN (-1) THEN \'#f8f9fa\' ELSE \'#fcfcfc\' END') - self.assertEqual(default_number, 0.0) + self.assertTrue(qgsDoubleNear(default_number, 0.0)) def testParseValueList(self): conversion_context = QgsMapBoxGlStyleConversionContext()