| 
									
										
										
										
											2022-12-16 13:45:07 +01:00
										 |  |  | import { Store, UIEventSource } from "../../Logic/UIEventSource" | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import LayerConfig from "../../Models/ThemeConfig/LayerConfig" | 
					
						
							| 
									
										
										
										
											2022-12-16 13:45:07 +01:00
										 |  |  | import { ShowDataLayerOptions } from "./ShowDataLayerOptions" | 
					
						
							|  |  |  | import { ElementStorage } from "../../Logic/ElementStorage" | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import RenderingMultiPlexerFeatureSource from "../../Logic/FeatureSource/Sources/RenderingMultiPlexerFeatureSource" | 
					
						
							|  |  |  | import ScrollableFullScreen from "../Base/ScrollableFullScreen" | 
					
						
							| 
									
										
										
										
											2023-01-04 17:41:11 +01:00
										 |  |  | import { LeafletMouseEvent, PathOptions } from "leaflet" | 
					
						
							| 
									
										
										
										
											2022-12-16 13:45:07 +01:00
										 |  |  | import Hash from "../../Logic/Web/Hash" | 
					
						
							| 
									
										
										
										
											2023-01-04 17:41:11 +01:00
										 |  |  | import { BBox } from "../../Logic/BBox" | 
					
						
							|  |  |  | import { Utils } from "../../Utils" | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2022-12-08 02:56:49 +01:00
										 |  |  | // import 'leaflet-polylineoffset';
 | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  | We don't actually import it here. It is imported in the 'MinimapImplementation'-class, which'll result in a patched 'L' object. | 
					
						
							|  |  |  |  Even though actually importing this here would seem cleaner, we don't do this as this breaks some scripts: | 
					
						
							|  |  |  |  - Scripts are ran in ts-node | 
					
						
							|  |  |  |  - ts-node doesn't define the 'window'-object | 
					
						
							|  |  |  |  - Importing this will execute some code which needs the window object | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * The data layer shows all the given geojson elements with the appropriate icon etc | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export default class ShowDataLayerImplementation { | 
					
						
							|  |  |  |     private static dataLayerIds = 0 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private readonly _leafletMap: Store<L.Map> | 
					
						
							|  |  |  |     private readonly _enablePopups: boolean | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |     private readonly _features: RenderingMultiPlexerFeatureSource | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private readonly _layerToShow: LayerConfig | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |     private readonly _selectedElement: UIEventSource<any> | 
					
						
							|  |  |  |     private readonly allElements: ElementStorage | 
					
						
							|  |  |  |     // Used to generate a fresh ID when needed
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private _cleanCount = 0 | 
					
						
							|  |  |  |     private geoLayer = undefined | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * A collection of functions to call when the current geolayer is unregistered | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private unregister: (() => void)[] = [] | 
					
						
							|  |  |  |     private isDirty = false | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * If the selected element triggers, this is used to lookup the correct layer and to open the popup | 
					
						
							|  |  |  |      * Used to avoid a lot of callbacks on the selected element | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Note: the key of this dictionary is 'feature.properties.id+features.geometry.type' as one feature might have multiple presentations | 
					
						
							|  |  |  |      * @private | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2022-12-16 13:45:07 +01:00
										 |  |  |     private readonly leafletLayersPerId = new Map< | 
					
						
							|  |  |  |         string, | 
					
						
							|  |  |  |         { feature: any; activateFunc: (event: LeafletMouseEvent) => void } | 
					
						
							|  |  |  |     >() | 
					
						
							| 
									
										
										
										
											2023-01-04 17:41:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private readonly showDataLayerid: number | 
					
						
							|  |  |  |     private readonly createPopup: ( | 
					
						
							|  |  |  |         tags: UIEventSource<any>, | 
					
						
							|  |  |  |         layer: LayerConfig | 
					
						
							|  |  |  |     ) => ScrollableFullScreen | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Creates a datalayer. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * If 'createPopup' is set, this function is called every time that 'popupOpen' is called | 
					
						
							|  |  |  |      * @param options | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     constructor(options: ShowDataLayerOptions & { layerToShow: LayerConfig }) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         this._leafletMap = options.leafletMap | 
					
						
							|  |  |  |         this.showDataLayerid = ShowDataLayerImplementation.dataLayerIds | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         ShowDataLayerImplementation.dataLayerIds++ | 
					
						
							|  |  |  |         if (options.features === undefined) { | 
					
						
							|  |  |  |             console.error("Invalid ShowDataLayer invocation: options.features is undefed") | 
					
						
							|  |  |  |             throw "Invalid ShowDataLayer invocation: options.features is undefed" | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         this._features = new RenderingMultiPlexerFeatureSource( | 
					
						
							|  |  |  |             options.features, | 
					
						
							|  |  |  |             options.layerToShow | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         this._layerToShow = options.layerToShow | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         this._selectedElement = options.selectedElement | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         this.allElements = options.state?.allElements | 
					
						
							|  |  |  |         this.createPopup = undefined | 
					
						
							|  |  |  |         this._enablePopups = options.popup !== undefined | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         if (options.popup !== undefined) { | 
					
						
							|  |  |  |             this.createPopup = options.popup | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const self = this | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-04 17:41:11 +01:00
										 |  |  |         options.leafletMap.addCallback(() => { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return self.update(options) | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         this._features.features.addCallback((_) => self.update(options)) | 
					
						
							|  |  |  |         options.doShowLayer?.addCallback((doShow) => { | 
					
						
							|  |  |  |             const mp = options.leafletMap.data | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |             if (mp === null) { | 
					
						
							|  |  |  |                 self.Destroy() | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 return true | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |             if (mp == undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (doShow) { | 
					
						
							|  |  |  |                 if (self.isDirty) { | 
					
						
							|  |  |  |                     return self.update(options) | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     mp.addLayer(this.geoLayer) | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 if (this.geoLayer !== undefined) { | 
					
						
							|  |  |  |                     mp.removeLayer(this.geoLayer) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     this.unregister.forEach((f) => f()) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |                     this.unregister = [] | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         this._selectedElement?.addCallbackAndRunD((selected) => { | 
					
						
							| 
									
										
										
										
											2023-01-04 18:52:49 +01:00
										 |  |  |             if (selected === undefined) { | 
					
						
							|  |  |  |                 ScrollableFullScreen.collapse() | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |             self.openPopupOfSelectedElement(selected) | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.update(options) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private Destroy() { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         this.unregister.forEach((f) => f()) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private openPopupOfSelectedElement(selected) { | 
					
						
							|  |  |  |         if (selected === undefined) { | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (this._leafletMap.data === undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         const v = this.leafletLayersPerId.get(selected.properties.id + selected.geometry.type) | 
					
						
							|  |  |  |         if (v === undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         const feature = v.feature | 
					
						
							|  |  |  |         if (selected.properties.id !== feature.properties.id) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (feature.id !== feature.properties.id) { | 
					
						
							|  |  |  |             // Probably a feature which has renamed
 | 
					
						
							|  |  |  |             // the feature might have as id 'node/-1' and as 'feature.properties.id' = 'the newly assigned id'. That is no good too
 | 
					
						
							|  |  |  |             console.log("Not opening the popup for", feature, "as probably renamed") | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-12-08 02:56:49 +01:00
										 |  |  |         v.activateFunc(null) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private update(options: ShowDataLayerOptions): boolean { | 
					
						
							|  |  |  |         if (this._features.features.data === undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         this.isDirty = true | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         if (options?.doShowLayer?.data === false) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const mp = options.leafletMap.data | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (mp === null) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return true // Unregister as the map has been destroyed
 | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (mp === undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this._cleanCount++ | 
					
						
							|  |  |  |         // clean all the old stuff away, if any
 | 
					
						
							|  |  |  |         if (this.geoLayer !== undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             mp.removeLayer(this.geoLayer) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const self = this | 
					
						
							| 
									
										
										
										
											2023-01-04 17:41:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.geoLayer = new L.LayerGroup() | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const selfLayer = this.geoLayer | 
					
						
							|  |  |  |         const allFeats = this._features.features.data | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         for (const feat of allFeats) { | 
					
						
							|  |  |  |             if (feat === undefined) { | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-01-04 17:41:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // Why not one geojson layer with _all_ features, and attaching a right-click onto every feature individually?
 | 
					
						
							|  |  |  |             // Because that somehow doesn't work :(
 | 
					
						
							|  |  |  |             const feature = feat | 
					
						
							|  |  |  |             const geojsonLayer = L.geoJSON(feature, { | 
					
						
							|  |  |  |                 style: (feature) => <PathOptions>self.createStyleFor(feature), | 
					
						
							|  |  |  |                 pointToLayer: (feature, latLng) => self.pointToLayer(feature, latLng), | 
					
						
							|  |  |  |                 onEachFeature: (feature, leafletLayer) => | 
					
						
							|  |  |  |                     self.postProcessFeature(feature, leafletLayer), | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |             if (feature.geometry.type === "Point") { | 
					
						
							|  |  |  |                 geojsonLayer.on({ | 
					
						
							|  |  |  |                     contextmenu: (e) => { | 
					
						
							|  |  |  |                         const o = self.leafletLayersPerId.get(feature?.properties?.id) | 
					
						
							|  |  |  |                         o?.activateFunc(<LeafletMouseEvent>e) | 
					
						
							|  |  |  |                         Utils.preventDefaultOnMouseEvent(e.originalEvent) | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                     dblclick: (e) => { | 
					
						
							|  |  |  |                         const o = self.leafletLayersPerId.get(feature?.properties?.id) | 
					
						
							|  |  |  |                         o?.activateFunc(<LeafletMouseEvent>e) | 
					
						
							|  |  |  |                         Utils.preventDefaultOnMouseEvent(e.originalEvent) | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 }) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             this.geoLayer.addLayer(geojsonLayer) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |             try { | 
					
						
							|  |  |  |                 if (feat.geometry.type === "LineString") { | 
					
						
							|  |  |  |                     const coords = L.GeoJSON.coordsToLatLngs(feat.geometry.coordinates) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     const tagsSource = | 
					
						
							|  |  |  |                         this.allElements?.addOrGetElement(feat) ?? | 
					
						
							|  |  |  |                         new UIEventSource<any>(feat.properties) | 
					
						
							|  |  |  |                     let offsettedLine | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |                     tagsSource | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                         .map((tags) => | 
					
						
							|  |  |  |                             this._layerToShow.lineRendering[ | 
					
						
							|  |  |  |                                 feat.lineRenderingIndex | 
					
						
							|  |  |  |                             ].GenerateLeafletStyle(tags) | 
					
						
							|  |  |  |                         ) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |                         .withEqualityStabilized((a, b) => { | 
					
						
							|  |  |  |                             if (a === b) { | 
					
						
							|  |  |  |                                 return true | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                             if (a === undefined || b === undefined) { | 
					
						
							|  |  |  |                                 return false | 
					
						
							|  |  |  |                             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                             return ( | 
					
						
							|  |  |  |                                 a.offset === b.offset && | 
					
						
							|  |  |  |                                 a.color === b.color && | 
					
						
							|  |  |  |                                 a.weight === b.weight && | 
					
						
							|  |  |  |                                 a.dashArray === b.dashArray | 
					
						
							|  |  |  |                             ) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |                         }) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                         .addCallbackAndRunD((lineStyle) => { | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |                             if (offsettedLine !== undefined) { | 
					
						
							|  |  |  |                                 self.geoLayer.removeLayer(offsettedLine) | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                             // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                             offsettedLine = L.polyline(coords, lineStyle) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |                             this.postProcessFeature(feat, offsettedLine) | 
					
						
							|  |  |  |                             offsettedLine.addTo(this.geoLayer) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                             // If 'self.geoLayer' is not the same as the layer the feature is added to, we can safely remove this callback
 | 
					
						
							|  |  |  |                             return self.geoLayer !== selfLayer | 
					
						
							|  |  |  |                         }) | 
					
						
							|  |  |  |                 } else { | 
					
						
							| 
									
										
										
										
											2023-01-04 17:41:11 +01:00
										 |  |  |                     geojsonLayer.addData(feat) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } catch (e) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 console.error( | 
					
						
							|  |  |  |                     "Could not add ", | 
					
						
							|  |  |  |                     feat, | 
					
						
							|  |  |  |                     "to the geojson layer in leaflet due to", | 
					
						
							|  |  |  |                     e, | 
					
						
							|  |  |  |                     e.stack | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-04 17:41:11 +01:00
										 |  |  |         if ((options.zoomToFeatures ?? false) && allFeats.length > 0) { | 
					
						
							|  |  |  |             let bound = undefined | 
					
						
							|  |  |  |             for (const feat of allFeats) { | 
					
						
							|  |  |  |                 const fbound = BBox.get(feat) | 
					
						
							|  |  |  |                 bound = bound?.unionWith(fbound) ?? fbound | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (bound !== undefined) { | 
					
						
							|  |  |  |                 mp.fitBounds(bound?.toLeaflet(), { animate: false }) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (options.doShowLayer?.data ?? true) { | 
					
						
							|  |  |  |             mp.addLayer(this.geoLayer) | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         this.isDirty = false | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         this.openPopupOfSelectedElement(this._selectedElement?.data) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private createStyleFor(feature) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const tagsSource = | 
					
						
							|  |  |  |             this.allElements?.addOrGetElement(feature) ?? new UIEventSource<any>(feature.properties) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         // Every object is tied to exactly one layer
 | 
					
						
							|  |  |  |         const layer = this._layerToShow | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const pointRenderingIndex = feature.pointRenderingIndex | 
					
						
							|  |  |  |         const lineRenderingIndex = feature.lineRenderingIndex | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (pointRenderingIndex !== undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const style = layer.mapRendering[pointRenderingIndex].GenerateLeafletStyle( | 
					
						
							|  |  |  |                 tagsSource, | 
					
						
							|  |  |  |                 this._enablePopups | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |             return { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 icon: style, | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (lineRenderingIndex !== undefined) { | 
					
						
							|  |  |  |             return layer.lineRendering[lineRenderingIndex].GenerateLeafletStyle(tagsSource.data) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         throw "Neither lineRendering nor mapRendering defined for " + feature | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private pointToLayer(feature, latLng): L.Layer { | 
					
						
							|  |  |  |         // Leaflet cannot handle geojson points natively
 | 
					
						
							|  |  |  |         // We have to convert them to the appropriate icon
 | 
					
						
							|  |  |  |         // Click handling is done in the next step
 | 
					
						
							|  |  |  |         const layer: LayerConfig = this._layerToShow | 
					
						
							|  |  |  |         if (layer === undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         let tagSource = | 
					
						
							|  |  |  |             this.allElements?.getEventSourceById(feature.properties.id) ?? | 
					
						
							|  |  |  |             new UIEventSource<any>(feature.properties) | 
					
						
							|  |  |  |         const clickable = | 
					
						
							|  |  |  |             !(layer.title === undefined && (layer.tagRenderings ?? []).length === 0) && | 
					
						
							|  |  |  |             this._enablePopups | 
					
						
							|  |  |  |         let style: any = layer.mapRendering[feature.pointRenderingIndex].GenerateLeafletStyle( | 
					
						
							|  |  |  |             tagSource, | 
					
						
							|  |  |  |             clickable | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         const baseElement = style.html | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         if (!this._enablePopups) { | 
					
						
							|  |  |  |             baseElement.SetStyle("cursor: initial !important") | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         style.html = style.html.ConstructElement() | 
					
						
							|  |  |  |         return L.marker(latLng, { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             icon: L.divIcon(style), | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-01-04 17:41:11 +01:00
										 |  |  |     private createActivateFunction(feature, key: string, layer: LayerConfig): (event) => void { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         let infobox: ScrollableFullScreen = undefined | 
					
						
							| 
									
										
										
										
											2022-12-08 02:56:49 +01:00
										 |  |  |         const self = this | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-16 13:45:07 +01:00
										 |  |  |         function activate(event: LeafletMouseEvent) { | 
					
						
							| 
									
										
										
										
											2023-01-13 03:49:22 +01:00
										 |  |  |             Utils.preventDefaultOnMouseEvent(event) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |             if (infobox === undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 const tags = | 
					
						
							| 
									
										
										
										
											2022-12-08 02:56:49 +01:00
										 |  |  |                     self.allElements?.getEventSourceById(key) ?? | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     new UIEventSource<any>(feature.properties) | 
					
						
							| 
									
										
										
										
											2022-12-08 02:56:49 +01:00
										 |  |  |                 infobox = self.createPopup(tags, layer) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-08 02:56:49 +01:00
										 |  |  |                 self.unregister.push(() => { | 
					
						
							|  |  |  |                     console.log("Destroying infobox") | 
					
						
							|  |  |  |                     infobox.Destroy() | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 }) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             infobox.Activate() | 
					
						
							| 
									
										
										
										
											2022-12-16 13:45:07 +01:00
										 |  |  |             self._selectedElement.setData( | 
					
						
							|  |  |  |                 self.allElements.ContainingFeatures.get(feature.id) ?? feature | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2023-01-04 17:41:11 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         return activate | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Post processing - basically adding the popup | 
					
						
							|  |  |  |      * @param feature | 
					
						
							|  |  |  |      * @param leafletLayer | 
					
						
							|  |  |  |      * @private | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private postProcessFeature(feature, leafletLayer: L.Evented) { | 
					
						
							|  |  |  |         const layer: LayerConfig = this._layerToShow | 
					
						
							|  |  |  |         if (layer.title === undefined || !this._enablePopups) { | 
					
						
							|  |  |  |             // No popup action defined -> Don't do anything
 | 
					
						
							|  |  |  |             // or probably a map in the popup - no popups needed!
 | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         const key = feature.properties.id | 
					
						
							|  |  |  |         let activate: (event) => void | 
					
						
							|  |  |  |         if (this.leafletLayersPerId.has(key)) { | 
					
						
							|  |  |  |             activate = this.leafletLayersPerId.get(key).activateFunc | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             activate = this.createActivateFunction(feature, key, layer) | 
					
						
							| 
									
										
										
										
											2022-12-08 02:56:49 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-04 17:41:11 +01:00
										 |  |  |         // We also have to open on rightclick, doubleclick, ... as users sometimes do this. See #1219
 | 
					
						
							|  |  |  |         leafletLayer.on({ | 
					
						
							|  |  |  |             dblclick: activate, | 
					
						
							|  |  |  |             contextmenu: activate, | 
					
						
							| 
									
										
										
										
											2023-01-13 03:49:22 +01:00
										 |  |  |             //  click: activate,
 | 
					
						
							| 
									
										
										
										
											2023-01-04 17:41:11 +01:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2023-01-13 03:49:22 +01:00
										 |  |  |         leafletLayer.addEventListener("click", activate) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         // Add the feature to the index to open the popup when needed
 | 
					
						
							| 
									
										
										
										
											2022-12-08 02:56:49 +01:00
										 |  |  |         this.leafletLayersPerId.set(key, { | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |             feature: feature, | 
					
						
							| 
									
										
										
										
											2022-12-08 02:56:49 +01:00
										 |  |  |             activateFunc: activate, | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2022-12-16 13:45:07 +01:00
										 |  |  |         if (Hash.hash.data === key) { | 
					
						
							| 
									
										
										
										
											2022-12-08 02:56:49 +01:00
										 |  |  |             activate(null) | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-04-30 00:41:33 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | } |