From 215f41ea945a1f52926be1d7ac95ab7404a419b4 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Wed, 7 Jan 2026 01:10:26 +0100 Subject: [PATCH] Create raster tile equivalents to leaflets definitions --- app/assets/javascripts/maplibre/map.js | 2 +- app/assets/javascripts/maplibre/styles.js | 71 +++++++++++++++++------ config/layers.yml | 18 ++++++ 3 files changed, 72 insertions(+), 19 deletions(-) diff --git a/app/assets/javascripts/maplibre/map.js b/app/assets/javascripts/maplibre/map.js index 4b5713842..ceb5539b3 100644 --- a/app/assets/javascripts/maplibre/map.js +++ b/app/assets/javascripts/maplibre/map.js @@ -36,7 +36,7 @@ OSM.MapLibre.SecondaryMap = class extends OSM.MapLibre.Map { const defaultHomeZoom = 11; super({ container: "map", - style: OSM.MapLibre.Styles.Mapnik, + style: OSM.MapLibre.Styles.Mapnik(), attributionControl: false, allowRotation: false, maxPitch: 0, diff --git a/app/assets/javascripts/maplibre/styles.js b/app/assets/javascripts/maplibre/styles.js index b938c7bb2..edf33ec9f 100644 --- a/app/assets/javascripts/maplibre/styles.js +++ b/app/assets/javascripts/maplibre/styles.js @@ -1,20 +1,55 @@ -OSM.MapLibre.Styles.Mapnik = { - version: 8, - sources: { - osm: { - type: "raster", - tiles: [ - "https://tile.openstreetmap.org/{z}/{x}/{y}.png" - ], - tileSize: 256, - maxzoom: 19 +(function () { + const convertIDUrlToMapLibreUrls = function (url) { + const tileUrl = url.replace("{zoom}", "{z}"); + + // {switch:a,b,c} for DNS server multiplexing + const switchRegex = /\{switch:([^}]+)}/; + const match = tileUrl.match(switchRegex); + if (!match) { + // No switch -> single tile URL + return [tileUrl]; } - }, - layers: [ - { - id: "osm", - type: "raster", - source: "osm" + + const subdomains = match[1].split(","); + return subdomains.map(subdomain => + tileUrl.replace(switchRegex, subdomain) + ); + }; + + const createRasterStyle = function (maxzoom, tileUrl) { + const tiles = convertIDUrlToMapLibreUrls(tileUrl); + return { + version: 8, + sources: { + raster: { + type: "raster", + tileSize: 256, + tiles, + maxzoom + } + }, + layers: [ + { + id: "raster", + type: "raster", + source: "raster" + } + ] + }; + }; + + // we register at OSM.MapLibre.Styles all the light and dark mode styles that exist in layers.yml + for (const layerDefinition of OSM.LAYER_DEFINITIONS) { + if (layerDefinition.isVectorStyle) { + OSM.MapLibre.Styles[layerDefinition.leafletOsmId] = (options) => layerDefinition.styleUrl.replace("{apikey}", options?.apikey); + if (layerDefinition.leafletOsmDarkId) { + OSM.MapLibre.Styles[layerDefinition.leafletOsmDarkId] = (options) => layerDefinition.styleUrlDark.replace("{apikey}", options?.apikey); + } + } else { + OSM.MapLibre.Styles[layerDefinition.leafletOsmId] = (options) => createRasterStyle(layerDefinition.maxZoom, layerDefinition.tileUrl.replace("{apikey}", options?.apikey)); + if (layerDefinition.leafletOsmDarkId) { + OSM.MapLibre.Styles[layerDefinition.leafletOsmDarkId] = (options) => createRasterStyle(layerDefinition.maxZoom, layerDefinition.tileUrlDark.replace("{apikey}", options?.apikey)); + } } - ] -}; + } +}()); diff --git a/config/layers.yml b/config/layers.yml index 4f73e2b81..101b88836 100644 --- a/config/layers.yml +++ b/config/layers.yml @@ -5,6 +5,8 @@ wiki: "https://wiki.openstreetmap.org/wiki/OpenStreetMap_Carto" canEmbed: true canDownloadImage: true + maxZoom: 19 + tileUrl: "https://tile.openstreetmap.org/{zoom}/{x}/{y}.png" credit: id: "make_a_donation" href: "https://supporting.openstreetmap.org" @@ -16,6 +18,8 @@ nameId: "cyclosm" wiki: "https://wiki.openstreetmap.org/wiki/CyclOSM" canEmbed: true + maxZoom: 20 + tileUrl: "https://{switch:a,b,c}.tile-cyclosm.openstreetmap.fr/cyclosm/{zoom}/{x}/{y}.png" credit: id: "cyclosm_credit" children: @@ -34,6 +38,8 @@ apiKeyId: "thunderforest_key" canEmbed: true canDownloadImage: true + maxZoom: 21 + tileUrl: "https://{switch:a,b,c}.tile.thunderforest.com/cycle/{zoom}/{x}/{y}.png?apikey={apikey}" credit: id: "thunderforest_credit" children: @@ -50,6 +56,9 @@ apiKeyId: "thunderforest_key" canEmbed: true canDownloadImage: true + maxZoom: 21 + tileUrl: "https://{switch:a,b,c}.tile.thunderforest.com/transport/{zoom}/{x}/{y}.png?apikey={apikey}" + tileUrlDark: "https://{switch:a,b,c}.tile.thunderforest.com/transport-dark/{zoom}/{x}/{y}.png?apikey={apikey}" credit: id: "thunderforest_credit" children: @@ -63,6 +72,8 @@ nameId: "tracestracktop_topo" wiki: "https://wiki.openstreetmap.org/wiki/Tracestrack" apiKeyId: "tracestrack_key" + maxZoom: 19 + tileUrl: "https://tile.tracestrack.com/topo__/{zoom}/{x}/{y}.webp?key={apikey}" credit: id: "tracestrack_credit" children: @@ -76,6 +87,8 @@ nameId: "hot" wiki: "https://wiki.openstreetmap.org/wiki/Humanitarian" canEmbed: true + maxZoom: 20 + tileUrl: "https://tile-{switch:a,b,c}.openstreetmap.fr/hot/{zoom}/{x}/{y}.png" credit: id: "hotosm_credit" children: @@ -93,6 +106,9 @@ nameId: "shortbread" wiki: "https://wiki.openstreetmap.org/wiki/Shortbread" maxZoom: 23 + isVectorStyle: true + styleUrl: "https://vector.openstreetmap.org/styles/shortbread/colorful.json" + styleUrlDark: "https://vector.openstreetmap.org/styles/shortbread/eclipse.json" credit: id: "make_a_donation" href: "https://supporting.openstreetmap.org" @@ -105,6 +121,8 @@ wiki: "https://wiki.openstreetmap.org/wiki/MapTiler" apiKeyId: "maptiler_key" maxZoom: 23 + isVectorStyle: true + styleUrl: "https://api.maptiler.com/maps/openstreetmap/style.json?key={apikey}" credit: id: "openmaptiles_credit" children: -- 2.39.5