| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | import LayoutConfig from "./ThemeConfig/LayoutConfig" | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  | import { SpecialVisualizationState } from "../UI/SpecialVisualization" | 
					
						
							|  |  |  | import { Changes } from "../Logic/Osm/Changes" | 
					
						
							|  |  |  | import { ImmutableStore, Store, UIEventSource } from "../Logic/UIEventSource" | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |     FeatureSource, | 
					
						
							|  |  |  |     IndexedFeatureSource, | 
					
						
							|  |  |  |     WritableFeatureSource, | 
					
						
							|  |  |  | } from "../Logic/FeatureSource/FeatureSource" | 
					
						
							|  |  |  | import { OsmConnection } from "../Logic/Osm/OsmConnection" | 
					
						
							|  |  |  | import { ExportableMap, MapProperties } from "./MapProperties" | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | import LayerState from "../Logic/State/LayerState" | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  | import { Feature, Point, Polygon } from "geojson" | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | import FullNodeDatabaseSource from "../Logic/FeatureSource/TiledFeatureSource/FullNodeDatabaseSource" | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  | import { Map as MlMap } from "maplibre-gl" | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | import InitialMapPositioning from "../Logic/Actors/InitialMapPositioning" | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  | import { MapLibreAdaptor } from "../UI/Map/MapLibreAdaptor" | 
					
						
							|  |  |  | import { GeoLocationState } from "../Logic/State/GeoLocationState" | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | import FeatureSwitchState from "../Logic/State/FeatureSwitchState" | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  | import { QueryParameters } from "../Logic/Web/QueryParameters" | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | import UserRelatedState from "../Logic/State/UserRelatedState" | 
					
						
							|  |  |  | import LayerConfig from "./ThemeConfig/LayerConfig" | 
					
						
							|  |  |  | import GeoLocationHandler from "../Logic/Actors/GeoLocationHandler" | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  | import { AvailableRasterLayers, RasterLayerPolygon, RasterLayerUtils } from "./RasterLayers" | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | import LayoutSource from "../Logic/FeatureSource/Sources/LayoutSource" | 
					
						
							|  |  |  | import StaticFeatureSource from "../Logic/FeatureSource/Sources/StaticFeatureSource" | 
					
						
							|  |  |  | import FeaturePropertiesStore from "../Logic/FeatureSource/Actors/FeaturePropertiesStore" | 
					
						
							|  |  |  | import PerLayerFeatureSourceSplitter from "../Logic/FeatureSource/PerLayerFeatureSourceSplitter" | 
					
						
							|  |  |  | import FilteringFeatureSource from "../Logic/FeatureSource/Sources/FilteringFeatureSource" | 
					
						
							|  |  |  | import ShowDataLayer from "../UI/Map/ShowDataLayer" | 
					
						
							|  |  |  | import TitleHandler from "../Logic/Actors/TitleHandler" | 
					
						
							|  |  |  | import ChangeToElementsActor from "../Logic/Actors/ChangeToElementsActor" | 
					
						
							|  |  |  | import PendingChangesUploader from "../Logic/Actors/PendingChangesUploader" | 
					
						
							|  |  |  | import SelectedElementTagsUpdater from "../Logic/Actors/SelectedElementTagsUpdater" | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  | import { BBox } from "../Logic/BBox" | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | import Constants from "./Constants" | 
					
						
							|  |  |  | import Hotkeys from "../UI/Base/Hotkeys" | 
					
						
							|  |  |  | import Translations from "../UI/i18n/Translations" | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  | import { GeoIndexedStoreForLayer } from "../Logic/FeatureSource/Actors/GeoIndexedStore" | 
					
						
							|  |  |  | import { LastClickFeatureSource } from "../Logic/FeatureSource/Sources/LastClickFeatureSource" | 
					
						
							|  |  |  | import { MenuState } from "./MenuState" | 
					
						
							| 
									
										
										
										
											2023-04-14 17:53:08 +02:00
										 |  |  | import MetaTagging from "../Logic/MetaTagging" | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  | import ChangeGeometryApplicator from "../Logic/FeatureSource/Sources/ChangeGeometryApplicator" | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  | import { NewGeometryFromChangesFeatureSource } from "../Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource" | 
					
						
							| 
									
										
										
										
											2023-04-20 18:58:31 +02:00
										 |  |  | import OsmObjectDownloader from "../Logic/Osm/OsmObjectDownloader" | 
					
						
							| 
									
										
										
										
											2023-04-21 01:53:24 +02:00
										 |  |  | import ShowOverlayRasterLayer from "../UI/Map/ShowOverlayRasterLayer" | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  | import { Utils } from "../Utils" | 
					
						
							|  |  |  | import { EliCategory } from "./RasterLayerProperties" | 
					
						
							| 
									
										
										
										
											2023-04-21 17:37:50 +02:00
										 |  |  | import BackgroundLayerResetter from "../Logic/Actors/BackgroundLayerResetter" | 
					
						
							| 
									
										
										
										
											2023-04-21 20:50:38 +02:00
										 |  |  | import SaveFeatureSourceToLocalStorage from "../Logic/FeatureSource/Actors/SaveFeatureSourceToLocalStorage" | 
					
						
							| 
									
										
										
										
											2023-04-27 00:58:21 +02:00
										 |  |  | import BBoxFeatureSource from "../Logic/FeatureSource/Sources/TouchesBboxFeatureSource" | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  | import ThemeViewStateHashActor from "../Logic/Web/ThemeViewStateHashActor" | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  | import NoElementsInViewDetector, { | 
					
						
							|  |  |  |     FeatureViewState, | 
					
						
							|  |  |  | } from "../Logic/Actors/NoElementsInViewDetector" | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The themeviewState contains all the state needed for the themeViewGUI. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This is pretty much the 'brain' or the HQ of MapComplete | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * It ties up all the needed elements and starts some actors. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export default class ThemeViewState implements SpecialVisualizationState { | 
					
						
							|  |  |  |     readonly layout: LayoutConfig | 
					
						
							|  |  |  |     readonly map: UIEventSource<MlMap> | 
					
						
							|  |  |  |     readonly changes: Changes | 
					
						
							|  |  |  |     readonly featureSwitches: FeatureSwitchState | 
					
						
							|  |  |  |     readonly featureSwitchIsTesting: Store<boolean> | 
					
						
							|  |  |  |     readonly featureSwitchUserbadge: Store<boolean> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     readonly featureProperties: FeaturePropertiesStore | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     readonly osmConnection: OsmConnection | 
					
						
							|  |  |  |     readonly selectedElement: UIEventSource<Feature> | 
					
						
							| 
									
										
										
										
											2023-04-19 03:20:49 +02:00
										 |  |  |     readonly mapProperties: MapProperties & ExportableMap | 
					
						
							| 
									
										
										
										
											2023-04-20 03:58:31 +02:00
										 |  |  |     readonly osmObjectDownloader: OsmObjectDownloader | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |     readonly dataIsLoading: Store<boolean> | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Indicates if there is _some_ data in view, even if it is not shown due to the filters | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     readonly hasDataInView: Store<FeatureViewState> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |     readonly guistate: MenuState | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |     readonly fullNodeDatabase?: FullNodeDatabaseSource | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 18:58:31 +02:00
										 |  |  |     readonly historicalUserLocations: WritableFeatureSource<Feature<Point>> | 
					
						
							|  |  |  |     readonly indexedFeatures: IndexedFeatureSource & LayoutSource | 
					
						
							| 
									
										
										
										
											2023-05-05 01:25:37 +02:00
										 |  |  |     readonly currentView: FeatureSource<Feature<Polygon>> | 
					
						
							| 
									
										
										
										
											2023-04-27 00:58:21 +02:00
										 |  |  |     readonly featuresInView: FeatureSource | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |     readonly newFeatures: WritableFeatureSource | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |     readonly layerState: LayerState | 
					
						
							|  |  |  |     readonly perLayer: ReadonlyMap<string, GeoIndexedStoreForLayer> | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |     readonly perLayerFiltered: ReadonlyMap<string, FilteringFeatureSource> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |     readonly availableLayers: Store<RasterLayerPolygon[]> | 
					
						
							|  |  |  |     readonly selectedLayer: UIEventSource<LayerConfig> | 
					
						
							|  |  |  |     readonly userRelatedState: UserRelatedState | 
					
						
							|  |  |  |     readonly geolocation: GeoLocationHandler | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |     readonly lastClickObject: WritableFeatureSource | 
					
						
							| 
									
										
										
										
											2023-04-21 01:53:24 +02:00
										 |  |  |     readonly overlayLayerStates: ReadonlyMap< | 
					
						
							|  |  |  |         string, | 
					
						
							|  |  |  |         { readonly isDisplayed: UIEventSource<boolean> } | 
					
						
							|  |  |  |     > | 
					
						
							| 
									
										
										
										
											2023-04-26 18:04:42 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * All 'level'-tags that are available with the current features | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     readonly floors: Store<string[]> | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |     constructor(layout: LayoutConfig) { | 
					
						
							|  |  |  |         this.layout = layout | 
					
						
							| 
									
										
										
										
											2023-04-19 03:20:49 +02:00
										 |  |  |         this.guistate = new MenuState(layout.id) | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         this.map = new UIEventSource<MlMap>(undefined) | 
					
						
							|  |  |  |         const initial = new InitialMapPositioning(layout) | 
					
						
							|  |  |  |         this.mapProperties = new MapLibreAdaptor(this.map, initial) | 
					
						
							|  |  |  |         const geolocationState = new GeoLocationState() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.featureSwitches = new FeatureSwitchState(layout) | 
					
						
							|  |  |  |         this.featureSwitchIsTesting = this.featureSwitches.featureSwitchIsTesting | 
					
						
							|  |  |  |         this.featureSwitchUserbadge = this.featureSwitches.featureSwitchUserbadge | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.osmConnection = new OsmConnection({ | 
					
						
							|  |  |  |             dryRun: this.featureSwitches.featureSwitchIsTesting, | 
					
						
							|  |  |  |             fakeUser: this.featureSwitches.featureSwitchFakeUser.data, | 
					
						
							|  |  |  |             oauth_token: QueryParameters.GetQueryParameter( | 
					
						
							|  |  |  |                 "oauth_token", | 
					
						
							|  |  |  |                 undefined, | 
					
						
							|  |  |  |                 "Used to complete the login" | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             osmConfiguration: <"osm" | "osm-test">this.featureSwitches.featureSwitchApiURL.data, | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2023-04-14 17:53:08 +02:00
										 |  |  |         this.userRelatedState = new UserRelatedState( | 
					
						
							|  |  |  |             this.osmConnection, | 
					
						
							|  |  |  |             layout?.language, | 
					
						
							|  |  |  |             layout, | 
					
						
							|  |  |  |             this.featureSwitches | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         this.selectedElement = new UIEventSource<Feature | undefined>(undefined, "Selected element") | 
					
						
							|  |  |  |         this.selectedLayer = new UIEventSource<LayerConfig>(undefined, "Selected layer") | 
					
						
							|  |  |  |         this.geolocation = new GeoLocationHandler( | 
					
						
							|  |  |  |             geolocationState, | 
					
						
							|  |  |  |             this.selectedElement, | 
					
						
							|  |  |  |             this.mapProperties, | 
					
						
							|  |  |  |             this.userRelatedState.gpsLocationHistoryRetentionTime | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-04-02 02:59:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         this.availableLayers = AvailableRasterLayers.layersAvailableAt(this.mapProperties.location) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |         const self = this | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         this.layerState = new LayerState(this.osmConnection, layout.layers, layout.id) | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-21 01:53:24 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             const overlayLayerStates = new Map<string, { isDisplayed: UIEventSource<boolean> }>() | 
					
						
							|  |  |  |             for (const rasterInfo of this.layout.tileLayerSources) { | 
					
						
							|  |  |  |                 const isDisplayed = QueryParameters.GetBooleanQueryParameter( | 
					
						
							|  |  |  |                     "overlay-" + rasterInfo.id, | 
					
						
							|  |  |  |                     rasterInfo.defaultState ?? true, | 
					
						
							|  |  |  |                     "Wether or not overlayer layer " + rasterInfo.id + " is shown" | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |                 const state = { isDisplayed } | 
					
						
							| 
									
										
										
										
											2023-04-21 01:53:24 +02:00
										 |  |  |                 overlayLayerStates.set(rasterInfo.id, state) | 
					
						
							|  |  |  |                 new ShowOverlayRasterLayer(rasterInfo, this.map, this.mapProperties, state) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             this.overlayLayerStates = overlayLayerStates | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             /* Setup the layout source | 
					
						
							|  |  |  |              * A bit tricky, as this is heavily intertwined with the 'changes'-element, which generate a stream of new and changed features too | 
					
						
							|  |  |  |              */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |             if (this.layout.layers.some((l) => l._needsFullNodeDatabase)) { | 
					
						
							| 
									
										
										
										
											2023-06-01 02:52:21 +02:00
										 |  |  |                 this.fullNodeDatabase = new FullNodeDatabaseSource() | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |             const layoutSource = new LayoutSource( | 
					
						
							|  |  |  |                 layout.layers, | 
					
						
							|  |  |  |                 this.featureSwitches, | 
					
						
							|  |  |  |                 this.mapProperties, | 
					
						
							|  |  |  |                 this.osmConnection.Backend(), | 
					
						
							| 
									
										
										
										
											2023-06-01 02:52:21 +02:00
										 |  |  |                 (id) => self.layerState.filteredLayers.get(id).isDisplayed, | 
					
						
							|  |  |  |                 this.fullNodeDatabase | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |             ) | 
					
						
							|  |  |  |             this.indexedFeatures = layoutSource | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-05 01:25:37 +02:00
										 |  |  |             const empty = [] | 
					
						
							| 
									
										
										
										
											2023-06-01 02:52:21 +02:00
										 |  |  |             let currentViewIndex = 0 | 
					
						
							| 
									
										
										
										
											2023-05-05 01:25:37 +02:00
										 |  |  |             this.currentView = new StaticFeatureSource( | 
					
						
							| 
									
										
										
										
											2023-06-01 02:52:21 +02:00
										 |  |  |                 this.mapProperties.bounds.map((bbox) => { | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |                     if (!bbox) { | 
					
						
							|  |  |  |                         return empty | 
					
						
							| 
									
										
										
										
											2023-06-01 02:52:21 +02:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |                     currentViewIndex++ | 
					
						
							|  |  |  |                     return <Feature[]>[ | 
					
						
							|  |  |  |                         bbox.asGeoJson({ | 
					
						
							|  |  |  |                             zoom: this.mapProperties.zoom.data, | 
					
						
							|  |  |  |                             ...this.mapProperties.location.data, | 
					
						
							|  |  |  |                             id: "current_view", | 
					
						
							|  |  |  |                         }), | 
					
						
							|  |  |  |                     ] | 
					
						
							|  |  |  |                 }) | 
					
						
							| 
									
										
										
										
											2023-05-05 01:25:37 +02:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2023-04-27 00:58:21 +02:00
										 |  |  |             this.featuresInView = new BBoxFeatureSource(layoutSource, this.mapProperties.bounds) | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |             this.dataIsLoading = layoutSource.isLoading | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |             this.dataIsLoading.addCallbackAndRunD((loading) => | 
					
						
							|  |  |  |                 console.log("Data is loading?", loading) | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             const indexedElements = this.indexedFeatures | 
					
						
							|  |  |  |             this.featureProperties = new FeaturePropertiesStore(indexedElements) | 
					
						
							|  |  |  |             this.changes = new Changes( | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     dryRun: this.featureSwitches.featureSwitchIsTesting, | 
					
						
							|  |  |  |                     allElements: indexedElements, | 
					
						
							|  |  |  |                     featurePropertiesStore: this.featureProperties, | 
					
						
							|  |  |  |                     osmConnection: this.osmConnection, | 
					
						
							|  |  |  |                     historicalUserLocations: this.geolocation.historicalUserLocations, | 
					
						
							| 
									
										
										
										
											2023-03-30 04:51:56 +02:00
										 |  |  |                 }, | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |                 layout?.isLeftRightSensitive() ?? false | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2023-04-20 18:58:31 +02:00
										 |  |  |             this.historicalUserLocations = this.geolocation.historicalUserLocations | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |             this.newFeatures = new NewGeometryFromChangesFeatureSource( | 
					
						
							|  |  |  |                 this.changes, | 
					
						
							|  |  |  |                 indexedElements, | 
					
						
							|  |  |  |                 this.osmConnection.Backend() | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             layoutSource.addSource(this.newFeatures) | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |             const perLayer = new PerLayerFeatureSourceSplitter( | 
					
						
							|  |  |  |                 Array.from(this.layerState.filteredLayers.values()).filter( | 
					
						
							|  |  |  |                     (l) => l.layerDef?.source !== null | 
					
						
							|  |  |  |                 ), | 
					
						
							|  |  |  |                 new ChangeGeometryApplicator(this.indexedFeatures, this.changes), | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     constructStore: (features, layer) => | 
					
						
							|  |  |  |                         new GeoIndexedStoreForLayer(features, layer), | 
					
						
							|  |  |  |                     handleLeftovers: (features) => { | 
					
						
							|  |  |  |                         console.warn( | 
					
						
							|  |  |  |                             "Got ", | 
					
						
							|  |  |  |                             features.length, | 
					
						
							|  |  |  |                             "leftover features, such as", | 
					
						
							|  |  |  |                             features[0].properties | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             this.perLayer = perLayer.perLayer | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         this.perLayer.forEach((fs) => { | 
					
						
							| 
									
										
										
										
											2023-04-21 20:50:38 +02:00
										 |  |  |             new SaveFeatureSourceToLocalStorage( | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |                 this.osmConnection.Backend(), | 
					
						
							| 
									
										
										
										
											2023-04-18 23:44:49 +02:00
										 |  |  |                 fs.layer.layerDef.id, | 
					
						
							|  |  |  |                 15, | 
					
						
							|  |  |  |                 fs, | 
					
						
							| 
									
										
										
										
											2023-06-01 11:38:20 +02:00
										 |  |  |                 this.featureProperties, | 
					
						
							|  |  |  |                 fs.layer.layerDef.maxAgeOfCache | 
					
						
							| 
									
										
										
										
											2023-04-21 20:50:38 +02:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-27 00:58:21 +02:00
										 |  |  |         this.floors = this.featuresInView.features.stabilized(500).map((features) => { | 
					
						
							| 
									
										
										
										
											2023-04-26 18:04:42 +02:00
										 |  |  |             if (!features) { | 
					
						
							|  |  |  |                 return [] | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             const floors = new Set<string>() | 
					
						
							|  |  |  |             for (const feature of features) { | 
					
						
							|  |  |  |                 const level = feature.properties["level"] | 
					
						
							|  |  |  |                 if (level) { | 
					
						
							| 
									
										
										
										
											2023-05-01 01:12:04 +02:00
										 |  |  |                     const levels = level.split(";") | 
					
						
							|  |  |  |                     for (const l of levels) { | 
					
						
							|  |  |  |                         floors.add(l) | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2023-06-01 02:52:21 +02:00
										 |  |  |                 } else { | 
					
						
							| 
									
										
										
										
											2023-05-25 10:45:17 +02:00
										 |  |  |                     floors.add("0") // '0' is the default and is thus _always_ present
 | 
					
						
							| 
									
										
										
										
											2023-04-26 18:04:42 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             const sorted = Array.from(floors) | 
					
						
							|  |  |  |             // Sort alphabetically first, to deal with floor "A", "B" and "C"
 | 
					
						
							|  |  |  |             sorted.sort() | 
					
						
							|  |  |  |             sorted.sort((a, b) => { | 
					
						
							|  |  |  |                 // We use the laxer 'parseInt' to deal with floor '1A'
 | 
					
						
							|  |  |  |                 const na = parseInt(a) | 
					
						
							|  |  |  |                 const nb = parseInt(b) | 
					
						
							|  |  |  |                 if (isNaN(na) || isNaN(nb)) { | 
					
						
							|  |  |  |                     return 0 | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return na - nb | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |             sorted.reverse(/* new list, no side-effects */) | 
					
						
							|  |  |  |             return sorted | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |         const lastClick = (this.lastClickObject = new LastClickFeatureSource( | 
					
						
							|  |  |  |             this.mapProperties.lastClickLocation, | 
					
						
							|  |  |  |             this.layout | 
					
						
							|  |  |  |         )) | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 18:58:31 +02:00
										 |  |  |         this.osmObjectDownloader = new OsmObjectDownloader( | 
					
						
							|  |  |  |             this.osmConnection.Backend(), | 
					
						
							|  |  |  |             this.changes | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-04-20 03:58:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |         this.perLayerFiltered = this.showNormalDataOn(this.map) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.hasDataInView = new NoElementsInViewDetector(this).hasFeatureInView | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         this.initActors() | 
					
						
							| 
									
										
										
										
											2023-05-03 00:57:15 +02:00
										 |  |  |         this.addLastClick(lastClick) | 
					
						
							|  |  |  |         this.drawSpecialLayers() | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         this.initHotkeys() | 
					
						
							|  |  |  |         this.miscSetup() | 
					
						
							| 
									
										
										
										
											2023-06-01 02:52:21 +02:00
										 |  |  |         if (!Utils.runningFromConsole) { | 
					
						
							| 
									
										
										
										
											2023-05-18 15:44:54 +02:00
										 |  |  |             console.log("State setup completed", this) | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |     public showNormalDataOn(map: Store<MlMap>): ReadonlyMap<string, FilteringFeatureSource> { | 
					
						
							|  |  |  |         const filteringFeatureSource = new Map<string, FilteringFeatureSource>() | 
					
						
							|  |  |  |         this.perLayer.forEach((fs, layerName) => { | 
					
						
							| 
									
										
										
										
											2023-06-04 22:52:13 +02:00
										 |  |  |             const doShowLayer = this.mapProperties.zoom.map( | 
					
						
							|  |  |  |                 (z) => | 
					
						
							|  |  |  |                     (fs.layer.isDisplayed?.data ?? true) && z >= (fs.layer.layerDef?.minzoom ?? 0), | 
					
						
							|  |  |  |                 [fs.layer.isDisplayed] | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ( | 
					
						
							|  |  |  |                 !doShowLayer.data && | 
					
						
							|  |  |  |                 (this.featureSwitches.featureSwitchFilter.data === false || !fs.layer.layerDef.name) | 
					
						
							|  |  |  |             ) { | 
					
						
							|  |  |  |                 /* This layer is hidden and there is no way to enable it (filterview is disabled or this layer doesn't show up in the filter view as the name is not defined) | 
					
						
							|  |  |  |                  * | 
					
						
							|  |  |  |                  * This means that we don't have to filter it, nor do we have to display it | 
					
						
							|  |  |  |                  * */ | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             const filtered = new FilteringFeatureSource( | 
					
						
							|  |  |  |                 fs.layer, | 
					
						
							|  |  |  |                 fs, | 
					
						
							|  |  |  |                 (id) => this.featureProperties.getStore(id), | 
					
						
							|  |  |  |                 this.layerState.globalFilters | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |             filteringFeatureSource.set(layerName, filtered) | 
					
						
							| 
									
										
										
										
											2023-06-04 22:52:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             new ShowDataLayer(map, { | 
					
						
							|  |  |  |                 layer: fs.layer.layerDef, | 
					
						
							|  |  |  |                 features: filtered, | 
					
						
							|  |  |  |                 doShowLayer, | 
					
						
							|  |  |  |                 selectedElement: this.selectedElement, | 
					
						
							|  |  |  |                 selectedLayer: this.selectedLayer, | 
					
						
							|  |  |  |                 fetchStore: (id) => this.featureProperties.getStore(id), | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |         return filteringFeatureSource | 
					
						
							| 
									
										
										
										
											2023-06-04 22:52:13 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Various small methods that need to be called | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private miscSetup() { | 
					
						
							|  |  |  |         this.userRelatedState.markLayoutAsVisited(this.layout) | 
					
						
							| 
									
										
										
										
											2023-04-15 02:28:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |         this.selectedElement.addCallbackAndRunD((feature) => { | 
					
						
							|  |  |  |             // As soon as we have a selected element, we clear the selected element
 | 
					
						
							| 
									
										
										
										
											2023-04-15 02:28:24 +02:00
										 |  |  |             // This is to work around maplibre, which'll _first_ register the click on the map and only _then_ on the feature
 | 
					
						
							| 
									
										
										
										
											2023-04-20 01:52:23 +02:00
										 |  |  |             // The only exception is if the last element is the 'add_new'-button, as we don't want it to disappear
 | 
					
						
							|  |  |  |             if (feature.properties.id === "last_click") { | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-04-15 02:28:24 +02:00
										 |  |  |             this.lastClickObject.features.setData([]) | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2023-04-21 16:02:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (this.layout.customCss !== undefined && window.location.pathname.indexOf("theme") >= 0) { | 
					
						
							|  |  |  |             Utils.LoadCustomCss(this.layout.customCss) | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private initHotkeys() { | 
					
						
							|  |  |  |         Hotkeys.RegisterHotkey( | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |             { nomod: "Escape", onUp: true }, | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |             Translations.t.hotkeyDocumentation.closeSidebar, | 
					
						
							|  |  |  |             () => { | 
					
						
							|  |  |  |                 this.selectedElement.setData(undefined) | 
					
						
							|  |  |  |                 this.guistate.closeAll() | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Hotkeys.RegisterHotkey( | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 nomod: "b", | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             Translations.t.hotkeyDocumentation.openLayersPanel, | 
					
						
							|  |  |  |             () => { | 
					
						
							|  |  |  |                 if (this.featureSwitches.featureSwitchFilter.data) { | 
					
						
							|  |  |  |                     this.guistate.openFilterView() | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-04-21 16:47:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-07 04:23:45 +02:00
										 |  |  |         Hotkeys.RegisterHotkey( | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |             { shift: "O" }, | 
					
						
							| 
									
										
										
										
											2023-04-07 04:23:45 +02:00
										 |  |  |             Translations.t.hotkeyDocumentation.selectMapnik, | 
					
						
							|  |  |  |             () => { | 
					
						
							| 
									
										
										
										
											2023-04-21 16:47:25 +02:00
										 |  |  |                 this.mapProperties.rasterLayer.setData(AvailableRasterLayers.osmCarto) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-04-21 17:37:50 +02:00
										 |  |  |         const setLayerCategory = (category: EliCategory) => { | 
					
						
							|  |  |  |             const available = this.availableLayers.data | 
					
						
							|  |  |  |             const current = this.mapProperties.rasterLayer | 
					
						
							|  |  |  |             const best = RasterLayerUtils.SelectBestLayerAccordingTo( | 
					
						
							|  |  |  |                 available, | 
					
						
							|  |  |  |                 category, | 
					
						
							|  |  |  |                 current.data | 
					
						
							| 
									
										
										
										
											2023-04-21 16:47:25 +02:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2023-04-21 17:37:50 +02:00
										 |  |  |             console.log("Best layer for category", category, "is", best.properties.id) | 
					
						
							|  |  |  |             current.setData(best) | 
					
						
							| 
									
										
										
										
											2023-04-21 16:47:25 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Hotkeys.RegisterHotkey( | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |             { nomod: "O" }, | 
					
						
							| 
									
										
										
										
											2023-04-21 16:47:25 +02:00
										 |  |  |             Translations.t.hotkeyDocumentation.selectOsmbasedmap, | 
					
						
							|  |  |  |             () => setLayerCategory("osmbasedmap") | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |         Hotkeys.RegisterHotkey({ nomod: "M" }, Translations.t.hotkeyDocumentation.selectMap, () => | 
					
						
							| 
									
										
										
										
											2023-04-21 16:47:25 +02:00
										 |  |  |             setLayerCategory("map") | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Hotkeys.RegisterHotkey( | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |             { nomod: "P" }, | 
					
						
							| 
									
										
										
										
											2023-04-21 16:47:25 +02:00
										 |  |  |             Translations.t.hotkeyDocumentation.selectAerial, | 
					
						
							|  |  |  |             () => setLayerCategory("photo") | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-01 01:12:04 +02:00
										 |  |  |     private addLastClick(last_click: LastClickFeatureSource) { | 
					
						
							|  |  |  |         // The last_click gets a _very_ special treatment as it interacts with various parts
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const last_click_layer = this.layerState.filteredLayers.get("last_click") | 
					
						
							|  |  |  |         this.featureProperties.trackFeatureSource(last_click) | 
					
						
							|  |  |  |         this.indexedFeatures.addSource(last_click) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         last_click.features.addCallbackAndRunD((features) => { | 
					
						
							|  |  |  |             if (this.selectedLayer.data?.id === "last_click") { | 
					
						
							|  |  |  |                 // The last-click location moved, but we have selected the last click of the previous location
 | 
					
						
							|  |  |  |                 // So, we update _after_ clearing the selection to make sure no stray data is sticking around
 | 
					
						
							|  |  |  |                 this.selectedElement.setData(undefined) | 
					
						
							|  |  |  |                 this.selectedElement.setData(features[0]) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         new ShowDataLayer(this.map, { | 
					
						
							|  |  |  |             features: new FilteringFeatureSource(last_click_layer, last_click), | 
					
						
							|  |  |  |             doShowLayer: new ImmutableStore(true), | 
					
						
							|  |  |  |             layer: last_click_layer.layerDef, | 
					
						
							|  |  |  |             selectedElement: this.selectedElement, | 
					
						
							|  |  |  |             selectedLayer: this.selectedLayer, | 
					
						
							|  |  |  |             onClick: (feature: Feature) => { | 
					
						
							|  |  |  |                 if (this.mapProperties.zoom.data < Constants.minZoomLevelToAddNewPoint) { | 
					
						
							|  |  |  |                     this.map.data.flyTo({ | 
					
						
							|  |  |  |                         zoom: Constants.minZoomLevelToAddNewPoint, | 
					
						
							|  |  |  |                         center: this.mapProperties.lastClickLocation.data, | 
					
						
							|  |  |  |                     }) | 
					
						
							|  |  |  |                     return | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 // We first clear the selection to make sure no weird state is around
 | 
					
						
							|  |  |  |                 this.selectedLayer.setData(undefined) | 
					
						
							|  |  |  |                 this.selectedElement.setData(undefined) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 this.selectedElement.setData(feature) | 
					
						
							|  |  |  |                 this.selectedLayer.setData(last_click_layer.layerDef) | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Add the special layers to the map | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-05-03 00:57:15 +02:00
										 |  |  |     private drawSpecialLayers() { | 
					
						
							| 
									
										
										
										
											2023-06-14 20:44:01 +02:00
										 |  |  |         type AddedByDefaultTypes = (typeof Constants.added_by_default)[number] | 
					
						
							| 
									
										
										
										
											2023-04-02 02:59:20 +02:00
										 |  |  |         const empty = [] | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         /** | 
					
						
							|  |  |  |          * A listing which maps the layerId onto the featureSource | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2023-04-02 02:59:20 +02:00
										 |  |  |         const specialLayers: Record< | 
					
						
							|  |  |  |             Exclude<AddedByDefaultTypes, "last_click"> | "current_view", | 
					
						
							|  |  |  |             FeatureSource | 
					
						
							|  |  |  |         > = { | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |             home_location: this.userRelatedState.homeLocation, | 
					
						
							|  |  |  |             gps_location: this.geolocation.currentUserLocation, | 
					
						
							|  |  |  |             gps_location_history: this.geolocation.historicalUserLocations, | 
					
						
							|  |  |  |             gps_track: this.geolocation.historicalUserLocationsTrack, | 
					
						
							|  |  |  |             selected_element: new StaticFeatureSource( | 
					
						
							|  |  |  |                 this.selectedElement.map((f) => (f === undefined ? empty : [f])) | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             range: new StaticFeatureSource( | 
					
						
							|  |  |  |                 this.mapProperties.maxbounds.map((bbox) => | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |                     bbox === undefined ? empty : <Feature[]>[bbox.asGeoJson({ id: "range" })] | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |                 ) | 
					
						
							|  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |             current_view: this.currentView, | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (this.layout?.lockLocation) { | 
					
						
							|  |  |  |             const bbox = new BBox(this.layout.lockLocation) | 
					
						
							|  |  |  |             this.mapProperties.maxbounds.setData(bbox) | 
					
						
							|  |  |  |             ShowDataLayer.showRange( | 
					
						
							|  |  |  |                 this.map, | 
					
						
							|  |  |  |                 new StaticFeatureSource([bbox.asGeoJson({})]), | 
					
						
							|  |  |  |                 this.featureSwitches.featureSwitchIsTesting | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |         const currentViewLayer = this.layout.layers.find((l) => l.id === "current_view") | 
					
						
							| 
									
										
										
										
											2023-06-01 02:52:21 +02:00
										 |  |  |         if (currentViewLayer?.tagRenderings?.length > 0) { | 
					
						
							|  |  |  |             const params = MetaTagging.createExtraFuncParams(this) | 
					
						
							|  |  |  |             this.featureProperties.trackFeatureSource(specialLayers.current_view) | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |             specialLayers.current_view.features.addCallbackAndRunD((features) => { | 
					
						
							|  |  |  |                 MetaTagging.addMetatags( | 
					
						
							|  |  |  |                     features, | 
					
						
							|  |  |  |                     params, | 
					
						
							|  |  |  |                     currentViewLayer, | 
					
						
							|  |  |  |                     this.layout, | 
					
						
							|  |  |  |                     this.osmObjectDownloader, | 
					
						
							|  |  |  |                     this.featureProperties | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2023-06-01 02:52:21 +02:00
										 |  |  |             }) | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.layerState.filteredLayers | 
					
						
							|  |  |  |             .get("range") | 
					
						
							|  |  |  |             ?.isDisplayed?.syncWith(this.featureSwitches.featureSwitchIsTesting, true) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.layerState.filteredLayers.forEach((flayer) => { | 
					
						
							| 
									
										
										
										
											2023-04-21 16:02:36 +02:00
										 |  |  |             const id = flayer.layerDef.id | 
					
						
							|  |  |  |             const features: FeatureSource = specialLayers[id] | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |             if (features === undefined) { | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-04-20 18:58:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-23 13:14:54 +02:00
										 |  |  |             this.featureProperties.trackFeatureSource(features) | 
					
						
							|  |  |  |             //  this.indexedFeatures.addSource(features)
 | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |             new ShowDataLayer(this.map, { | 
					
						
							|  |  |  |                 features, | 
					
						
							|  |  |  |                 doShowLayer: flayer.isDisplayed, | 
					
						
							|  |  |  |                 layer: flayer.layerDef, | 
					
						
							|  |  |  |                 selectedElement: this.selectedElement, | 
					
						
							|  |  |  |                 selectedLayer: this.selectedLayer, | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Setup various services for which no reference are needed | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private initActors() { | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |         // Unselect the selected element if it is panned out of view
 | 
					
						
							|  |  |  |         this.mapProperties.bounds.stabilized(250).addCallbackD((bounds) => { | 
					
						
							|  |  |  |             const selected = this.selectedElement.data | 
					
						
							|  |  |  |             if (selected === undefined) { | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             const bbox = BBox.get(selected) | 
					
						
							|  |  |  |             if (!bbox.overlapsWith(bounds)) { | 
					
						
							|  |  |  |                 this.selectedElement.setData(undefined) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.selectedElement.addCallback((selected) => { | 
					
						
							|  |  |  |             if (selected === undefined) { | 
					
						
							|  |  |  |                 // We did _unselect_ an item - we always remove the lastclick-object
 | 
					
						
							|  |  |  |                 this.lastClickObject.features.setData([]) | 
					
						
							|  |  |  |                 this.selectedLayer.setData(undefined) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2023-06-07 18:04:25 +02:00
										 |  |  |         new ThemeViewStateHashActor(this) | 
					
						
							| 
									
										
										
										
											2023-04-14 17:53:08 +02:00
										 |  |  |         new MetaTagging(this) | 
					
						
							| 
									
										
										
										
											2023-04-02 02:59:20 +02:00
										 |  |  |         new TitleHandler(this.selectedElement, this.selectedLayer, this.featureProperties, this) | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         new ChangeToElementsActor(this.changes, this.featureProperties) | 
					
						
							|  |  |  |         new PendingChangesUploader(this.changes, this.selectedElement) | 
					
						
							| 
									
										
										
										
											2023-04-07 03:54:11 +02:00
										 |  |  |         new SelectedElementTagsUpdater(this) | 
					
						
							| 
									
										
										
										
											2023-04-21 17:37:50 +02:00
										 |  |  |         new BackgroundLayerResetter(this.mapProperties.rasterLayer, this.availableLayers) | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } |