Chore: refactoring

This commit is contained in:
Pieter Vander Vennet 2025-02-07 01:09:17 +01:00
parent 12869321fd
commit f1f8b75964
2 changed files with 64 additions and 85 deletions

View file

@ -25,13 +25,13 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
"dragRotate", "dragRotate",
"dragPan", "dragPan",
"keyboard", "keyboard",
"touchZoomRotate", "touchZoomRotate"
] ]
private static maplibre_zoom_handlers = [ private static maplibre_zoom_handlers = [
"scrollZoom", "scrollZoom",
"boxZoom", "boxZoom",
"doubleClickZoom", "doubleClickZoom",
"touchZoomRotate", "touchZoomRotate"
] ]
readonly location: UIEventSource<{ lon: number; lat: number }> readonly location: UIEventSource<{ lon: number; lat: number }>
private readonly isFlying = new UIEventSource(false) private readonly isFlying = new UIEventSource(false)
@ -45,14 +45,14 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
readonly lastClickLocation: Store< readonly lastClickLocation: Store<
| undefined | undefined
| { | {
lon: number lon: number
lat: number lat: number
mode: "left" | "right" | "middle" mode: "left" | "right" | "middle"
/** /**
* The nearest feature from a MapComplete layer * The nearest feature from a MapComplete layer
*/ */
nearestFeature?: Feature nearestFeature?: Feature
} }
> >
readonly minzoom: UIEventSource<number> readonly minzoom: UIEventSource<number>
readonly maxzoom: UIEventSource<number> readonly maxzoom: UIEventSource<number>
@ -143,7 +143,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
const features = map const features = map
.queryRenderedFeatures([ .queryRenderedFeatures([
[point.x - buffer, point.y - buffer], [point.x - buffer, point.y - buffer],
[point.x + buffer, point.y + buffer], [point.x + buffer, point.y + buffer]
]) ])
.filter((f) => f.source.startsWith("mapcomplete_")) .filter((f) => f.source.startsWith("mapcomplete_"))
if (features.length === 1) { if (features.length === 1) {
@ -172,38 +172,28 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
lastClickLocation.setData({ lon, lat, mode, nearestFeature }) lastClickLocation.setData({ lon, lat, mode, nearestFeature })
} }
const syncStores = () => {
this.MoveMapToCurrentLoc(this.location.data)
this.SetZoom(this.zoom.data)
this.setMaxBounds(this.maxbounds.data)
this.setAllowMoving(this.allowMoving.data)
this.setAllowRotating(this.allowRotating.data)
this.setAllowZooming(this.allowZooming.data)
this.setMinzoom(this.minzoom.data)
this.setMaxzoom(this.maxzoom.data)
this.setBounds(this.bounds.data)
this.SetRotation(this.rotation.data)
this.setScale(this.showScale.data)
this.setTerrain(this.useTerrain.data)
this.updateStores(true)
}
maplibreMap.addCallbackAndRunD((map) => { maplibreMap.addCallbackAndRunD((map) => {
map.on("load", () => { map.on("load", () => {
console.log("Setting projection") syncStores()
map.setProjection({
type: "globe" // Set projection to globe
})
self.MoveMapToCurrentLoc(self.location.data)
self.SetZoom(self.zoom.data)
self.setMaxBounds(self.maxbounds.data)
self.setAllowMoving(self.allowMoving.data)
self.setAllowRotating(self.allowRotating.data)
self.setAllowZooming(self.allowZooming.data)
self.setMinzoom(self.minzoom.data)
self.setMaxzoom(self.maxzoom.data)
self.setBounds(self.bounds.data)
self.setTerrain(self.useTerrain.data)
self.setScale(self.showScale.data)
this.updateStores(true)
}) })
self.MoveMapToCurrentLoc(self.location.data) syncStores()
self.SetZoom(self.zoom.data)
self.setMaxBounds(self.maxbounds.data)
self.setAllowMoving(self.allowMoving.data)
self.setAllowRotating(self.allowRotating.data)
self.setAllowZooming(self.allowZooming.data)
self.setMinzoom(self.minzoom.data)
self.setMaxzoom(self.maxzoom.data)
self.setBounds(self.bounds.data)
self.SetRotation(self.rotation.data)
self.setTerrain(self.useTerrain.data)
self.setScale(self.showScale.data)
this.updateStores(true)
map.on("movestart", () => { map.on("movestart", () => {
this.isFlying.setData(true) this.isFlying.setData(true)
}) })
@ -224,9 +214,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
map.on("dblclick", (e) => { map.on("dblclick", (e) => {
handleClick(e, "left") handleClick(e, "left")
}) })
map.on("touchend", (e) => {
const touchEvent = e.originalEvent
})
map.on("rotateend", (_) => { map.on("rotateend", (_) => {
this.updateStores() this.updateStores()
}) })
@ -265,22 +253,22 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
}) })
this.location.addCallbackAndRunD((loc) => { this.location.addCallbackAndRunD((loc) => {
self.MoveMapToCurrentLoc(loc) this.MoveMapToCurrentLoc(loc)
}) })
this.zoom.addCallbackAndRunD((z) => self.SetZoom(z)) this.zoom.addCallbackAndRunD((z) => this.SetZoom(z))
this.maxbounds.addCallbackAndRun((bbox) => self.setMaxBounds(bbox)) this.maxbounds.addCallbackAndRun((bbox) => this.setMaxBounds(bbox))
this.rotation.addCallbackAndRunD((bearing) => self.SetRotation(bearing)) this.rotation.addCallbackAndRunD((bearing) => this.SetRotation(bearing))
this.allowMoving.addCallbackAndRun((allowMoving) => { this.allowMoving.addCallbackAndRun((allowMoving) => {
self.setAllowMoving(allowMoving) this.setAllowMoving(allowMoving)
self.pingKeycodeEvent(allowMoving ? "unlocked" : "locked") this.pingKeycodeEvent(allowMoving ? "unlocked" : "locked")
}) })
this.allowRotating.addCallbackAndRunD((allowRotating) => this.allowRotating.addCallbackAndRunD((allowRotating) =>
self.setAllowRotating(allowRotating) this.setAllowRotating(allowRotating)
) )
this.allowZooming.addCallbackAndRun((allowZooming) => self.setAllowZooming(allowZooming)) this.allowZooming.addCallbackAndRun((allowZooming) => this.setAllowZooming(allowZooming))
this.bounds.addCallbackAndRunD((bounds) => self.setBounds(bounds)) this.bounds.addCallbackAndRunD((bounds) => this.setBounds(bounds))
this.useTerrain?.addCallbackAndRun((useTerrain) => self.setTerrain(useTerrain)) this.useTerrain?.addCallbackAndRun((useTerrain) => this.setTerrain(useTerrain))
this.showScale?.addCallbackAndRun((showScale) => self.setScale(showScale)) this.showScale?.addCallbackAndRun((showScale) => this.setScale(showScale))
} }
/** /**
@ -295,9 +283,9 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
return { return {
map: mlmap, map: mlmap,
ui: new SvelteUIElement(MaplibreMap, { ui: new SvelteUIElement(MaplibreMap, {
map: mlmap, map: mlmap
}), }),
mapproperties: new MapLibreAdaptor(mlmap), mapproperties: new MapLibreAdaptor(mlmap)
} }
} }
@ -365,7 +353,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
) { ) {
const event = { const event = {
date: new Date(), date: new Date(),
key: key, key: key
} }
for (let i = 0; i < this._onKeyNavigation.length; i++) { for (let i = 0; i < this._onKeyNavigation.length; i++) {
@ -434,7 +422,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
element.style.transform = "" element.style.transform = ""
const offset = style.match(/translate\(([-0-9]+)%, ?([-0-9]+)%\)/) const offset = style.match(/translate\(([-0-9]+)%, ?([-0-9]+)%\)/)
let labels = <HTMLElement[]>Array.from(element.getElementsByClassName("marker-label")) const labels = <HTMLElement[]>Array.from(element.getElementsByClassName("marker-label"))
const origLabelTransforms = labels.map((l) => l.style.transform) const origLabelTransforms = labels.map((l) => l.style.transform)
// We save the original width (`w`) and height (`h`) in order to restore them later on // We save the original width (`w`) and height (`h`) in order to restore them later on
const w = element.style.width const w = element.style.width
@ -554,7 +542,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
const bounds = map.getBounds() const bounds = map.getBounds()
const bbox = new BBox([ const bbox = new BBox([
[bounds.getEast(), bounds.getNorth()], [bounds.getEast(), bounds.getNorth()],
[bounds.getWest(), bounds.getSouth()], [bounds.getWest(), bounds.getSouth()]
]) ])
if (this.bounds.data === undefined || !isSetup) { if (this.bounds.data === undefined || !isSetup) {
this.bounds.setData(bbox) this.bounds.setData(bbox)
@ -748,14 +736,14 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
type: "raster-dem", type: "raster-dem",
url: url:
"https://api.maptiler.com/tiles/terrain-rgb/tiles.json?key=" + "https://api.maptiler.com/tiles/terrain-rgb/tiles.json?key=" +
Constants.maptilerApiKey, Constants.maptilerApiKey
}) })
try { try {
while (!map?.isStyleLoaded()) { while (!map?.isStyleLoaded()) {
await Utils.waitFor(250) await Utils.waitFor(250)
} }
map.setTerrain({ map.setTerrain({
source: id, source: id
}) })
} catch (e) { } catch (e) {
console.error(e) console.error(e)
@ -780,7 +768,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
if (this.scaleControl === undefined) { if (this.scaleControl === undefined) {
this.scaleControl = new ScaleControl({ this.scaleControl = new ScaleControl({
maxWidth: 100, maxWidth: 100,
unit: "metric", unit: "metric"
}) })
} }
if (!map.hasControl(this.scaleControl)) { if (!map.hasControl(this.scaleControl)) {
@ -793,7 +781,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
window.requestAnimationFrame(() => { window.requestAnimationFrame(() => {
this._maplibreMap.data?.flyTo({ this._maplibreMap.data?.flyTo({
zoom, zoom,
center: [lon, lat], center: [lon, lat]
}) })
}) })
} }

View file

@ -1,5 +1,5 @@
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource" import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
import type { AddLayerObject, Map as MlMap } from "maplibre-gl" import type { AddLayerObject, Alignment, Map as MlMap } from "maplibre-gl"
import { GeoJSONSource, Marker } from "maplibre-gl" import { GeoJSONSource, Marker } from "maplibre-gl"
import { ShowDataLayerOptions } from "./ShowDataLayerOptions" import { ShowDataLayerOptions } from "./ShowDataLayerOptions"
import { GeoOperations } from "../../Logic/GeoOperations" import { GeoOperations } from "../../Logic/GeoOperations"
@ -16,6 +16,7 @@ import PerLayerFeatureSourceSplitter from "../../Logic/FeatureSource/PerLayerFea
import FilteredLayer from "../../Models/FilteredLayer" import FilteredLayer from "../../Models/FilteredLayer"
import SimpleFeatureSource from "../../Logic/FeatureSource/Sources/SimpleFeatureSource" import SimpleFeatureSource from "../../Logic/FeatureSource/Sources/SimpleFeatureSource"
import { TagsFilter } from "../../Logic/Tags/TagsFilter" import { TagsFilter } from "../../Logic/Tags/TagsFilter"
import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson"
class PointRenderingLayer { class PointRenderingLayer {
private readonly _config: PointRenderingConfig private readonly _config: PointRenderingConfig
@ -47,19 +48,18 @@ class PointRenderingLayer {
this._fetchStore = fetchStore this._fetchStore = fetchStore
this._onClick = onClick this._onClick = onClick
this._selectedElement = selectedElement this._selectedElement = selectedElement
const self = this
if (!features?.features) { if (!features?.features) {
throw ( throw (
"Could not setup a PointRenderingLayer; features?.features is undefined/null. The layer is " + "Could not setup a PointRenderingLayer; features?.features is undefined/null. The layer is " +
layer.id layer.id
) )
} }
features.features?.addCallbackAndRunD((features) => self.updateFeatures(features)) features.features?.addCallbackAndRunD((features) => this.updateFeatures(features))
visibility?.addCallbackAndRunD((visible) => { visibility?.addCallbackAndRunD((visible) => {
if (visible === true && self._dirty) { if (visible === true && this._dirty) {
self.updateFeatures(features.features.data) this.updateFeatures(features.features.data)
} }
self.setVisibility(visible) this.setVisibility(visible)
}) })
selectedElement?.addCallbackAndRun((selected) => { selectedElement?.addCallbackAndRun((selected) => {
this._markedAsSelected.forEach((el) => el.classList.remove("selected")) this._markedAsSelected.forEach((el) => el.classList.remove("selected"))
@ -123,7 +123,7 @@ class PointRenderingLayer {
} }
const loc = GeoOperations.featureToCoordinateWithRenderingType( const loc = GeoOperations.featureToCoordinateWithRenderingType(
<any>feature, feature,
location location
) )
if (loc === undefined) { if (loc === undefined) {
@ -199,10 +199,10 @@ class PointRenderingLayer {
.addTo(this._map) .addTo(this._map)
store store
.map((tags) => this._config.pitchAlignment.GetRenderValue(tags).Subs(tags).txt) .map((tags) => this._config.pitchAlignment.GetRenderValue(tags).Subs(tags).txt)
.addCallbackAndRun((pitchAligment) => marker.setPitchAlignment(<any>pitchAligment)) .addCallbackAndRun((pitchAligment) => marker.setPitchAlignment(<Alignment>pitchAligment))
store store
.map((tags) => this._config.rotationAlignment.GetRenderValue(tags).Subs(tags).txt) .map((tags) => this._config.rotationAlignment.GetRenderValue(tags).Subs(tags).txt)
.addCallbackAndRun((pitchAligment) => marker.setRotationAlignment(<any>pitchAligment)) .addCallbackAndRun((pitchAligment) => marker.setRotationAlignment(<Alignment>pitchAligment))
if (feature.geometry.type === "Point") { if (feature.geometry.type === "Point") {
// When the tags get 'pinged', check that the location didn't change // When the tags get 'pinged', check that the location didn't change
@ -261,10 +261,9 @@ class LineRenderingLayer {
this._visibility = visibility this._visibility = visibility
this._fetchStore = fetchStore this._fetchStore = fetchStore
this._onClick = onClick this._onClick = onClick
const self = this features.features.addCallbackAndRunD(() => this.update(features.features))
features.features.addCallbackAndRunD(() => self.update(features.features))
map.on("styledata", () => self.update(features.features)) map.on("styledata", () => this.update(features.features))
} }
public destruct(): void { public destruct(): void {
@ -324,7 +323,7 @@ class LineRenderingLayer {
calculatedProps.fillColor = calculatedProps.fillColor ?? calculatedProps.color calculatedProps.fillColor = calculatedProps.fillColor ?? calculatedProps.color
for (const key of LineRenderingLayer.lineConfigKeysColor) { for (const key of LineRenderingLayer.lineConfigKeysColor) {
let v = <string>calculatedProps[key] const v = <string>calculatedProps[key]
if (v === undefined) { if (v === undefined) {
continue continue
} }
@ -353,14 +352,6 @@ class LineRenderingLayer {
// As such, we only now read the features from the featureSource and compare with the previously set data // As such, we only now read the features from the featureSource and compare with the previously set data
const features = featureSource.data const features = featureSource.data
const src = <GeoJSONSource>map.getSource(this._layername) const src = <GeoJSONSource>map.getSource(this._layername)
if (
src !== undefined &&
this.currentSourceData === features &&
src._data === <any>features
) {
// Already up to date
return
}
{ {
// Add source to the map or update the feature source // Add source to the map or update the feature source
if (src === undefined) { if (src === undefined) {
@ -516,7 +507,7 @@ class LineRenderingLayer {
} }
export default class ShowDataLayer { export default class ShowDataLayer {
public static rangeLayer = new LayerConfig(<any>range_layer, "ShowDataLayer.ts:range.json") public static rangeLayer = new LayerConfig(<LayerConfigJson>range_layer, "ShowDataLayer.ts:range.json")
private readonly _options: ShowDataLayerOptions & { private readonly _options: ShowDataLayerOptions & {
layer: LayerConfig layer: LayerConfig
drawMarkers?: true | boolean drawMarkers?: true | boolean