diff --git a/src/Models/ThemeViewState.ts b/src/Models/ThemeViewState.ts index 2dcbfd23b..32b8b9745 100644 --- a/src/Models/ThemeViewState.ts +++ b/src/Models/ThemeViewState.ts @@ -469,6 +469,9 @@ export default class ThemeViewState implements SpecialVisualizationState { public showCurrentLocationOn(map: Store): ShowDataLayer { const id = "gps_location" const flayerGps = this.layerState.filteredLayers.get(id) + if(flayerGps === undefined){ + return + } const features = this.geolocation.currentUserLocation return new ShowDataLayer(map, { features, diff --git a/src/UI/Map/MaplibreMap.svelte b/src/UI/Map/MaplibreMap.svelte index 4174df43f..882398f51 100644 --- a/src/UI/Map/MaplibreMap.svelte +++ b/src/UI/Map/MaplibreMap.svelte @@ -22,11 +22,16 @@ export let mapProperties: MapProperties = undefined export let interactive: boolean = true + /** + * If many maps are shown (> ~15), Chromium will drop some because of "too Much WEBGL-contexts" (see issue #2024 or https://webglfundamentals.org/webgl/lessons/webgl-multiple-views.html) + * For important maps (e.g. the main map), we want to recover from this + */ + export let autorecovery: boolean = false let container: HTMLElement let _map: Map - onMount(() => { + function initMap() { const { lon, lat } = mapProperties?.location?.data ?? { lon: 0, lat: 0 } const rasterLayer: RasterLayerProperties = mapProperties?.rasterLayer?.data?.properties @@ -56,9 +61,25 @@ window.requestAnimationFrame(() => { _map.resize() }) + _map.on("load", function() { _map.resize() const canvas = _map.getCanvas() + canvas.addEventListener("webglcontextlost", (e) => { + console.warn("A MapLibreMap lost their context. Recovery is", autorecovery, e) + try{ + _map?.remove() + }catch (e) { + console.log("Could not remove map due to", e) + } + if(autorecovery){ + requestAnimationFrame(() => { + console.warn("Attempting map recovery") + _map = new maplibre.Map(options) + initMap() + }) + } + }) if (interactive) { ariaLabel(canvas, Translations.t.general.visualFeedback.navigation) canvas.role = "application" @@ -69,7 +90,12 @@ } }) map.set(_map) - }) + } + + + onMount(() => initMap()) + + onDestroy(async () => { await Utils.waitFor(100) requestAnimationFrame( diff --git a/src/UI/ThemeViewGUI.svelte b/src/UI/ThemeViewGUI.svelte index 70a32da8f..c709b20bd 100644 --- a/src/UI/ThemeViewGUI.svelte +++ b/src/UI/ThemeViewGUI.svelte @@ -213,7 +213,7 @@
- +
{#if $visualFeedback} @@ -286,9 +286,11 @@ on:keydown={forwardEventToMap} htmlElem={openCurrentViewLayerButton} > +
currentViewLayer.defaultIcon().SetClass("w-8 h-8 cursor-pointer")} + construct={() => currentViewLayer.defaultIcon()} /> +
{/if}