Skip to content

Commit 236cdaf

Browse files
nyalldawsongithub-actions[bot]
authored andcommittedApr 22, 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 222c65c commit 236cdaf

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
@@ -940,6 +940,72 @@ def testLabelWithField(self):
940940
self.assertFalse(labeling_style.labelSettings().isExpression)
941941
self.assertEqual(labeling_style.labelSettings().fieldName, 'substance')
942942

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

0 commit comments

Comments
 (0)
Please sign in to comment.