forked from MapComplete/MapComplete
		
	Add names to feature sources, fix that old, cached geometries get changed when a newer version is loaded
This commit is contained in:
		
							parent
							
								
									6234d26bac
								
							
						
					
					
						commit
						141d4db028
					
				
					 14 changed files with 60 additions and 43 deletions
				
			
		|  | @ -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; | ||||
|             } | ||||
|  | @ -129,7 +131,7 @@ export default class UpdateFromOverpass implements FeatureSource { | |||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if(this.timeout.data > 0){ | ||||
|         if (this.timeout.data > 0) { | ||||
|             console.log("Still in timeout - not updating") | ||||
|             return; | ||||
|         } | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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){ | ||||
|  |  | |||
|  | @ -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<boolean>, layerDef: LayerConfig }[]>, | ||||
|                 updater: FeatureSource, | ||||
|                 layout: UIEventSource<LayoutConfig>, | ||||
|  |  | |||
|  | @ -2,4 +2,8 @@ import {UIEventSource} from "../UIEventSource"; | |||
| 
 | ||||
| export default interface FeatureSource { | ||||
|     features: UIEventSource<{feature: any, freshness: Date}[]>; | ||||
|     /** | ||||
|      * Mainly used for debuging | ||||
|      */ | ||||
|     name: string; | ||||
| } | ||||
|  | @ -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; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  |  | |||
|  | @ -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<boolean>, | ||||
|                     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); | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<string> = new Set<string>() | ||||
| 
 | ||||
|     constructor(locationControl: UIEventSource<Loc>, | ||||
|  | @ -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,16 +174,16 @@ 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); | ||||
|             console.debug("Downloaded " + newFeatures.length + " new features and " + skipped + " already seen features from " + url); | ||||
| 
 | ||||
|             if(newFeatures.length == 0){ | ||||
|             if (newFeatures.length == 0) { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<LayoutConfig>) { | ||||
|         this.features = source.features; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<LayoutConfig>) { | ||||
|         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) | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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)) { | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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){ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue