| 
									
										
										
										
											2021-01-27 01:14:16 +01:00
										 |  |  | import { UIEventSource } from "../UIEventSource" | 
					
						
							| 
									
										
										
										
											2021-07-28 00:09:17 +02:00
										 |  |  | import { OsmObject } from "../Osm/OsmObject" | 
					
						
							| 
									
										
										
										
											2021-05-06 01:33:09 +02:00
										 |  |  | import Loc from "../../Models/Loc" | 
					
						
							| 
									
										
										
										
											2021-09-21 03:10:15 +02:00
										 |  |  | import { ElementStorage } from "../ElementStorage" | 
					
						
							| 
									
										
										
										
											2021-09-22 05:02:09 +02:00
										 |  |  | import FeaturePipeline from "../FeatureSource/FeaturePipeline" | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  | import { GeoOperations } from "../GeoOperations" | 
					
						
							|  |  |  | import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig" | 
					
						
							| 
									
										
										
										
											2021-01-27 01:14:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2021-05-06 01:33:09 +02:00
										 |  |  |  * Makes sure the hash shows the selected element and vice-versa. | 
					
						
							| 
									
										
										
										
											2021-01-27 01:14:16 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | export default class SelectedFeatureHandler { | 
					
						
							| 
									
										
										
										
											2021-11-12 04:11:53 +01:00
										 |  |  |     private static readonly _no_trigger_on = new Set([ | 
					
						
							|  |  |  |         "welcome", | 
					
						
							|  |  |  |         "copyright", | 
					
						
							|  |  |  |         "layers", | 
					
						
							|  |  |  |         "new", | 
					
						
							|  |  |  |         "filters", | 
					
						
							|  |  |  |         "location_track", | 
					
						
							|  |  |  |         "", | 
					
						
							|  |  |  |         undefined, | 
					
						
							|  |  |  |     ]) | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |     private readonly hash: UIEventSource<string> | 
					
						
							| 
									
										
										
										
											2021-09-21 03:10:15 +02:00
										 |  |  |     private readonly state: { | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |         selectedElement: UIEventSource<any> | 
					
						
							|  |  |  |         allElements: ElementStorage | 
					
						
							|  |  |  |         locationControl: UIEventSource<Loc> | 
					
						
							|  |  |  |         layoutToUse: LayoutConfig | 
					
						
							| 
									
										
										
										
											2021-09-21 03:10:15 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor( | 
					
						
							|  |  |  |         hash: UIEventSource<string>, | 
					
						
							|  |  |  |         state: { | 
					
						
							|  |  |  |             selectedElement: UIEventSource<any> | 
					
						
							| 
									
										
										
										
											2021-09-22 05:02:09 +02:00
										 |  |  |             allElements: ElementStorage | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |             featurePipeline: FeaturePipeline | 
					
						
							|  |  |  |             locationControl: UIEventSource<Loc> | 
					
						
							|  |  |  |             layoutToUse: LayoutConfig | 
					
						
							| 
									
										
										
										
											2021-09-21 03:10:15 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     ) { | 
					
						
							|  |  |  |         this.hash = hash | 
					
						
							|  |  |  |         this.state = state | 
					
						
							| 
									
										
										
										
											2021-09-22 05:02:09 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // If the hash changes, set the selected element correctly
 | 
					
						
							| 
									
										
										
										
											2021-07-28 00:09:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |         const self = this | 
					
						
							|  |  |  |         hash.addCallback(() => self.setSelectedElementFromHash()) | 
					
						
							|  |  |  |         this.initialLoad() | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-10-23 02:46:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * On startup: check if the hash is loaded and eventually zoom to it | 
					
						
							|  |  |  |      * @private | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private initialLoad() { | 
					
						
							|  |  |  |         const hash = this.hash.data | 
					
						
							|  |  |  |         if (hash === undefined || hash === "" || hash.indexOf("-") >= 0) { | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (SelectedFeatureHandler._no_trigger_on.has(hash)) { | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-23 02:46:37 +02:00
										 |  |  |         if (!(hash.startsWith("node") || hash.startsWith("way") || hash.startsWith("relation"))) { | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-11-07 16:34:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |         OsmObject.DownloadObjectAsync(hash).then((obj) => { | 
					
						
							|  |  |  |             try { | 
					
						
							|  |  |  |                 console.log("Downloaded selected object from OSM-API for initial load: ", hash) | 
					
						
							|  |  |  |                 const geojson = obj.asGeoJson() | 
					
						
							|  |  |  |                 this.state.allElements.addOrGetElement(geojson) | 
					
						
							|  |  |  |                 this.state.selectedElement.setData(geojson) | 
					
						
							|  |  |  |                 this.zoomToSelectedFeature() | 
					
						
							|  |  |  |             } catch (e) { | 
					
						
							|  |  |  |                 console.error(e) | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-09-22 05:02:09 +02:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2021-01-27 01:14:16 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-07-28 00:09:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |     private setSelectedElementFromHash() { | 
					
						
							|  |  |  |         const state = this.state | 
					
						
							|  |  |  |         const h = this.hash.data | 
					
						
							|  |  |  |         if (h === undefined || h === "") { | 
					
						
							|  |  |  |             // Hash has been cleared - we clear the selected element
 | 
					
						
							|  |  |  |             state.selectedElement.setData(undefined) | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             // we search the element to select
 | 
					
						
							|  |  |  |             const feature = state.allElements.ContainingFeatures.get(h) | 
					
						
							|  |  |  |             if (feature === undefined) { | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-02-09 16:05:37 +01:00
										 |  |  |             const currentlySelected = state.selectedElement.data | 
					
						
							|  |  |  |             if (currentlySelected === undefined) { | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |                 state.selectedElement.setData(feature) | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-02-09 16:05:37 +01:00
										 |  |  |             if (currentlySelected.properties?.id === feature.properties.id) { | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |                 // We already have the right feature
 | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             state.selectedElement.setData(feature) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 01:33:09 +02:00
										 |  |  |     // If a feature is selected via the hash, zoom there
 | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |     private zoomToSelectedFeature() { | 
					
						
							|  |  |  |         const selected = this.state.selectedElement.data | 
					
						
							| 
									
										
										
										
											2021-10-23 02:46:37 +02:00
										 |  |  |         if (selected === undefined) { | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2021-05-06 01:33:09 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-10-23 02:46:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const centerpoint = GeoOperations.centerpointCoordinates(selected) | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |         const location = this.state.locationControl | 
					
						
							|  |  |  |         location.data.lon = centerpoint[0] | 
					
						
							|  |  |  |         location.data.lat = centerpoint[1] | 
					
						
							| 
									
										
										
										
											2021-10-23 02:46:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |         const minZoom = Math.max( | 
					
						
							|  |  |  |             14, | 
					
						
							|  |  |  |             ...(this.state.layoutToUse?.layers?.map((l) => l.minzoomVisible) ?? []) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-10-23 02:46:37 +02:00
										 |  |  |         if (location.data.zoom < minZoom) { | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |             location.data.zoom = minZoom | 
					
						
							| 
									
										
										
										
											2021-07-18 14:52:09 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-10-23 02:46:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |         location.ping() | 
					
						
							| 
									
										
										
										
											2021-05-06 01:33:09 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-27 01:14:16 +01:00
										 |  |  | } |