From 141d4db0282ff3041dc2ebbe1a28b42c5e21b5de Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 23 Apr 2021 12:55:38 +0200 Subject: [PATCH] Add names to feature sources, fix that old, cached geometries get changed when a newer version is loaded --- Logic/Actors/UpdateFromOverpass.ts | 8 +++--- Logic/Actors/UpdateTagsFromOsmAPI.ts | 4 +-- .../FeatureDuplicatorPerLayer.ts | 6 ++--- Logic/FeatureSource/FeaturePipeline.ts | 2 ++ Logic/FeatureSource/FeatureSource.ts | 4 +++ Logic/FeatureSource/FeatureSourceMerger.ts | 18 +++++++------ Logic/FeatureSource/FilteringFeatureSource.ts | 5 +--- Logic/FeatureSource/GeoJsonSource.ts | 25 ++++++++----------- Logic/FeatureSource/LocalStorageSaver.ts | 2 ++ Logic/FeatureSource/LocalStorageSource.ts | 12 +++++++-- .../FeatureSource/MetaTaggingFeatureSource.ts | 5 +++- .../FeatureSource/RegisteringFeatureSource.ts | 5 ++-- Logic/FeatureSource/RememberingSource.ts | 5 +++- .../WayHandlingApplyingFeatureSource.ts | 2 +- 14 files changed, 60 insertions(+), 43 deletions(-) diff --git a/Logic/Actors/UpdateFromOverpass.ts b/Logic/Actors/UpdateFromOverpass.ts index 370da70..77c9ab7 100644 --- a/Logic/Actors/UpdateFromOverpass.ts +++ b/Logic/Actors/UpdateFromOverpass.ts @@ -11,6 +11,8 @@ import {TagsFilter} from "../Tags/TagsFilter"; export default class UpdateFromOverpass implements FeatureSource { + public readonly name = "UpdateFromOverpass" + /** * The last loaded features of the geojson */ @@ -86,7 +88,7 @@ export default class UpdateFromOverpass implements FeatureSource { if (layer.doNotDownload) { continue; } - if(layer.source.geojsonSource !== undefined){ + if (layer.source.geojsonSource !== undefined) { // Not our responsibility to download this layer! continue; } @@ -128,8 +130,8 @@ export default class UpdateFromOverpass implements FeatureSource { console.log("Still running a query, not updating"); return; } - - if(this.timeout.data > 0){ + + if (this.timeout.data > 0) { console.log("Still in timeout - not updating") return; } diff --git a/Logic/Actors/UpdateTagsFromOsmAPI.ts b/Logic/Actors/UpdateTagsFromOsmAPI.ts index cdf0863..f9ed6a0 100644 --- a/Logic/Actors/UpdateTagsFromOsmAPI.ts +++ b/Logic/Actors/UpdateTagsFromOsmAPI.ts @@ -13,7 +13,7 @@ export default class UpdateTagsFromOsmAPI { "_last_edit:timestamp", "_version_number"], "Information about the last edit of this object. \n\nIMPORTANT: this data is _only_ loaded when the popup is added. This means it should _not_ be used to render icons!", - (feature: any, index: number, freshness: Date) => {/*Do nothing - this is only added for documentation reasons*/ + () => {/*Do nothing - this is only added for documentation reasons*/ } ) @@ -28,7 +28,7 @@ export default class UpdateTagsFromOsmAPI { } OsmObject.DownloadObject(id, (element: OsmObject, meta: OsmObjectMeta) => { - console.log("Updating element from OSM-API: ", element) + console.debug("Updating tags from the OSM-API: ", element) const tags = element.tags; diff --git a/Logic/FeatureSource/FeatureDuplicatorPerLayer.ts b/Logic/FeatureSource/FeatureDuplicatorPerLayer.ts index 5ca6870..0771314 100644 --- a/Logic/FeatureSource/FeatureDuplicatorPerLayer.ts +++ b/Logic/FeatureSource/FeatureDuplicatorPerLayer.ts @@ -11,12 +11,10 @@ import LayerConfig from "../../Customizations/JSON/LayerConfig"; export default class FeatureDuplicatorPerLayer implements FeatureSource { public readonly features: UIEventSource<{ feature: any; freshness: Date }[]>; - - public static GetMatchingLayerId(){ - - } + public readonly name; constructor(layers: UIEventSource<{ layerDef: LayerConfig }[]>, upstream: FeatureSource) { + this.name = "FeatureDuplicator of "+upstream.name; this.features = upstream.features.map(features => { const newFeatures: { feature: any, freshness: Date }[] = []; if(features === undefined){ diff --git a/Logic/FeatureSource/FeaturePipeline.ts b/Logic/FeatureSource/FeaturePipeline.ts index 81fe3e2..bae68a8 100644 --- a/Logic/FeatureSource/FeaturePipeline.ts +++ b/Logic/FeatureSource/FeaturePipeline.ts @@ -18,6 +18,8 @@ export default class FeaturePipeline implements FeatureSource { public features: UIEventSource<{ feature: any; freshness: Date }[]>; + public readonly name = "FeaturePipeline" + constructor(flayers: UIEventSource<{ isDisplayed: UIEventSource, layerDef: LayerConfig }[]>, updater: FeatureSource, layout: UIEventSource, diff --git a/Logic/FeatureSource/FeatureSource.ts b/Logic/FeatureSource/FeatureSource.ts index 16475b9..ba56827 100644 --- a/Logic/FeatureSource/FeatureSource.ts +++ b/Logic/FeatureSource/FeatureSource.ts @@ -2,4 +2,8 @@ import {UIEventSource} from "../UIEventSource"; export default interface FeatureSource { features: UIEventSource<{feature: any, freshness: Date}[]>; + /** + * Mainly used for debuging + */ + name: string; } \ No newline at end of file diff --git a/Logic/FeatureSource/FeatureSourceMerger.ts b/Logic/FeatureSource/FeatureSourceMerger.ts index 717c18b..76c4c52 100644 --- a/Logic/FeatureSource/FeatureSourceMerger.ts +++ b/Logic/FeatureSource/FeatureSourceMerger.ts @@ -3,13 +3,15 @@ import {UIEventSource} from "../UIEventSource"; export default class FeatureSourceMerger implements FeatureSource { - public features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{feature: any; freshness: Date}[]>([]); + public features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]); + public readonly name; private readonly _sources: FeatureSource[]; constructor(sources: FeatureSource[]) { this._sources = sources; + this.name = "SourceMerger of (" + sources.map(s => s.name).join(", ") + ")" const self = this; - for (let i = 0; i < sources.length; i++){ + for (let i = 0; i < sources.length; i++) { let source = sources[i]; source.features.addCallback(() => { self.Update(); @@ -21,17 +23,17 @@ export default class FeatureSourceMerger implements FeatureSource { private Update() { let all = {}; // Mapping 'id' -> {feature, freshness} for (const source of this._sources) { - if(source?.features?.data === undefined){ + if (source?.features?.data === undefined) { continue; } for (const f of source.features.data) { - const id = f.feature.properties.id+f.feature.geometry.type+f.feature._matching_layer_id; + const id = f.feature.properties.id; const oldV = all[id]; - if(oldV === undefined){ + if (oldV === undefined) { all[id] = f; - }else{ - if(oldV.freshness < f.freshness){ - all[id]=f; + } else { + if (oldV.freshness < f.freshness) { + all[id] = f; } } } diff --git a/Logic/FeatureSource/FilteringFeatureSource.ts b/Logic/FeatureSource/FilteringFeatureSource.ts index a1e25e2..4023465 100644 --- a/Logic/FeatureSource/FilteringFeatureSource.ts +++ b/Logic/FeatureSource/FilteringFeatureSource.ts @@ -5,7 +5,7 @@ import Loc from "../../Models/Loc"; export default class FilteringFeatureSource implements FeatureSource { public features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]); - +public readonly name = "FilteringFeatureSource" constructor(layers: UIEventSource<{ isDisplayed: UIEventSource, layerDef: LayerConfig @@ -23,7 +23,6 @@ export default class FilteringFeatureSource implements FeatureSource { layerDict[layer.layerDef.id] = layer; } - console.log("Updating the filtering layer, input ", upstream.features.data.length, "features") const features: { feature: any, freshness: Date }[] = upstream.features.data; @@ -65,8 +64,6 @@ export default class FilteringFeatureSource implements FeatureSource { return false; }); - console.log("Updating the filtering layer, output ", newFeatures.length, "features") - self.features.setData(newFeatures); } diff --git a/Logic/FeatureSource/GeoJsonSource.ts b/Logic/FeatureSource/GeoJsonSource.ts index 1000f66..e6bdfcb 100644 --- a/Logic/FeatureSource/GeoJsonSource.ts +++ b/Logic/FeatureSource/GeoJsonSource.ts @@ -14,12 +14,10 @@ import LayerConfig from "../../Customizations/JSON/LayerConfig"; */ export default class GeoJsonSource implements FeatureSource { - features: UIEventSource<{ feature: any; freshness: Date }[]>; - + public readonly features: UIEventSource<{ feature: any; freshness: Date }[]>; + public readonly name; private readonly onFail: ((errorMsg: any, url: string) => void) = undefined; - private readonly layerId: string; - private readonly seenids: Set = new Set() constructor(locationControl: UIEventSource, @@ -27,6 +25,7 @@ export default class GeoJsonSource implements FeatureSource { onFail?: ((errorMsg: any) => void)) { this.layerId = flayer.layerDef.id; let url = flayer.layerDef.source.geojsonSource; + this.name = "GeoJsonSource of " + url; const zoomLevel = flayer.layerDef.source.geojsonZoomLevel; this.features = new UIEventSource<{ feature: any; freshness: Date }[]>([]) @@ -110,8 +109,6 @@ export default class GeoJsonSource implements FeatureSource { flayersPerSource.get(url).push(flayer) } - console.log("SOURCES", flayersPerSource) - const sources: GeoJsonSource[] = [] flayersPerSource.forEach((flayers, key) => { @@ -153,13 +150,11 @@ export default class GeoJsonSource implements FeatureSource { const self = this; $.getJSON(url, function (json, status) { if (status !== "success") { - console.log("Fetching geojson failed failed") self.onFail(status, url); return; } if (json.elements === [] && json.remarks.indexOf("runtime error") > 0) { - console.log("Timeout or other runtime error"); self.onFail("Runtime error (timeout)", url) return; } @@ -179,19 +174,19 @@ export default class GeoJsonSource implements FeatureSource { } self.seenids.add(feature.properties.id) - let freshness : Date = time; - if(feature["_timestamp"] !== undefined){ + let freshness: Date = time; + if (feature["_timestamp"] !== undefined) { freshness = new Date(feature["_timestamp"]) } - + newFeatures.push({feature: feature, freshness: freshness}) } - console.log("Downloaded "+newFeatures.length+" new features and "+skipped+" already seen features from "+ url); - - if(newFeatures.length == 0){ + console.debug("Downloaded " + newFeatures.length + " new features and " + skipped + " already seen features from " + url); + + if (newFeatures.length == 0) { return; } - + eventSource.setData(eventSource.data.concat(newFeatures)) }).fail(msg => self.onFail(msg, url)) diff --git a/Logic/FeatureSource/LocalStorageSaver.ts b/Logic/FeatureSource/LocalStorageSaver.ts index 5a66cef..e459424 100644 --- a/Logic/FeatureSource/LocalStorageSaver.ts +++ b/Logic/FeatureSource/LocalStorageSaver.ts @@ -11,6 +11,8 @@ export default class LocalStorageSaver implements FeatureSource { public static readonly storageKey: string = "cached-features"; public readonly features: UIEventSource<{ feature: any; freshness: Date }[]>; + public readonly name = "LocalStorageSaver"; + constructor(source: FeatureSource, layout: UIEventSource) { this.features = source.features; diff --git a/Logic/FeatureSource/LocalStorageSource.ts b/Logic/FeatureSource/LocalStorageSource.ts index 39d96a6..0723a2f 100644 --- a/Logic/FeatureSource/LocalStorageSource.ts +++ b/Logic/FeatureSource/LocalStorageSource.ts @@ -5,6 +5,7 @@ import LayoutConfig from "../../Customizations/JSON/LayoutConfig"; export default class LocalStorageSource implements FeatureSource { public features: UIEventSource<{ feature: any; freshness: Date }[]>; + public readonly name = "LocalStorageSource"; constructor(layout: UIEventSource) { this.features = new UIEventSource<{ feature: any; freshness: Date }[]>([]) @@ -17,8 +18,15 @@ export default class LocalStorageSource implements FeatureSource { if (fromStorage == null) { return; } - const loaded = JSON.parse(fromStorage); - this.features.setData(loaded); + const loaded : { feature: any; freshness: Date | string }[]= + JSON.parse(fromStorage); + + const parsed : { feature: any; freshness: Date }[]= loaded.map(ff => ({ + feature: ff.feature, + freshness : typeof ff.freshness == "string" ? new Date(ff.freshness) : ff.freshness + })) + + this.features.setData(parsed); console.log("Loaded ", loaded.length, " features from localstorage as cache") } catch (e) { console.log("Could not load features from localStorage:", e) diff --git a/Logic/FeatureSource/MetaTaggingFeatureSource.ts b/Logic/FeatureSource/MetaTaggingFeatureSource.ts index 3cc1c28..5beefa9 100644 --- a/Logic/FeatureSource/MetaTaggingFeatureSource.ts +++ b/Logic/FeatureSource/MetaTaggingFeatureSource.ts @@ -6,10 +6,13 @@ import MetaTagging from "../MetaTagging"; import ExtractRelations from "../Osm/ExtractRelations"; export default class MetaTaggingFeatureSource implements FeatureSource { - features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{feature: any; freshness: Date}[]>(undefined); + public readonly features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{feature: any; freshness: Date}[]>(undefined); + + public readonly name; constructor(source: FeatureSource) { const self = this; + this.name = "MetaTagging of "+source.name source.features.addCallbackAndRun((featuresFreshness: { feature: any, freshness: Date }[]) => { if (featuresFreshness === undefined) { return; diff --git a/Logic/FeatureSource/RegisteringFeatureSource.ts b/Logic/FeatureSource/RegisteringFeatureSource.ts index 9e5d19d..48fc315 100644 --- a/Logic/FeatureSource/RegisteringFeatureSource.ts +++ b/Logic/FeatureSource/RegisteringFeatureSource.ts @@ -3,10 +3,11 @@ import {UIEventSource} from "../UIEventSource"; import State from "../../State"; export default class RegisteringFeatureSource implements FeatureSource { - features: UIEventSource<{ feature: any; freshness: Date }[]>; - +public readonly features: UIEventSource<{ feature: any; freshness: Date }[]>; +public readonly name; constructor(source: FeatureSource) { this.features = source.features; + this.name = "RegisteringSource of "+source.name; this.features.addCallbackAndRun(features => { for (const feature of features ?? []) { if (!State.state.allElements.has(feature.feature.properties.id)) { diff --git a/Logic/FeatureSource/RememberingSource.ts b/Logic/FeatureSource/RememberingSource.ts index 7f95b8f..b77e613 100644 --- a/Logic/FeatureSource/RememberingSource.ts +++ b/Logic/FeatureSource/RememberingSource.ts @@ -5,10 +5,13 @@ import FeatureSource from "./FeatureSource"; import {UIEventSource} from "../UIEventSource"; export default class RememberingSource implements FeatureSource { - features: UIEventSource<{ feature: any, freshness: Date }[]>; + public readonly features: UIEventSource<{ feature: any, freshness: Date }[]>; + public readonly name; + constructor(source: FeatureSource) { const self = this; + this.name = "RememberingSource of "+source.name; const empty = []; this.features = source.features.map(features => { const oldFeatures = self.features?.data ?? empty; diff --git a/Logic/FeatureSource/WayHandlingApplyingFeatureSource.ts b/Logic/FeatureSource/WayHandlingApplyingFeatureSource.ts index 95b9ede..fcce1a4 100644 --- a/Logic/FeatureSource/WayHandlingApplyingFeatureSource.ts +++ b/Logic/FeatureSource/WayHandlingApplyingFeatureSource.ts @@ -51,7 +51,7 @@ export default class WayHandlingApplyingFeatureSource implements FeatureSource { // Create the copy const centerPoint = GeoOperations.centerpoint(feat); - centerPoint._matching_layer_id = feat._matching_layer_id; + centerPoint["_matching_layer_id"] = feat._matching_layer_id; newFeatures.push({feature: centerPoint, freshness: f.freshness}); if(layer.wayHandling === LayerConfig.WAYHANDLING_CENTER_AND_WAY){