diff --git a/src/Logic/Actors/InitialMapPositioning.ts b/src/Logic/Actors/InitialMapPositioning.ts index 55b9aaf4b..1c7439bf5 100644 --- a/src/Logic/Actors/InitialMapPositioning.ts +++ b/src/Logic/Actors/InitialMapPositioning.ts @@ -2,10 +2,15 @@ import { ImmutableStore, Store, UIEventSource } from "../UIEventSource" import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig" import { LocalStorageSource } from "../Web/LocalStorageSource" import { QueryParameters } from "../Web/QueryParameters" +import Hash from "../Web/Hash" +import OsmObjectDownloader from "../Osm/OsmObjectDownloader" +import { OsmObject } from "../Osm/OsmObject" +import Constants from "../../Models/Constants" /** * This actor is responsible to set the map location. * It will attempt to + * - Set the map to the position of the selected element * - 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) * - Set the map to the layout default @@ -16,7 +21,7 @@ export default class InitialMapPositioning { public zoom: UIEventSource public location: UIEventSource<{ lon: number; lat: number }> public useTerrain: Store - constructor(layoutToUse: LayoutConfig) { + constructor(layoutToUse: LayoutConfig, downloader: OsmObjectDownloader) { function localStorageSynced( key: string, deflt: number, @@ -38,6 +43,8 @@ export default class InitialMapPositioning { return src } + const initialHash = Hash.hash.data + // -- Location control initialization this.zoom = localStorageSynced( "z", @@ -62,5 +69,17 @@ export default class InitialMapPositioning { lon.setData(loc.lon) }) this.useTerrain = new ImmutableStore(layoutToUse.enableTerrain) + + if(initialHash.match(/^(node|way|relation)\/[0-9]+$/)){ + const [type, id] = initialHash.split("/") + OsmObjectDownloader.RawDownloadObjectAsync(type, Number(id), Constants.osmAuthConfig.url+"/").then(osmObject => { + if(osmObject === "deleted"){ + return + } + const [lat, lon] = osmObject.centerpoint() + this.location.setData({lon, lat}) + }) + } + } } diff --git a/src/Logic/Osm/OsmObject.ts b/src/Logic/Osm/OsmObject.ts index d743b58c9..03048f408 100644 --- a/src/Logic/Osm/OsmObject.ts +++ b/src/Logic/Osm/OsmObject.ts @@ -127,7 +127,9 @@ export abstract class OsmObject { return result } - // The centerpoint of the feature, as [lat, lon] + /** The centerpoint of the feature, as [lat, lon] + * + */ public abstract centerpoint(): [number, number] public abstract asGeoJson(): any diff --git a/src/Logic/Osm/OsmObjectDownloader.ts b/src/Logic/Osm/OsmObjectDownloader.ts index 211827577..4baed2032 100644 --- a/src/Logic/Osm/OsmObjectDownloader.ts +++ b/src/Logic/Osm/OsmObjectDownloader.ts @@ -62,7 +62,7 @@ export default class OsmObjectDownloader { if (idN < 0) { obj = this.constructObject(<"node" | "way" | "relation">type, idN) } else { - obj = await this.RawDownloadObjectAsync(type, idN, maxCacheAgeInSecs) + obj = await OsmObjectDownloader.RawDownloadObjectAsync(type, idN, this.backend, maxCacheAgeInSecs) } if (obj === "deleted") { return obj @@ -211,13 +211,22 @@ export default class OsmObjectDownloader { } } - private async RawDownloadObjectAsync( + /** + * Only to be used in exceptional cases + * @param type + * @param idN + * @param backend + * @param maxCacheAgeInSecs + * @constructor + */ + public static async RawDownloadObjectAsync( type: string, idN: number, + backend: string, maxCacheAgeInSecs?: number ): Promise { const full = type !== "node" ? "/full" : "" - const url = `${this.backend}api/0.6/${type}/${idN}${full}` + const url = `${backend}api/0.6/${type}/${idN}${full}` const rawData = await Utils.downloadJsonCachedAdvanced( url, (maxCacheAgeInSecs ?? 10) * 1000 @@ -227,7 +236,7 @@ export default class OsmObjectDownloader { } // A full query might contain more then just the requested object (e.g. nodes that are part of a way, where we only want the way) const parsed = OsmObject.ParseObjects(rawData["content"].elements) - // Lets fetch the object we need + // Let us fetch the object we need for (const osmObject of parsed) { if (osmObject.type !== type) { continue