mapcomplete/UI/Map/OverlayMap.svelte

69 lines
2.2 KiB
Svelte

<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} />