2021-10-15 05:20:02 +02:00
|
|
|
import UserRelatedState from "./UserRelatedState";
|
|
|
|
import {UIEventSource} from "../UIEventSource";
|
|
|
|
import BaseLayer from "../../Models/BaseLayer";
|
|
|
|
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
|
|
|
|
import AvailableBaseLayers from "../Actors/AvailableBaseLayers";
|
|
|
|
import Attribution from "../../UI/BigComponents/Attribution";
|
|
|
|
import Minimap, {MinimapObj} from "../../UI/Base/Minimap";
|
|
|
|
import {Tiles} from "../../Models/TileRange";
|
|
|
|
import BaseUIElement from "../../UI/BaseUIElement";
|
2022-01-08 04:22:50 +01:00
|
|
|
import FilteredLayer, {FilterState} from "../../Models/FilteredLayer";
|
2021-10-15 05:20:02 +02:00
|
|
|
import TilesourceConfig from "../../Models/ThemeConfig/TilesourceConfig";
|
|
|
|
import {QueryParameters} from "../Web/QueryParameters";
|
|
|
|
import ShowOverlayLayer from "../../UI/ShowDataLayer/ShowOverlayLayer";
|
2021-11-09 01:49:07 +01:00
|
|
|
import {FeatureSourceForLayer, Tiled} from "../FeatureSource/FeatureSource";
|
2021-11-08 02:36:01 +01:00
|
|
|
import SimpleFeatureSource from "../FeatureSource/Sources/SimpleFeatureSource";
|
2021-11-12 04:11:53 +01:00
|
|
|
import {LocalStorageSource} from "../Web/LocalStorageSource";
|
|
|
|
import {GeoOperations} from "../GeoOperations";
|
2021-12-21 18:35:31 +01:00
|
|
|
import TitleHandler from "../Actors/TitleHandler";
|
2022-02-01 04:14:54 +01:00
|
|
|
import {BBox} from "../BBox";
|
2022-02-14 18:18:05 +01:00
|
|
|
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
|
2021-10-15 05:20:02 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Contains all the leaflet-map related state
|
|
|
|
*/
|
|
|
|
export default class MapState extends UserRelatedState {
|
|
|
|
|
|
|
|
/**
|
|
|
|
The leaflet instance of the big basemap
|
|
|
|
*/
|
2021-10-15 14:52:11 +02:00
|
|
|
public leafletMap = new UIEventSource<any /*L.Map*/>(undefined, "leafletmap");
|
2021-10-15 05:20:02 +02:00
|
|
|
/**
|
|
|
|
* A list of currently available background layers
|
|
|
|
*/
|
|
|
|
public availableBackgroundLayers: UIEventSource<BaseLayer[]>;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The current background layer
|
|
|
|
*/
|
|
|
|
public backgroundLayer: UIEventSource<BaseLayer>;
|
|
|
|
/**
|
|
|
|
* 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;
|
2021-10-15 05:20:02 +02:00
|
|
|
/**
|
|
|
|
* The location as delivered by the GPS
|
|
|
|
*/
|
2021-11-08 02:36:01 +01:00
|
|
|
public currentUserLocation: FeatureSourceForLayer & Tiled;
|
2022-01-08 22:11:24 +01:00
|
|
|
|
2021-11-08 02:36:01 +01:00
|
|
|
/**
|
|
|
|
* All previously visited points
|
|
|
|
*/
|
|
|
|
public historicalUserLocations: FeatureSourceForLayer & Tiled;
|
2021-11-12 04:11:53 +01:00
|
|
|
/**
|
2021-11-14 16:57:14 +01:00
|
|
|
* The number of seconds that the GPS-locations are stored in memory.
|
|
|
|
* Time in seconds
|
2021-11-12 04:11:53 +01:00
|
|
|
*/
|
2021-11-12 18:39:38 +01:00
|
|
|
public gpsLocationHistoryRetentionTime = new UIEventSource(7 * 24 * 60 * 60, "gps_location_retention")
|
2021-11-12 04:11:53 +01:00
|
|
|
public historicalUserLocationsTrack: FeatureSourceForLayer & Tiled;
|
2021-11-08 02:36:01 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A feature source containing the current home location of the user
|
|
|
|
*/
|
|
|
|
public homeLocation: FeatureSourceForLayer & Tiled
|
2021-10-15 05:20:02 +02:00
|
|
|
|
|
|
|
public readonly mainMapObject: BaseUIElement & MinimapObj;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2022-02-01 04:14:54 +01:00
|
|
|
* Which layers are enabled in the current theme and what filters are applied onto them
|
2021-10-15 05:20:02 +02:00
|
|
|
*/
|
|
|
|
public filteredLayers: UIEventSource<FilteredLayer[]> = new UIEventSource<FilteredLayer[]>([], "filteredLayers");
|
|
|
|
/**
|
|
|
|
* Which overlays are shown
|
|
|
|
*/
|
|
|
|
public overlayToggles: { config: TilesourceConfig, isDisplayed: UIEventSource<boolean> }[]
|
|
|
|
|
2021-11-12 18:39:38 +01:00
|
|
|
|
2022-01-08 22:11:24 +01:00
|
|
|
constructor(layoutToUse: LayoutConfig, options?: { attemptLogin: true | boolean }) {
|
2021-12-13 02:05:34 +01:00
|
|
|
super(layoutToUse, options);
|
2021-10-15 05:20:02 +02:00
|
|
|
|
|
|
|
this.availableBackgroundLayers = AvailableBaseLayers.AvailableLayersAt(this.locationControl);
|
|
|
|
|
2021-11-21 02:44:35 +01:00
|
|
|
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
|
|
|
|
2021-10-15 05:20:02 +02:00
|
|
|
const attr = new Attribution(
|
|
|
|
this.locationControl,
|
|
|
|
this.osmConnection.userDetails,
|
|
|
|
this.layoutToUse,
|
|
|
|
this.currentBounds
|
|
|
|
);
|
|
|
|
|
|
|
|
// Will write into this.leafletMap
|
|
|
|
this.mainMapObject = Minimap.createMiniMap({
|
|
|
|
background: this.backgroundLayer,
|
|
|
|
location: this.locationControl,
|
|
|
|
leafletMap: this.leafletMap,
|
|
|
|
bounds: this.currentBounds,
|
|
|
|
attribution: attr,
|
|
|
|
lastClickLocation: this.LastClickLocation
|
|
|
|
})
|
|
|
|
|
2021-10-15 14:52:11 +02:00
|
|
|
|
2022-02-22 14:13:41 +01:00
|
|
|
this.overlayToggles = this.layoutToUse?.tileLayerSources
|
|
|
|
?.filter(c => c.name !== undefined)
|
|
|
|
?.map(c => ({
|
2021-10-15 05:20:02 +02:00
|
|
|
config: c,
|
2022-02-14 18:18:05 +01:00
|
|
|
isDisplayed: QueryParameters.GetBooleanQueryParameter("overlay-" + c.id, c.defaultState, "Wether or not the overlay " + c.id + " is shown")
|
2022-02-22 14:13:41 +01:00
|
|
|
})) ?? []
|
2021-10-15 05:20:02 +02:00
|
|
|
this.filteredLayers = this.InitializeFilteredLayers()
|
|
|
|
|
|
|
|
|
2021-10-15 14:52:11 +02:00
|
|
|
this.lockBounds()
|
|
|
|
this.AddAllOverlaysToMap(this.leafletMap)
|
2021-11-12 18:39:38 +01:00
|
|
|
|
2021-11-08 02:36:01 +01:00
|
|
|
this.initHomeLocation()
|
|
|
|
this.initGpsLocation()
|
2021-11-08 14:18:45 +01:00
|
|
|
this.initUserLocationTrail()
|
2021-12-10 15:51:08 +01:00
|
|
|
this.initCurrentView()
|
2021-12-21 18:35:31 +01:00
|
|
|
|
|
|
|
new TitleHandler(this);
|
2021-10-15 05:20:02 +02:00
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
}
|
2021-10-15 05:20:02 +02:00
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2021-10-15 05:20:02 +02:00
|
|
|
|
|
|
|
private lockBounds() {
|
|
|
|
const layout = this.layoutToUse;
|
2022-02-22 14:13:41 +01:00
|
|
|
if (!layout?.lockLocation) {
|
|
|
|
return;
|
2021-10-15 05:20:02 +02:00
|
|
|
}
|
2022-02-22 14:13:41 +01:00
|
|
|
console.warn("Locking the bounds to ", layout.lockLocation);
|
|
|
|
this.mainMapObject.installBounds(
|
|
|
|
new BBox(layout.lockLocation),
|
|
|
|
this.featureSwitchIsTesting.data
|
|
|
|
)
|
2021-10-15 05:20:02 +02:00
|
|
|
}
|
2022-01-08 22:11:24 +01:00
|
|
|
|
|
|
|
private initCurrentView() {
|
2021-12-10 17:30:50 +01:00
|
|
|
let currentViewLayer: FilteredLayer = this.filteredLayers.data.filter(l => l.layerDef.id === "current_view")[0]
|
|
|
|
|
2022-01-08 22:11:24 +01:00
|
|
|
if (currentViewLayer === undefined) {
|
2021-12-10 17:30:50 +01:00
|
|
|
// This layer is not needed by the theme and thus unloaded
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let i = 0
|
2021-12-12 02:59:24 +01:00
|
|
|
const self = this;
|
2022-01-08 22:11:24 +01:00
|
|
|
const features: UIEventSource<{ feature: any, freshness: Date }[]> = this.currentBounds.map(bounds => {
|
|
|
|
if (bounds === undefined) {
|
2021-12-10 17:30:50 +01:00
|
|
|
return []
|
|
|
|
}
|
|
|
|
i++
|
2021-12-10 15:51:08 +01:00
|
|
|
const feature = {
|
|
|
|
freshness: new Date(),
|
|
|
|
feature: {
|
2021-12-10 17:30:50 +01:00
|
|
|
type: "Feature",
|
2022-01-08 22:11:24 +01:00
|
|
|
properties: {
|
|
|
|
id: "current_view-" + i,
|
|
|
|
"current_view": "yes",
|
|
|
|
"zoom": "" + self.locationControl.data.zoom
|
2021-12-10 15:51:08 +01:00
|
|
|
},
|
2022-01-08 22:11:24 +01:00
|
|
|
geometry: {
|
|
|
|
type: "Polygon",
|
|
|
|
coordinates: [[
|
2021-12-10 15:51:08 +01:00
|
|
|
[bounds.maxLon, bounds.maxLat],
|
|
|
|
[bounds.minLon, bounds.maxLat],
|
|
|
|
[bounds.minLon, bounds.minLat],
|
|
|
|
[bounds.maxLon, bounds.minLat],
|
|
|
|
[bounds.maxLon, bounds.maxLat],
|
2021-12-10 17:30:50 +01:00
|
|
|
]]
|
2021-12-10 15:51:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return [feature]
|
|
|
|
})
|
2022-01-08 22:11:24 +01:00
|
|
|
|
|
|
|
this.currentView = new SimpleFeatureSource(currentViewLayer, 0, features)
|
2021-12-10 15:51:08 +01:00
|
|
|
}
|
2021-11-12 18:39:38 +01:00
|
|
|
|
|
|
|
private initGpsLocation() {
|
2021-11-08 02:36:01 +01:00
|
|
|
// Initialize the gps layer data. This is emtpy for now, the actual writing happens in the Geolocationhandler
|
|
|
|
let gpsLayerDef: FilteredLayer = this.filteredLayers.data.filter(l => l.layerDef.id === "gps_location")[0]
|
2022-01-26 21:40:38 +01:00
|
|
|
if (gpsLayerDef === undefined) {
|
2022-01-08 22:11:24 +01:00
|
|
|
return
|
|
|
|
}
|
2021-11-08 02:36:01 +01:00
|
|
|
this.currentUserLocation = new SimpleFeatureSource(gpsLayerDef, Tiles.tile_index(0, 0, 0));
|
|
|
|
}
|
2021-11-12 18:39:38 +01:00
|
|
|
|
|
|
|
private initUserLocationTrail() {
|
|
|
|
const features = LocalStorageSource.GetParsed<{ feature: any, freshness: Date }[]>("gps_location_history", [])
|
2021-11-12 04:11:53 +01:00
|
|
|
const now = new Date().getTime()
|
|
|
|
features.data = features.data
|
|
|
|
.map(ff => ({feature: ff.feature, freshness: new Date(ff.freshness)}))
|
2021-11-14 16:57:14 +01:00
|
|
|
.filter(ff => (now - ff.freshness.getTime()) < 1000 * this.gpsLocationHistoryRetentionTime.data)
|
2021-11-12 04:11:53 +01:00
|
|
|
features.ping()
|
|
|
|
const self = this;
|
2021-11-08 14:18:45 +01:00
|
|
|
let i = 0
|
2022-01-08 22:11:24 +01:00
|
|
|
this.currentUserLocation?.features?.addCallbackAndRunD(([location]) => {
|
2021-11-12 18:39:38 +01:00
|
|
|
if (location === undefined) {
|
2021-11-08 14:18:45 +01:00
|
|
|
return;
|
|
|
|
}
|
2021-11-12 18:39:38 +01:00
|
|
|
|
2021-11-12 04:11:53 +01:00
|
|
|
const previousLocation = features.data[features.data.length - 1]
|
2021-11-12 18:39:38 +01:00
|
|
|
if (previousLocation !== undefined) {
|
2021-11-12 04:11:53 +01:00
|
|
|
const d = GeoOperations.distanceBetween(
|
|
|
|
previousLocation.feature.geometry.coordinates,
|
|
|
|
location.feature.geometry.coordinates
|
|
|
|
)
|
2021-11-12 18:39:38 +01:00
|
|
|
let timeDiff = Number.MAX_VALUE // in seconds
|
|
|
|
const olderLocation = features.data[features.data.length - 2]
|
|
|
|
if (olderLocation !== undefined) {
|
2021-11-15 11:51:32 +01:00
|
|
|
timeDiff = (new Date(previousLocation.freshness).getTime() - new Date(olderLocation.freshness).getTime()) / 1000
|
2021-11-12 18:39:38 +01:00
|
|
|
}
|
|
|
|
if (d < 20 && timeDiff < 60) {
|
2021-11-12 04:11:53 +01:00
|
|
|
// Do not append changes less then 20m - it's probably noise anyway
|
|
|
|
return;
|
|
|
|
}
|
2021-11-08 14:18:45 +01:00
|
|
|
}
|
2021-11-12 18:39:38 +01:00
|
|
|
|
2021-11-12 04:11:53 +01:00
|
|
|
const feature = JSON.parse(JSON.stringify(location.feature))
|
2021-11-12 18:39:38 +01:00
|
|
|
feature.properties.id = "gps/" + features.data.length
|
2021-11-12 04:11:53 +01:00
|
|
|
i++
|
|
|
|
features.data.push({feature, freshness: new Date()})
|
2021-11-08 14:18:45 +01:00
|
|
|
features.ping()
|
|
|
|
})
|
2021-11-12 18:39:38 +01:00
|
|
|
|
|
|
|
|
2021-11-12 04:11:53 +01:00
|
|
|
let gpsLayerDef: FilteredLayer = this.filteredLayers.data.filter(l => l.layerDef.id === "gps_location_history")[0]
|
2022-01-26 21:40:38 +01:00
|
|
|
if (gpsLayerDef !== undefined) {
|
2022-01-08 22:11:24 +01:00
|
|
|
this.historicalUserLocations = new SimpleFeatureSource(gpsLayerDef, Tiles.tile_index(0, 0, 0), features);
|
2022-02-16 01:46:55 +01:00
|
|
|
this.changes.setHistoricalUserLocations(this.historicalUserLocations)
|
2022-01-08 22:11:24 +01:00
|
|
|
}
|
2021-11-12 04:11:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
const asLine = features.map(allPoints => {
|
2021-11-12 18:39:38 +01:00
|
|
|
if (allPoints === undefined || allPoints.length < 2) {
|
2021-11-12 04:11:53 +01:00
|
|
|
return []
|
|
|
|
}
|
|
|
|
|
|
|
|
const feature = {
|
|
|
|
type: "Feature",
|
2021-11-12 18:39:38 +01:00
|
|
|
properties: {
|
|
|
|
"id": "location_track",
|
2021-11-12 04:11:53 +01:00
|
|
|
"_date:now": new Date().toISOString(),
|
|
|
|
},
|
2021-11-12 18:39:38 +01:00
|
|
|
geometry: {
|
2021-11-12 04:11:53 +01:00
|
|
|
type: "LineString",
|
|
|
|
coordinates: allPoints.map(ff => ff.feature.geometry.coordinates)
|
|
|
|
}
|
|
|
|
}
|
2021-11-12 18:39:38 +01:00
|
|
|
|
2021-11-12 04:11:53 +01:00
|
|
|
self.allElements.ContainingFeatures.set(feature.properties.id, feature)
|
2021-11-12 18:39:38 +01:00
|
|
|
|
2021-11-12 04:11:53 +01:00
|
|
|
return [{
|
|
|
|
feature,
|
|
|
|
freshness: new Date()
|
|
|
|
}]
|
|
|
|
})
|
|
|
|
let gpsLineLayerDef: FilteredLayer = this.filteredLayers.data.filter(l => l.layerDef.id === "gps_track")[0]
|
2022-01-26 21:40:38 +01:00
|
|
|
if (gpsLineLayerDef !== undefined) {
|
2022-01-08 22:11:24 +01:00
|
|
|
this.historicalUserLocationsTrack = new SimpleFeatureSource(gpsLineLayerDef, Tiles.tile_index(0, 0, 0), asLine);
|
|
|
|
}
|
2021-11-08 14:18:45 +01:00
|
|
|
}
|
2021-11-08 02:36:01 +01:00
|
|
|
|
|
|
|
private initHomeLocation() {
|
|
|
|
const empty = []
|
|
|
|
const feature = UIEventSource.ListStabilized(this.osmConnection.userDetails.map(userDetails => {
|
|
|
|
|
|
|
|
if (userDetails === undefined) {
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
const home = userDetails.home;
|
|
|
|
if (home === undefined) {
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
return [home.lon, home.lat]
|
|
|
|
})).map(homeLonLat => {
|
|
|
|
if (homeLonLat === undefined) {
|
|
|
|
return empty
|
|
|
|
}
|
|
|
|
return [{
|
|
|
|
feature: {
|
|
|
|
"type": "Feature",
|
|
|
|
"properties": {
|
2021-11-12 18:39:38 +01:00
|
|
|
"id": "home",
|
2021-11-08 02:36:01 +01:00
|
|
|
"user:home": "yes",
|
|
|
|
"_lon": homeLonLat[0],
|
|
|
|
"_lat": homeLonLat[1]
|
|
|
|
},
|
|
|
|
"geometry": {
|
|
|
|
"type": "Point",
|
|
|
|
"coordinates": homeLonLat
|
|
|
|
}
|
|
|
|
}, freshness: new Date()
|
|
|
|
}]
|
|
|
|
})
|
|
|
|
|
|
|
|
const flayer = this.filteredLayers.data.filter(l => l.layerDef.id === "home_location")[0]
|
2022-01-08 22:11:24 +01:00
|
|
|
if (flayer !== undefined) {
|
|
|
|
this.homeLocation = new SimpleFeatureSource(flayer, Tiles.tile_index(0, 0, 0), feature)
|
|
|
|
}
|
2021-11-08 02:36:01 +01:00
|
|
|
|
|
|
|
}
|
2021-10-15 14:52:11 +02:00
|
|
|
|
2022-02-14 18:18:05 +01:00
|
|
|
private getPref(key: string, layer: LayerConfig): UIEventSource<boolean> {
|
|
|
|
const pref = this.osmConnection
|
|
|
|
.GetPreference(key)
|
|
|
|
.map(v => {
|
|
|
|
if(v === undefined){
|
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
return v === "true";
|
|
|
|
}, [], b => {
|
|
|
|
if(b === undefined){
|
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
return "" + b;
|
|
|
|
})
|
|
|
|
pref.setData(layer.shownByDefault)
|
|
|
|
return pref
|
|
|
|
}
|
|
|
|
|
2021-10-15 05:20:02 +02:00
|
|
|
private InitializeFilteredLayers() {
|
|
|
|
const layoutToUse = this.layoutToUse;
|
2022-02-22 14:13:41 +01:00
|
|
|
if(layoutToUse === undefined){
|
|
|
|
return new UIEventSource<FilteredLayer[]>([])
|
|
|
|
}
|
2021-10-15 05:20:02 +02:00
|
|
|
const flayers: FilteredLayer[] = [];
|
|
|
|
for (const layer of layoutToUse.layers) {
|
|
|
|
let isDisplayed: UIEventSource<boolean>
|
2022-02-14 18:18:05 +01:00
|
|
|
if (layer.syncSelection === "local") {
|
|
|
|
isDisplayed = LocalStorageSource.GetParsed(layoutToUse.id + "-layer-" + layer.id + "-enabled", layer.shownByDefault)
|
|
|
|
} else if (layer.syncSelection === "theme-only") {
|
|
|
|
isDisplayed = this.getPref(layoutToUse.id+ "-layer-" + layer.id + "-enabled", layer)
|
|
|
|
} else if (layer.syncSelection === "global") {
|
|
|
|
isDisplayed = this.getPref("layer-" + layer.id + "-enabled", layer)
|
2021-10-15 05:20:02 +02:00
|
|
|
} else {
|
2022-02-16 00:21:03 +01:00
|
|
|
isDisplayed = QueryParameters.GetBooleanQueryParameter("layer-" + layer.id, layer.shownByDefault, "Wether or not layer "+layer.id+" is shown")
|
2021-10-15 05:20:02 +02:00
|
|
|
}
|
2022-02-14 18:18:05 +01:00
|
|
|
|
|
|
|
|
2022-01-08 22:11:24 +01:00
|
|
|
const flayer: FilteredLayer = {
|
2021-10-15 05:20:02 +02:00
|
|
|
isDisplayed: isDisplayed,
|
|
|
|
layerDef: layer,
|
2022-01-08 22:11:24 +01:00
|
|
|
appliedFilters: new UIEventSource<Map<string, FilterState>>(new Map<string, FilterState>())
|
2021-10-15 05:20:02 +02:00
|
|
|
};
|
2022-01-08 04:22:50 +01:00
|
|
|
layer.filters.forEach(filterConfig => {
|
|
|
|
const stateSrc = filterConfig.initState()
|
2022-01-08 22:11:24 +01:00
|
|
|
|
|
|
|
stateSrc.addCallbackAndRun(state => flayer.appliedFilters.data.set(filterConfig.id, state))
|
2022-01-08 04:22:50 +01:00
|
|
|
flayer.appliedFilters.map(dict => dict.get(filterConfig.id))
|
|
|
|
.addCallback(state => stateSrc.setData(state))
|
|
|
|
})
|
2021-10-15 05:20:02 +02:00
|
|
|
|
|
|
|
flayers.push(flayer);
|
|
|
|
}
|
2022-02-01 04:14:54 +01:00
|
|
|
|
|
|
|
for (const layer of layoutToUse.layers) {
|
2022-02-14 18:18:05 +01:00
|
|
|
if (layer.filterIsSameAs === undefined) {
|
2022-02-01 04:14:54 +01:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
const toReuse = flayers.find(l => l.layerDef.id === layer.filterIsSameAs)
|
2022-02-14 18:18:05 +01:00
|
|
|
if (toReuse === undefined) {
|
|
|
|
throw "Error in layer " + layer.id + ": it defines that it should be use the filters of " + layer.filterIsSameAs + ", but this layer was not loaded"
|
2022-02-01 04:14:54 +01:00
|
|
|
}
|
2022-02-14 18:18:05 +01:00
|
|
|
console.warn("Linking filter and isDisplayed-states of " + layer.id + " and " + layer.filterIsSameAs)
|
2022-02-01 04:14:54 +01:00
|
|
|
const selfLayer = flayers.findIndex(l => l.layerDef.id === layer.id)
|
|
|
|
flayers[selfLayer] = {
|
|
|
|
isDisplayed: toReuse.isDisplayed,
|
|
|
|
layerDef: layer,
|
|
|
|
appliedFilters: toReuse.appliedFilters
|
|
|
|
};
|
|
|
|
}
|
2022-02-14 18:18:05 +01:00
|
|
|
|
2021-10-15 05:20:02 +02:00
|
|
|
return new UIEventSource<FilteredLayer[]>(flayers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|