forked from MapComplete/MapComplete
Fix #2024 (or at least: workaround). The main map will now automatically recover from contextLost-events
This commit is contained in:
parent
7d678d95c7
commit
7d0816219f
3 changed files with 35 additions and 4 deletions
|
@ -469,6 +469,9 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
public showCurrentLocationOn(map: Store<MlMap>): 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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -213,7 +213,7 @@
|
|||
|
||||
<main>
|
||||
<div class="absolute top-0 left-0 h-screen w-screen overflow-hidden">
|
||||
<MaplibreMap map={maplibremap} mapProperties={mapproperties} />
|
||||
<MaplibreMap map={maplibremap} mapProperties={mapproperties} autorecovery={true}/>
|
||||
</div>
|
||||
|
||||
{#if $visualFeedback}
|
||||
|
@ -286,9 +286,11 @@
|
|||
on:keydown={forwardEventToMap}
|
||||
htmlElem={openCurrentViewLayerButton}
|
||||
>
|
||||
<div class="w-8 h-8 cursor-pointer">
|
||||
<ToSvelte
|
||||
construct={() => currentViewLayer.defaultIcon().SetClass("w-8 h-8 cursor-pointer")}
|
||||
construct={() => currentViewLayer.defaultIcon()}
|
||||
/>
|
||||
</div>
|
||||
</MapControlButton>
|
||||
{/if}
|
||||
<ExtraLinkButton {state} />
|
||||
|
|
Loading…
Reference in a new issue