<script lang="ts"> /** * The overlay map is a bit a weird map: * it is a HTML-component which is intended to be placed _over_ another map. * It will align itself in order to seamlessly show the same location; but possibly in a different style */ import MaplibreMap from "./MaplibreMap.svelte"; import {Store, UIEventSource} from "../../Logic/UIEventSource"; import {Map as MlMap} from "maplibre-gl"; import {MapLibreAdaptor} from "./MapLibreAdaptor"; import type {MapProperties} from "../../Models/MapProperties"; import {onDestroy} from "svelte"; import type {RasterLayerPolygon} from "../../Models/RasterLayers"; export let placedOverMapProperties: MapProperties export let placedOverMap: UIEventSource<MlMap> export let rasterLayer: UIEventSource<RasterLayerPolygon> export let visible: Store<boolean> = undefined let altmap: UIEventSource<MlMap> = new UIEventSource(undefined) let altproperties = new MapLibreAdaptor(altmap, { rasterLayer, zoom: UIEventSource.feedFrom(placedOverMapProperties.zoom) }) altproperties.allowMoving.setData(false) altproperties.allowZooming.setData(false) function pixelCenterOf(map: UIEventSource<MlMap>): [number, number] { const rect = map?.data?.getCanvas()?.getBoundingClientRect() if (!rect) { return undefined } const x = (rect.left + rect.right) / 2 const y = (rect.top + rect.bottom) / 2 return [x, y] } function updateLocation() { if (!placedOverMap.data || !altmap.data) { return } altmap.data.resize() const {lon, lat} = placedOverMapProperties.location.data const altMapCenter = pixelCenterOf(altmap) const c = placedOverMap.data.unproject(altMapCenter) altproperties.location.setData({lon: c.lng, lat: c.lat}) } onDestroy(placedOverMapProperties.location.addCallbackAndRunD(updateLocation)) updateLocation() window.setTimeout(updateLocation, 150) window.setTimeout(updateLocation, 500) if (visible) { onDestroy(visible?.addCallbackAndRunD(v => { if (!v) { return } updateLocation() window.setTimeout(updateLocation, 150) window.setTimeout(updateLocation, 500) })) } </script> <MaplibreMap map={altmap}/>