| 
									
										
										
										
											2024-02-03 14:33:10 +01:00
										 |  |  | import { ImmutableStore, Store, UIEventSource } from "../UIEventSource" | 
					
						
							| 
									
										
										
										
											2024-10-17 04:06:03 +02:00
										 |  |  | import ThemeConfig from "../../Models/ThemeConfig/ThemeConfig" | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  | import { LocalStorageSource } from "../Web/LocalStorageSource" | 
					
						
							|  |  |  | import { QueryParameters } from "../Web/QueryParameters" | 
					
						
							| 
									
										
										
										
											2024-04-30 17:20:08 +02:00
										 |  |  | import Hash from "../Web/Hash" | 
					
						
							|  |  |  | import OsmObjectDownloader from "../Osm/OsmObjectDownloader" | 
					
						
							|  |  |  | import { OsmObject } from "../Osm/OsmObject" | 
					
						
							|  |  |  | import Constants from "../../Models/Constants" | 
					
						
							| 
									
										
										
										
											2024-06-17 19:27:21 +02:00
										 |  |  | import { Utils } from "../../Utils" | 
					
						
							|  |  |  | import { GeoLocationState } from "../State/GeoLocationState" | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * This actor is responsible to set the map location. | 
					
						
							|  |  |  |  * It will attempt to | 
					
						
							| 
									
										
										
										
											2024-04-30 17:20:08 +02:00
										 |  |  |  * - Set the map to the position of the selected element | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |  * - Set the map to the position as passed in by the query parameters (if available) | 
					
						
							|  |  |  |  * - Set the map to the position remembered in LocalStorage (if available) | 
					
						
							| 
									
										
										
										
											2024-06-17 19:27:21 +02:00
										 |  |  |  * - Set the map to what IP-info says (very coarse) | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |  * - Set the map to the layout default | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Additionally, it will save the map location to local storage | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export default class InitialMapPositioning { | 
					
						
							|  |  |  |     public zoom: UIEventSource<number> | 
					
						
							|  |  |  |     public location: UIEventSource<{ lon: number; lat: number }> | 
					
						
							| 
									
										
										
										
											2024-02-03 14:33:10 +01:00
										 |  |  |     public useTerrain: Store<boolean> | 
					
						
							| 
									
										
										
										
											2024-04-30 18:56:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-17 04:06:03 +02:00
										 |  |  |     constructor(layoutToUse: ThemeConfig, geolocationState: GeoLocationState) { | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |         function localStorageSynced( | 
					
						
							|  |  |  |             key: string, | 
					
						
							|  |  |  |             deflt: number, | 
					
						
							|  |  |  |             docs: string | 
					
						
							|  |  |  |         ): UIEventSource<number> { | 
					
						
							| 
									
										
										
										
											2024-10-17 02:10:25 +02:00
										 |  |  |             const localStorage = LocalStorageSource.get(key) | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |             const previousValue = localStorage.data | 
					
						
							|  |  |  |             const src = UIEventSource.asFloat( | 
					
						
							|  |  |  |                 QueryParameters.GetQueryParameter(key, "" + deflt, docs).syncWith(localStorage) | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (src.data === deflt) { | 
					
						
							|  |  |  |                 const prev = Number(previousValue) | 
					
						
							|  |  |  |                 if (!isNaN(prev)) { | 
					
						
							|  |  |  |                     src.setData(prev) | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return src | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-30 17:20:08 +02:00
										 |  |  |         const initialHash = Hash.hash.data | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |         // -- Location control initialization
 | 
					
						
							|  |  |  |         this.zoom = localStorageSynced( | 
					
						
							|  |  |  |             "z", | 
					
						
							|  |  |  |             layoutToUse?.startZoom ?? 1, | 
					
						
							|  |  |  |             "The initial/current zoom level" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-06-20 04:21:29 +02:00
										 |  |  |         const defaultLat = layoutToUse?.startLat ?? 0 | 
					
						
							|  |  |  |         const lat = localStorageSynced("lat", defaultLat, "The initial/current latitude") | 
					
						
							| 
									
										
										
										
											2024-06-17 19:27:21 +02:00
										 |  |  |         const defaultLon = layoutToUse?.startLon ?? 0 | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |         const lon = localStorageSynced( | 
					
						
							|  |  |  |             "lon", | 
					
						
							| 
									
										
										
										
											2024-06-20 04:21:29 +02:00
										 |  |  |             defaultLon, | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |             "The initial/current longitude of the app" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.location = new UIEventSource({ lon: lon.data, lat: lat.data }) | 
					
						
							| 
									
										
										
										
											2024-02-03 14:33:10 +01:00
										 |  |  |         // Note: this syncs only in one direction
 | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |         this.location.addCallbackD((loc) => { | 
					
						
							|  |  |  |             lat.setData(loc.lat) | 
					
						
							|  |  |  |             lon.setData(loc.lon) | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2024-02-03 14:33:10 +01:00
										 |  |  |         this.useTerrain = new ImmutableStore<boolean>(layoutToUse.enableTerrain) | 
					
						
							| 
									
										
										
										
											2024-04-30 17:20:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-30 18:56:50 +02:00
										 |  |  |         if (initialHash?.match(/^(node|way|relation)\/[0-9]+$/)) { | 
					
						
							| 
									
										
										
										
											2024-06-17 19:27:21 +02:00
										 |  |  |             // We pan to the selected element
 | 
					
						
							| 
									
										
										
										
											2024-04-30 17:20:08 +02:00
										 |  |  |             const [type, id] = initialHash.split("/") | 
					
						
							| 
									
										
										
										
											2024-06-16 16:06:26 +02:00
										 |  |  |             OsmObjectDownloader.RawDownloadObjectAsync( | 
					
						
							|  |  |  |                 type, | 
					
						
							|  |  |  |                 Number(id), | 
					
						
							|  |  |  |                 Constants.osmAuthConfig.url + "/" | 
					
						
							|  |  |  |             ).then((osmObject) => { | 
					
						
							| 
									
										
										
										
											2024-04-30 18:56:50 +02:00
										 |  |  |                 if (osmObject === "deleted") { | 
					
						
							| 
									
										
										
										
											2024-04-30 17:20:08 +02:00
										 |  |  |                     return | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-04-30 18:56:50 +02:00
										 |  |  |                 const targetLayer = layoutToUse.getMatchingLayer(osmObject.tags) | 
					
						
							|  |  |  |                 this.zoom.setData(Math.max(this.zoom.data, targetLayer.minzoom)) | 
					
						
							| 
									
										
										
										
											2024-04-30 17:20:08 +02:00
										 |  |  |                 const [lat, lon] = osmObject.centerpoint() | 
					
						
							| 
									
										
										
										
											2024-04-30 18:56:50 +02:00
										 |  |  |                 this.location.setData({ lon, lat }) | 
					
						
							| 
									
										
										
										
											2024-04-30 17:20:08 +02:00
										 |  |  |             }) | 
					
						
							| 
									
										
										
										
											2024-06-20 04:21:29 +02:00
										 |  |  |         } else if ( | 
					
						
							|  |  |  |             Constants.GeoIpServer && | 
					
						
							|  |  |  |             lat.data === defaultLat && | 
					
						
							|  |  |  |             lon.data === defaultLon && | 
					
						
							|  |  |  |             !Utils.runningFromConsole | 
					
						
							|  |  |  |         ) { | 
					
						
							| 
									
										
										
										
											2024-06-17 19:27:21 +02:00
										 |  |  |             console.log("Using geoip to determine start location...") | 
					
						
							|  |  |  |             // We use geo-IP to zoom to some location
 | 
					
						
							| 
									
										
										
										
											2024-06-20 04:21:29 +02:00
										 |  |  |             Utils.downloadJson<{ latitude: number; longitude: number }>( | 
					
						
							| 
									
										
										
										
											2024-06-17 19:27:21 +02:00
										 |  |  |                 Constants.GeoIpServer + "ip" | 
					
						
							|  |  |  |             ).then(({ longitude, latitude }) => { | 
					
						
							| 
									
										
										
										
											2024-08-09 10:53:09 +02:00
										 |  |  |                 const gpsLoc = geolocationState.currentGPSLocation.data | 
					
						
							|  |  |  |                 if (gpsLoc !== undefined) { | 
					
						
							| 
									
										
										
										
											2024-06-17 19:27:21 +02:00
										 |  |  |                     return // We got a geolocation by now, abort
 | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-06-20 04:21:29 +02:00
										 |  |  |                 console.log("Setting location based on geoip", longitude, latitude) | 
					
						
							| 
									
										
										
										
											2024-06-17 19:27:21 +02:00
										 |  |  |                 this.zoom.setData(8) | 
					
						
							|  |  |  |                 this.location.setData({ lon: longitude, lat: latitude }) | 
					
						
							|  |  |  |             }) | 
					
						
							| 
									
										
										
										
											2024-04-30 17:20:08 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } |