Skip to content

Commit c09e96b

Browse files
committedApr 24, 2023
Fix conversion of max zoom level from mapbox styles
The QGIS renderers for vector tiles treat maxzoom different to the MapBox Style Specifications. From the MapBox Specifications: "The maximum zoom level for the layer. At zoom levels equal to or greater than the maxzoom, the layer will be hidden." However the QGIS styles will be hidden if the zoom level is GREATER THAN (not equal to) maxzoom. Accordingly we need to subtract 1 from the maxzoom value when converting mapbox styles
1 parent 67e1a5e commit c09e96b

File tree

2 files changed

+77
-1
lines changed

2 files changed

+77
-1
lines changed
 

‎src/core/vectortile/qgsmapboxglstyleconverter.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,17 @@ void QgsMapBoxGlStyleConverter::parseLayers( const QVariantList &layers, QgsMapB
136136
const QString layerName = jsonLayer.value( QStringLiteral( "source-layer" ) ).toString();
137137

138138
const int minZoom = jsonLayer.value( QStringLiteral( "minzoom" ), QStringLiteral( "-1" ) ).toInt();
139-
const int maxZoom = jsonLayer.value( QStringLiteral( "maxzoom" ), QStringLiteral( "-1" ) ).toInt();
139+
140+
// WARNING -- the QGIS renderers for vector tiles treat maxzoom different to the MapBox Style Specifications.
141+
// from the MapBox Specifications:
142+
//
143+
// "The maximum zoom level for the layer. At zoom levels equal to or greater than the maxzoom, the layer will be hidden."
144+
//
145+
// However the QGIS styles will be hidden if the zoom level is GREATER THAN (not equal to) maxzoom.
146+
// Accordingly we need to subtract 1 from the maxzoom value in the JSON:
147+
int maxZoom = jsonLayer.value( QStringLiteral( "maxzoom" ), QStringLiteral( "-1" ) ).toInt();
148+
if ( maxZoom != -1 )
149+
maxZoom--;
140150

141151
const bool enabled = jsonLayer.value( QStringLiteral( "visibility" ) ).toString() != QLatin1String( "none" );
142152

‎tests/src/python/test_qgsmapboxglconverter.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,72 @@ def testLabelWithField(self):
945945
self.assertFalse(labeling_style.labelSettings().isExpression)
946946
self.assertEqual(labeling_style.labelSettings().fieldName, 'substance')
947947

948+
def test_parse_zoom_levels(self):
949+
context = QgsMapBoxGlStyleConversionContext()
950+
style = {
951+
"sources": {
952+
"Basemaps": {
953+
"type": "vector",
954+
"url": "https://xxxxxx"
955+
}
956+
},
957+
"layers": [
958+
{
959+
"id": "water",
960+
"source": "streets",
961+
"source-layer": "water",
962+
"minzoom": 3,
963+
"maxzoom": 11,
964+
"type": "fill",
965+
"paint": {
966+
"fill-color": "#00ffff"
967+
}
968+
},
969+
{
970+
"layout": {
971+
"text-field": "{name_en}",
972+
"text-font": [
973+
"Open Sans Semibold",
974+
"Arial Unicode MS Bold"
975+
],
976+
"text-max-width": 8,
977+
"text-anchor": "top",
978+
"text-size": 11,
979+
"icon-size": 1
980+
},
981+
"type": "symbol",
982+
"id": "poi_label",
983+
"minzoom": 3,
984+
"maxzoom": 11,
985+
"paint": {
986+
"text-color": "#666",
987+
"text-halo-width": 1.5,
988+
"text-halo-color": "rgba(255,255,255,0.95)",
989+
"text-halo-blur": 1
990+
},
991+
"source-layer": "poi_label"
992+
}
993+
]
994+
}
995+
996+
converter = QgsMapBoxGlStyleConverter()
997+
converter.convert(style, context)
998+
999+
renderer = converter.renderer()
1000+
style = renderer.style(0)
1001+
self.assertEqual(style.minZoomLevel(), 3)
1002+
# This differs from the handling of the max zoom as defined
1003+
# in the MapBox Style, since in MapBox styles the style is rendered
1004+
# only if the zoom level is less than the maximum zoom but in QGIS
1005+
# styles the style is rendered if the zoom level is less than OR EQUAL TO
1006+
# the maximum zoom
1007+
self.assertEqual(style.maxZoomLevel(), 10)
1008+
1009+
labeling = converter.labeling()
1010+
style = labeling.style(0)
1011+
self.assertEqual(style.minZoomLevel(), 3)
1012+
self.assertEqual(style.maxZoomLevel(), 10)
1013+
9481014
def test_parse_raster_source(self):
9491015
context = QgsMapBoxGlStyleConversionContext()
9501016
style = {

0 commit comments

Comments
 (0)
Please sign in to comment.