From 7237a8994e0a9805e1385de2d86c1bd17eb4bf4a Mon Sep 17 00:00:00 2001 From: lpernelle-woosmap Date: Thu, 30 Apr 2026 12:00:43 +0200 Subject: [PATCH 1/2] feat: replace ArcGIS satellite with OpenSnowMap ski runs in map-external-layer sample - Swap default third-party layer from ArcGIS satellite to OpenSnowMap ski runs - Default style set to Light Grey, view centered on Oz-en-Oisans - OpenWeather layers (temperature, precipitation) fly to a US view - Refactor: replace if/else chains with Record-based STYLE_PRESETS and LAYER_CONFIGS - Fix overlay stacking bug (clear before insertAt) - Fix opacity validation (handle NaN, dedupe parseFloat) - Split layer/opacity handlers so opacity changes no longer reset bounds - TypeScript cleanup: split combined declarations, String -> string, === Co-Authored-By: Claude Opus 4.7 (1M context) --- samples/map-external-layer/index.njk | 4 +- samples/map-external-layer/index.ts | 174 +++++++++++++++------------ 2 files changed, 100 insertions(+), 78 deletions(-) diff --git a/samples/map-external-layer/index.njk b/samples/map-external-layer/index.njk index 1af0e108..49e4f818 100644 --- a/samples/map-external-layer/index.njk +++ b/samples/map-external-layer/index.njk @@ -7,7 +7,7 @@ Woosmap Style @@ -15,7 +15,7 @@
Third party layer diff --git a/samples/map-external-layer/index.ts b/samples/map-external-layer/index.ts index ae902fe2..75e8cdd1 100644 --- a/samples/map-external-layer/index.ts +++ b/samples/map-external-layer/index.ts @@ -2,42 +2,25 @@ const openWeatherMapKey = "723abb7941260adc84c92a1f526bdabb"; // [START woosmap_map_external_layer] let map: woosmap.map.Map; -let styleSelect, layerSelect: HTMLSelectElement; +let styleSelect: HTMLSelectElement; +let layerSelect: HTMLSelectElement; let opacityInput: HTMLInputElement; -const centerLatLng: woosmap.map.LatLngLiteral = { - lat: 39.15253, - lng: -97.74332 +const centerLatLng: woosmap.map.LatLngLiteral = { + lat: 45.126643, + lng: 6.073999, }; function initMap() { map = new window.woosmap.map.Map( document.getElementById("map") as HTMLElement, { - zoom: 3, + zoom: 15.64, center: centerLatLng, - styles: [] + styles: STYLE_PRESETS.lightgrey, }, ); - const imageMapType = new woosmap.map.ImageMapType({ - url: "https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}.png", - tileSize: new woosmap.map.Size(256, 256), - maxZoom: 19 - }); - map.overlayMapTypes.insertAt(0, imageMapType); - - const onChangeHandler = () => { - if ( - parseFloat(opacityInput.value) > 1 || - parseFloat(opacityInput.value) < 0 - ) { - alert("Value should be between 0 and 1"); - return; - } - changeStyle(styleSelect.value) - changeLayer(layerSelect.value, parseFloat(opacityInput.value)) - }; styleSelect = document.getElementById( "woosmap-style-select", ) as HTMLSelectElement; @@ -47,63 +30,67 @@ function initMap() { opacityInput = document.getElementById( "opacity-value-input", ) as HTMLInputElement; - styleSelect.addEventListener("change", onChangeHandler); - layerSelect.addEventListener("change", onChangeHandler); - opacityInput.addEventListener("change", onChangeHandler); + + applyLayer(layerSelect.value, readOpacity()); + + styleSelect.addEventListener("change", onStyleChange); + layerSelect.addEventListener("change", onLayerChange); + opacityInput.addEventListener("change", onOpacityChange); } -function changeStyle(name: String) -{ - let styles; - if(name == "retro") - { - styles = retroStyles - } - else if(name == "lightgrey") - { - styles = lightgreyStyles - } - else if(name=="night") - { - styles = nightStyles - } - else{ - styles = [] - } - map = new window.woosmap.map.Map( - document.getElementById("map") as HTMLElement, - { - zoom: map.getZoom(), - center: map.getCenter(), - styles: styles - }, - ); +function readOpacity(): number { + const opacity = parseFloat(opacityInput.value); + if (isNaN(opacity) || opacity < 0 || opacity > 1) { + alert("Opacity should be between 0 and 1"); + return 1; + } + return opacity; } -function changeLayer(provider: string, opacity: number) -{ - let url - if(provider == "temperature") - { - url = `https://tile.openweathermap.org/map/temp_new/{z}/{x}/{y}?appid=${openWeatherMapKey}`; - - } - else if(provider == "precipitation") - { - url = `https://tile.openweathermap.org/map/precipitation_new/{z}/{x}/{y}?appid=${openWeatherMapKey}`; - } - else +function onStyleChange() { + applyStyle(styleSelect.value); + // Recreating the map wipes overlays — reapply the current layer. + applyLayer(layerSelect.value, readOpacity()); +} + +function onLayerChange() { + const view = LAYER_VIEWS[layerSelect.value]; + if (view) { + map.flyTo(view); + } + applyLayer(layerSelect.value, readOpacity()); +} + +function onOpacityChange() { + applyLayer(layerSelect.value, readOpacity()); +} + +function applyStyle(name: string) { + const styles = STYLE_PRESETS[name] ?? []; + map = new window.woosmap.map.Map( + document.getElementById("map") as HTMLElement, { - url = `https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}.png`; - } - const imageMapType = new woosmap.map.ImageMapType({ - url: url, - tileSize: new woosmap.map.Size(256, 256), - maxZoom: 19, - opacity: opacity, - name: "Layer" - }); - map.overlayMapTypes.insertAt(0, imageMapType); + zoom: map.getZoom(), + center: map.getCenter(), + styles, + }, + ); +} + +function applyLayer(provider: string, opacity: number) { + map.overlayMapTypes.clear(); + const config = LAYER_CONFIGS[provider]; + if (!config) { + return; + } + map.overlayMapTypes.insertAt( + 0, + new woosmap.map.ImageMapType({ + ...config, + tileSize: new woosmap.map.Size(256, 256), + opacity, + }), + ); } const nightStyles = [ @@ -390,6 +377,41 @@ const lightgreyStyles = [ }, ] +const STYLE_PRESETS: Record = { + retro: retroStyles, + lightgrey: lightgreyStyles, + night: nightStyles, +}; + +const LAYER_CONFIGS: Record = { + pistes: { + url: "https://tiles.opensnowmap.org/pistes/{z}/{x}/{y}.png", + name: "OpenSnowMap", + maxZoom: 19, + }, + temperature: { + url: `https://tile.openweathermap.org/map/temp_new/{z}/{x}/{y}?appid=${openWeatherMapKey}`, + name: "Temperature", + maxZoom: 19, + }, + precipitation: { + url: `https://tile.openweathermap.org/map/precipitation_new/{z}/{x}/{y}?appid=${openWeatherMapKey}`, + name: "Precipitation", + maxZoom: 19, + }, +}; + +const US_VIEW = { + center: { lat: 39.8283, lng: -98.5795 }, + zoom: 4, +}; + +const LAYER_VIEWS: Record = { + pistes: { center: { lat: 45.126643, lng: 6.073999 }, zoom: 15.64 }, + temperature: US_VIEW, + precipitation: US_VIEW, +}; + declare global { interface Window { initMap: () => void; From 6f581e2f9a515c052a3fabc0438b4128257e0cfe Mon Sep 17 00:00:00 2001 From: lpernelle-woosmap Date: Thu, 30 Apr 2026 12:09:49 +0200 Subject: [PATCH 2/2] feat: improve UI controls panel in map-external-layer sample MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add panel title and stack labels above selects (was cramped at 100px width) - Replace opacity number input with range slider + live percentage readout - Style selects and slider with consistent borders, focus state, accent color - Wrap controls in