Fix overlay layers

This commit is contained in:
Pieter Vander Vennet 2023-04-21 01:53:24 +02:00
parent 3aeedf22c8
commit 24f7610d0a
15 changed files with 216 additions and 184 deletions

View file

@ -1,6 +1,6 @@
import { Store, UIEventSource } from "../../Logic/UIEventSource"
import type { Map as MLMap } from "maplibre-gl"
import { Map as MlMap } from "maplibre-gl"
import { Map as MlMap, SourceSpecification } from "maplibre-gl"
import { RasterLayerPolygon, RasterLayerProperties } from "../../Models/RasterLayers"
import { Utils } from "../../Utils"
import { BBox } from "../../Logic/BBox"
@ -37,6 +37,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
readonly allowZooming: UIEventSource<true | boolean | undefined>
readonly lastClickLocation: Store<undefined | { lon: number; lat: number }>
readonly minzoom: UIEventSource<number>
readonly maxzoom: UIEventSource<number>
private readonly _maplibreMap: Store<MLMap>
/**
* Used for internal bookkeeping (to remove a rasterLayer when done loading)
@ -50,12 +51,14 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
this.location = state?.location ?? new UIEventSource({ lon: 0, lat: 0 })
this.zoom = state?.zoom ?? new UIEventSource(1)
this.minzoom = state?.minzoom ?? new UIEventSource(0)
this.maxzoom = state?.maxzoom ?? new UIEventSource(24)
this.zoom.addCallbackAndRunD((z) => {
if (z < this.minzoom.data) {
this.zoom.setData(this.minzoom.data)
}
if (z > 24) {
this.zoom.setData(24)
const max = Math.min(24, this.maxzoom.data ?? 24)
if (z > max) {
this.zoom.setData(max)
}
})
this.maxbounds = state?.maxbounds ?? new UIEventSource(undefined)
@ -90,6 +93,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
self.setAllowMoving(self.allowMoving.data)
self.setAllowZooming(self.allowZooming.data)
self.setMinzoom(self.minzoom.data)
self.setMaxzoom(self.maxzoom.data)
self.setBounds(self.bounds.data)
})
self.MoveMapToCurrentLoc(self.location.data)
@ -98,6 +102,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
self.setAllowMoving(self.allowMoving.data)
self.setAllowZooming(self.allowZooming.data)
self.setMinzoom(self.minzoom.data)
self.setMaxzoom(self.maxzoom.data)
self.setBounds(self.bounds.data)
this.updateStores()
map.on("moveend", () => this.updateStores())
@ -146,10 +151,23 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
}
}
public static prepareWmsSource(layer: RasterLayerProperties): SourceSpecification {
return {
type: "raster",
// use the tiles option to specify a 256WMS tile source URL
// https://maplibre.org/maplibre-gl-js-docs/style-spec/sources/
tiles: [MapLibreAdaptor.prepareWmsURL(layer.url, layer["tile-size"] ?? 256)],
tileSize: layer["tile-size"] ?? 256,
minzoom: layer["min_zoom"] ?? 1,
maxzoom: layer["max_zoom"] ?? 25,
// scheme: background["type"] === "tms" ? "tms" : "xyz",
}
}
/**
* Prepares an ELI-URL to be compatible with mapbox
*/
private static prepareWmsURL(url: string, size: number = 256) {
private static prepareWmsURL(url: string, size: number = 256): string {
// ELI: LAYERS=OGWRGB13_15VL&STYLES=&FORMAT=image/jpeg&CRS={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}&VERSION=1.3.0&SERVICE=WMS&REQUEST=GetMap
// PROD: SERVICE=WMS&REQUEST=GetMap&LAYERS=OGWRGB13_15VL&STYLES=&FORMAT=image/jpeg&TRANSPARENT=false&VERSION=1.3.0&WIDTH=256&HEIGHT=256&CRS=EPSG:3857&BBOX=488585.4847988467,6590094.830634755,489196.9810251281,6590706.32686104
@ -342,16 +360,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
return
}
map.addSource(background.id, {
type: "raster",
// use the tiles option to specify a 256WMS tile source URL
// https://maplibre.org/maplibre-gl-js-docs/style-spec/sources/
tiles: [MapLibreAdaptor.prepareWmsURL(background.url, background["tile-size"] ?? 256)],
tileSize: background["tile-size"] ?? 256,
minzoom: background["min_zoom"] ?? 1,
maxzoom: background["max_zoom"] ?? 25,
// scheme: background["type"] === "tms" ? "tms" : "xyz",
})
map.addSource(background.id, MapLibreAdaptor.prepareWmsSource(background))
map.addLayer(
{
@ -405,6 +414,14 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
map.setMinZoom(minzoom)
}
private setMaxzoom(maxzoom: number) {
const map = this._maplibreMap.data
if (map === undefined) {
return
}
map.setMaxZoom(maxzoom)
}
private setAllowZooming(allow: true | boolean | undefined) {
const map = this._maplibreMap.data
if (map === undefined) {

View file

@ -0,0 +1,92 @@
import { RasterLayerProperties } from "../../Models/RasterLayers"
import { Store, UIEventSource } from "../../Logic/UIEventSource"
import { Map as MlMap } from "maplibre-gl"
import { Utils } from "../../Utils"
import { MapLibreAdaptor } from "./MapLibreAdaptor"
export default class ShowOverlayRasterLayer {
private readonly _map: UIEventSource<MlMap>
private readonly _layer: RasterLayerProperties
private readonly _mapProperties?: { zoom: Store<number> }
private _mllayer
private readonly _isDisplayed?: Store<boolean>
constructor(
layer: RasterLayerProperties,
map: UIEventSource<MlMap>,
mapProperties?: { zoom: Store<number> },
options?: {
isDisplayed?: Store<boolean>
}
) {
this._mapProperties = mapProperties
this._layer = layer
this._map = map
this._isDisplayed = options?.isDisplayed
const self = this
map.addCallbackAndRunD((map) => {
self.addLayer()
map.on("load", () => {
self.addLayer()
})
})
this.addLayer()
options?.isDisplayed?.addCallbackAndRun(() => {
self.setVisibility()
})
mapProperties?.zoom?.addCallbackAndRun(() => {
self.setVisibility()
})
}
private setVisibility() {
let zoom = this._mapProperties?.zoom?.data
let withinRange = zoom === undefined || zoom > this._layer.min_zoom
let isDisplayed = (this._isDisplayed?.data ?? true) && withinRange
this._map.data?.setLayoutProperty(
this._layer.id,
"visibility",
isDisplayed ? "visible" : "none"
)
}
private async awaitStyleIsLoaded(): Promise<void> {
const map = this._map.data
if (map === undefined) {
return
}
while (!map?.isStyleLoaded()) {
await Utils.waitFor(250)
}
}
private async addLayer() {
const map = this._map.data
console.log("Attempting to add ", this._layer.id)
if (map === undefined) {
return
}
await this.awaitStyleIsLoaded()
if (this._mllayer) {
// Already initialized
return
}
const background: RasterLayerProperties = this._layer
map.addSource(background.id, MapLibreAdaptor.prepareWmsSource(background))
this._mllayer = map.addLayer({
id: background.id,
type: "raster",
source: background.id,
paint: {},
})
map.setLayoutProperty(
this._layer.id,
"visibility",
this._isDisplayed?.data ?? true ? "visible" : "none"
)
this.setVisibility()
}
}