mapcomplete/Logic/State/MapState.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

134 lines
4.6 KiB
TypeScript
Raw Normal View History

2023-03-24 19:21:15 +01:00
import { Store, UIEventSource } from "../UIEventSource"
2023-03-25 02:48:24 +01:00
import FilteredLayer from "../../Models/FilteredLayer"
import TilesourceConfig from "../../Models/ThemeConfig/TilesourceConfig"
2022-12-16 13:45:07 +01:00
import { QueryParameters } from "../Web/QueryParameters"
import ShowOverlayLayer from "../../UI/ShowDataLayer/ShowOverlayLayer"
import { FeatureSource, FeatureSourceForLayer, Tiled } from "../FeatureSource/FeatureSource"
2023-03-24 19:21:15 +01:00
import StaticFeatureSource, {
TiledStaticFeatureSource,
} from "../FeatureSource/Sources/StaticFeatureSource"
import { Feature } from "geojson"
import { MapProperties } from "../../Models/MapProperties"
/**
* Contains all the leaflet-map related state
*/
2023-03-24 19:21:15 +01:00
export default class MapState {
/**
* Last location where a click was registered
*/
public readonly LastClickLocation: UIEventSource<{
lat: number
lon: number
}> = new UIEventSource<{ lat: number; lon: number }>(undefined)
2021-12-10 17:30:50 +01:00
/**
* The bounds of the current map view
*/
public currentView: FeatureSourceForLayer & Tiled
/**
* A builtin layer which contains the selected element.
* Loads 'selected_element.json'
* This _might_ contain multiple points, e.g. every center of a multipolygon
*/
public selectedElementsLayer: FeatureSourceForLayer & Tiled
/**
* Which overlays are shown
*/
public overlayToggles: { config: TilesourceConfig; isDisplayed: UIEventSource<boolean> }[]
2023-03-24 19:21:15 +01:00
constructor() {
this.availableBackgroundLayers = AvailableBaseLayers.AvailableLayersAt(this.locationControl)
let defaultLayer = AvailableBaseLayers.osmCarto
const available = this.availableBackgroundLayers.data
for (const layer of available) {
if (this.backgroundLayerId.data === layer.id) {
defaultLayer = layer
}
}
const self = this
this.backgroundLayer = new UIEventSource<BaseLayer>(defaultLayer)
this.backgroundLayer.addCallbackAndRunD((layer) => self.backgroundLayerId.setData(layer.id))
2022-01-08 22:11:24 +01:00
2022-02-22 14:13:41 +01:00
this.overlayToggles =
this.layoutToUse?.tileLayerSources
?.filter((c) => c.name !== undefined)
?.map((c) => ({
config: c,
isDisplayed: QueryParameters.GetBooleanQueryParameter(
"overlay-" + c.id,
c.defaultState,
"Wether or not the overlay " + c.id + " is shown"
2022-09-08 21:40:48 +02:00
),
})) ?? []
2021-10-15 14:52:11 +02:00
this.AddAllOverlaysToMap(this.leafletMap)
2021-12-10 15:51:08 +01:00
this.initCurrentView()
this.initSelectedElement()
}
2021-11-07 16:34:51 +01:00
public AddAllOverlaysToMap(leafletMap: UIEventSource<any>) {
const initialized = new Set()
for (const overlayToggle of this.overlayToggles) {
new ShowOverlayLayer(overlayToggle.config, leafletMap, overlayToggle.isDisplayed)
initialized.add(overlayToggle.config)
}
2022-02-22 14:13:41 +01:00
for (const tileLayerSource of this.layoutToUse?.tileLayerSources ?? []) {
2021-11-07 16:34:51 +01:00
if (initialized.has(tileLayerSource)) {
continue
}
new ShowOverlayLayer(tileLayerSource, leafletMap)
}
}
2023-03-25 02:48:24 +01:00
private static initCurrentView(mapproperties: MapProperties): FeatureSource {
2021-12-10 17:30:50 +01:00
let i = 0
2023-03-25 02:48:24 +01:00
const features: Store<Feature[]> = mapproperties.bounds.map((bounds) => {
if (bounds === undefined) {
return []
2021-12-10 15:51:08 +01:00
}
i++
2023-03-25 02:48:24 +01:00
return [
bounds.asGeoJson({
id: "current_view-" + i,
current_view: "yes",
2023-03-25 02:48:24 +01:00
zoom: "" + mapproperties.zoom.data,
}),
]
})
2022-01-08 22:11:24 +01:00
2023-03-25 02:48:24 +01:00
return new StaticFeatureSource(features)
2021-12-10 15:51:08 +01:00
}
2022-12-16 13:45:07 +01:00
private initSelectedElement() {
const layerDef: FilteredLayer = this.filteredLayers.data.filter(
(l) => l.layerDef.id === "selected_element"
)[0]
const empty = []
2022-12-16 13:45:07 +01:00
const store = this.selectedElement.map((feature) => {
if (feature === undefined || feature === null) {
return empty
}
2022-12-16 13:45:07 +01:00
return [
{
feature: {
type: "Feature",
properties: {
selected: "yes",
id: "selected" + feature.properties.id,
},
geometry: feature.geometry,
},
2022-12-16 13:45:07 +01:00
freshness: new Date(),
},
]
})
this.selectedElementsLayer = new TiledStaticFeatureSource(store, layerDef)
}
}