From 0dcc20f20b23ff9b1ad64f269972088a625e7db6 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Tue, 21 Mar 2023 20:01:36 +0100 Subject: [PATCH 1/4] docs: improve typing --- Logic/Osm/OsmObject.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Logic/Osm/OsmObject.ts b/Logic/Osm/OsmObject.ts index 29827789437..b9bff14ec8d 100644 --- a/Logic/Osm/OsmObject.ts +++ b/Logic/Osm/OsmObject.ts @@ -163,6 +163,11 @@ export abstract class OsmObject { }) } + public static DownloadHistory(id: NodeId): UIEventSource + public static DownloadHistory(id: WayId): UIEventSource + public static DownloadHistory(id: RelationId): UIEventSource + + public static DownloadHistory(id: OsmId): UIEventSource public static DownloadHistory(id: string): UIEventSource { if (OsmObject.historyCache.has(id)) { return OsmObject.historyCache.get(id) @@ -180,6 +185,7 @@ export abstract class OsmObject { const osmObjects: OsmObject[] = [] for (const element of elements) { let osmObject: OsmObject = null + element.nodes = [] switch (type) { case "node": osmObject = new OsmNode(idN) From 3eee9bd9f8f165b5521ecf8ee6edc45a77271c00 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Tue, 21 Mar 2023 20:59:09 +0100 Subject: [PATCH 2/4] docs: improve typing --- Logic/ElementStorage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Logic/ElementStorage.ts b/Logic/ElementStorage.ts index 49213b99f6d..8d9723f8e44 100644 --- a/Logic/ElementStorage.ts +++ b/Logic/ElementStorage.ts @@ -38,7 +38,7 @@ export class ElementStorage { return es } - getEventSourceById(elementId): UIEventSource { + getEventSourceById(elementId): UIEventSource | undefined { if (elementId === undefined) { return undefined } From b99588b4ba90b1130aac939ff5c6a54275182fe6 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Tue, 21 Mar 2023 20:59:31 +0100 Subject: [PATCH 3/4] performance: Make _referencing_ways actually lazy --- Logic/SimpleMetaTagger.ts | 46 +++++++++++++++---------------- Utils.ts | 57 ++++++++++++++++++++++++++++++++++----- 2 files changed, 71 insertions(+), 32 deletions(-) diff --git a/Logic/SimpleMetaTagger.ts b/Logic/SimpleMetaTagger.ts index 7b38d85bc51..faddf290631 100644 --- a/Logic/SimpleMetaTagger.ts +++ b/Logic/SimpleMetaTagger.ts @@ -80,20 +80,25 @@ export class ReferencingWaysMetaTagger extends SimpleMetaTagger { if (!id.startsWith("node/")) { return false } - console.trace("Downloading referencing ways for", feature.properties.id) - OsmObject.DownloadReferencingWays(id).then((referencingWays) => { - const currentTagsSource = state.allElements?.getEventSourceById(id) ?? [] - const wayIds = referencingWays.map((w) => "way/" + w.id) - wayIds.sort() - const wayIdsStr = wayIds.join(";") - if ( - wayIdsStr !== "" && - currentTagsSource.data["_referencing_ways"] !== wayIdsStr - ) { - currentTagsSource.data["_referencing_ways"] = wayIdsStr - currentTagsSource.ping() + + const currentTagsSource = state.allElements?.getEventSourceById(id) + if (currentTagsSource === undefined) { + return + } + Utils.AddLazyPropertyAsync( + currentTagsSource.data, + "_referencing_ways", + async () => { + const referencingWays = await OsmObject.DownloadReferencingWays(id) + const wayIds = referencingWays.map((w) => "way/" + w.id) + wayIds.sort() + const wayIdsStr = wayIds.join(";") + if (wayIdsStr !== "" && currentTagsSource.data[""] !== wayIdsStr) { + currentTagsSource.data["_referencing_ways"] = wayIdsStr + currentTagsSource.ping() + } } - }) + ) return true } @@ -282,16 +287,9 @@ export default class SimpleMetaTaggers { }, }) - Object.defineProperty(feature.properties, "_surface:ha", { - enumerable: false, - configurable: true, - get: () => { - const sqMeters = GeoOperations.surfaceAreaInSqMeters(feature) - const sqMetersHa = "" + Math.floor(sqMeters / 1000) / 10 - delete feature.properties["_surface:ha"] - feature.properties["_surface:ha"] = sqMetersHa - return sqMetersHa - }, + Utils.AddLazyProperty(feature.properties, "_surface:ha", () => { + const sqMeters = GeoOperations.surfaceAreaInSqMeters(feature) + return "" + Math.floor(sqMeters / 1000) / 10 }) return true @@ -443,8 +441,6 @@ export default class SimpleMetaTaggers { } }, }) - - const tagsSource = state.allElements.getEventSourceById(feature.properties.id) } ) private static directionSimplified = new SimpleMetaTagger( diff --git a/Utils.ts b/Utils.ts index 8bc0e011cfd..7e8fdff24bf 100644 --- a/Utils.ts +++ b/Utils.ts @@ -300,6 +300,49 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be return str.substr(0, l - 3) + "..." } + /** + * Adds a property to the given object, but the value will _only_ be calculated when it is actually requested + * @param object + * @param name + * @param init + * @constructor + */ + public static AddLazyProperty(object: any, name: string, init: () => any) { + Object.defineProperty(object, name, { + enumerable: false, + configurable: true, + get: () => { + delete object[name] + object[name] = init() + return object[name] + }, + }) + } + + /** + * Adds a property to the given object, but the value will _only_ be calculated when it is actually requested + */ + public static AddLazyPropertyAsync( + object: any, + name: string, + init: () => Promise, + whenDone?: () => void + ) { + Object.defineProperty(object, name, { + enumerable: false, + configurable: true, + get: () => { + init().then((r) => { + delete object[name] + object[name] = r + if (whenDone) { + whenDone() + } + }) + }, + }) + } + public static FixedLength(str: string, l: number) { str = Utils.EllipsesAfter(str, l) while (str.length < l) { @@ -1281,13 +1324,6 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be return d } - private static colorDiff( - c0: { r: number; g: number; b: number }, - c1: { r: number; g: number; b: number } - ) { - return Math.abs(c0.r - c1.r) + Math.abs(c0.g - c1.g) + Math.abs(c0.b - c1.b) - } - static toIdRecord(ts: T[]): Record { const result: Record = {} for (const t of ts) { @@ -1317,4 +1353,11 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be // If the element has a parent, repeat the process for the parent element return Utils.findParentWithScrolling(element.parentElement) } + + private static colorDiff( + c0: { r: number; g: number; b: number }, + c1: { r: number; g: number; b: number } + ) { + return Math.abs(c0.r - c1.r) + Math.abs(c0.g - c1.g) + Math.abs(c0.b - c1.b) + } } From ef93ad126f5c6b973fb2f66c368522ebdee07543 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Wed, 22 Mar 2023 16:25:24 +0100 Subject: [PATCH 4/4] Fix: gps-icon should turn into an arrow again --- Logic/Actors/GeoLocationHandler.ts | 9 +++++++++ assets/layers/gps_location/gps_location.json | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Logic/Actors/GeoLocationHandler.ts b/Logic/Actors/GeoLocationHandler.ts index a5f51959e1d..b458af29fe4 100644 --- a/Logic/Actors/GeoLocationHandler.ts +++ b/Logic/Actors/GeoLocationHandler.ts @@ -130,10 +130,14 @@ export default class GeoLocationHandler { private CopyGeolocationIntoMapstate() { const state = this._state + // For some weird reason, the 'Object.keys' method doesn't work for the 'location: GeolocationCoordinates'-object and will thus not copy all the properties when using {...location} + // As such, they are copied here + const keysToCopy = ["speed", "accuracy", "altitude", "altitudeAccuracy", "heading"] this.geolocationState.currentGPSLocation.addCallbackAndRun((location) => { if (location === undefined) { return } + const feature = { type: "Feature", properties: { @@ -147,6 +151,11 @@ export default class GeoLocationHandler { coordinates: [location.longitude, location.latitude], }, } + for (const key of keysToCopy) { + if (location[key] !== null) { + feature.properties[key] = location[key] + } + } state.currentUserLocation?.features?.setData([{ feature, freshness: new Date() }]) }) diff --git a/assets/layers/gps_location/gps_location.json b/assets/layers/gps_location/gps_location.json index 9d11abeab5b..edf09cfb831 100644 --- a/assets/layers/gps_location/gps_location.json +++ b/assets/layers/gps_location/gps_location.json @@ -1,6 +1,6 @@ { "id": "gps_location", - "description": "Meta layer showing the current location of the user. Add this to your theme and override the icon to change the appearance of the current location. The object will always have `id=gps` and will have _all_ the properties included in the [`Coordinates`-object](https://developer.mozilla.org/en-US/docs/Web/API/GeolocationCoordinates) returned by the browser.", + "description": "Meta layer showing the current location of the user. Add this to your theme and override the icon to change the appearance of the current location. The object will always have `id=gps` and will have _all_ the properties included in the [`Coordinates`-object](https://developer.mozilla.org/en-US/docs/Web/API/GeolocationCoordinates) (except latitude and longitude) returned by the browser, such as `speed`, `altitude`, `heading`, ....", "minzoom": 0, "source": { "osmTags": "id=gps", @@ -38,4 +38,4 @@ ] } ] -} \ No newline at end of file +}