forked from MapComplete/MapComplete
		
	Add feature which loads the selected element from overpass to update the tags to the latest version
This commit is contained in:
		
							parent
							
								
									d7277838e4
								
							
						
					
					
						commit
						c6b4ba43fb
					
				
					 4 changed files with 91 additions and 25 deletions
				
			
		
							
								
								
									
										54
									
								
								Logic/Actors/UpdateTagsFromOsmAPI.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								Logic/Actors/UpdateTagsFromOsmAPI.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | |||
| import {UIEventSource} from "../UIEventSource"; | ||||
| import {ElementStorage} from "../ElementStorage"; | ||||
| import {OsmObject, OsmObjectMeta} from "../Osm/OsmObject"; | ||||
| import SimpleMetaTagger from "../SimpleMetaTagger"; | ||||
| 
 | ||||
| export default class UpdateTagsFromOsmAPI { | ||||
| 
 | ||||
| 
 | ||||
|     public static readonly metaTagger = new SimpleMetaTagger( | ||||
|         ["_last_edit:contributor", | ||||
|             "_last_edit:contributor:uid", | ||||
|             "_last_edit:changeset", | ||||
|             "_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*/ | ||||
|         } | ||||
|     ) | ||||
| 
 | ||||
|     /*** | ||||
|      * This actor downloads the element from the OSM-API and updates the corresponding tags in the UI-updater. | ||||
|      */ | ||||
|     constructor(idToDownload: UIEventSource<string>, allElements: ElementStorage) { | ||||
| 
 | ||||
|         idToDownload.addCallbackAndRun(id => { | ||||
|             if (id === undefined) { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             OsmObject.DownloadObject(id, (element: OsmObject, meta: OsmObjectMeta) => { | ||||
|                 console.log("Updating element from OSM-API: ", element) | ||||
| 
 | ||||
| 
 | ||||
|                 const tags = element.tags; | ||||
|                 tags["_last_edit:contributor"] = meta["_last_edit:contributor"] | ||||
|                 tags["_last_edit:contributor:uid"] = meta["_last_edit:contributor:uid"] | ||||
|                 tags["_last_edit:changeset"] = meta["_last_edit:changeset"] | ||||
|                 tags["_last_edit:timestamp"] = meta["_last_edit:timestamp"].toLocaleString() | ||||
|                 tags["_version_number"] = meta._version_number | ||||
|                 if (!allElements.has(id)) { | ||||
|                     console.warn("Adding element by id") | ||||
|                     allElements.addElementById(id, new UIEventSource<any>(tags)) | ||||
|                 } else { | ||||
|                     // We merge
 | ||||
|                     console.warn("merging by OSM API UPDATE") | ||||
|                     allElements.addOrGetById(id, tags) | ||||
|                 } | ||||
|             }) | ||||
|         }) | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | @ -23,34 +23,43 @@ export class ElementStorage { | |||
|      */ | ||||
|     addOrGetElement(feature: any): UIEventSource<any> { | ||||
|         const elementId = feature.properties.id; | ||||
|         if (this._elements.has(elementId)) { | ||||
|             const es = this._elements.get(elementId); | ||||
|             if (es.data == feature.properties) { | ||||
|                 // Reference comparison gives the same object! we can just return the event source
 | ||||
|                 return es; | ||||
|             } | ||||
|         const newProperties = feature.properties; | ||||
| 
 | ||||
|             const keptKeys = es.data; | ||||
|             // The element already exists
 | ||||
|             // We add all the new keys to the old keys
 | ||||
|             let somethingChanged = false; | ||||
|             for (const k in feature.properties) { | ||||
|                 const v = feature.properties[k]; | ||||
|                 if (keptKeys[k] !== v) { | ||||
|                     keptKeys[k] = v; | ||||
|                     somethingChanged = true; | ||||
|                 } | ||||
|             } | ||||
|             if (somethingChanged) { | ||||
|                 es.ping(); | ||||
|             } | ||||
|         const es = this.addOrGetById(elementId, newProperties) | ||||
| 
 | ||||
|             return es; | ||||
|         } else { | ||||
|             const eventSource = new UIEventSource<any>(feature.properties, "tags of " + feature.properties.id); | ||||
|             this._elements.set(feature.properties.id, eventSource); | ||||
|         // At last, we overwrite the tag of the new feature to use the tags in the already existing event source
 | ||||
|         feature.properties = es.data | ||||
|         return es; | ||||
|     } | ||||
| 
 | ||||
|     addOrGetById(elementId: string, newProperties: any): UIEventSource<any> { | ||||
|         if (!this._elements.has(elementId)) { | ||||
|             const eventSource = new UIEventSource<any>(newProperties, "tags of " + elementId); | ||||
|             this._elements.set(elementId, eventSource); | ||||
|             return eventSource; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         const es = this._elements.get(elementId); | ||||
|         if (es.data == newProperties) { | ||||
|             // Reference comparison gives the same object! we can just return the event source
 | ||||
|             return es; | ||||
|         } | ||||
|         const keptKeys = es.data; | ||||
|         // The element already exists
 | ||||
|         // We use the new feature to overwrite all the properties in the already existing eventsource
 | ||||
|         let somethingChanged = false; | ||||
|         for (const k in newProperties) { | ||||
|             const v = newProperties[k]; | ||||
|             if (keptKeys[k] !== v) { | ||||
|                 keptKeys[k] = v; | ||||
|                 somethingChanged = true; | ||||
|             } | ||||
|         } | ||||
|         if (somethingChanged) { | ||||
|             es.ping(); | ||||
|         } | ||||
|         return es; | ||||
|     } | ||||
| 
 | ||||
|     getEventSourceById(elementId): UIEventSource<any> { | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ import {Utils} from "../Utils"; | |||
| import opening_hours from "opening_hours"; | ||||
| import {UIElement} from "../UI/UIElement"; | ||||
| import Combine from "../UI/Base/Combine"; | ||||
| import UpdateTagsFromOsmAPI from "./Actors/UpdateTagsFromOsmAPI"; | ||||
| 
 | ||||
| export default class SimpleMetaTagger { | ||||
|     public readonly keys: string[]; | ||||
|  | @ -330,7 +331,7 @@ export default class SimpleMetaTagger { | |||
| 
 | ||||
|         ]; | ||||
| 
 | ||||
|         for (const metatag of SimpleMetaTagger.metatags) { | ||||
|         for (const metatag of SimpleMetaTagger.metatags.concat(UpdateTagsFromOsmAPI.metaTagger)) { | ||||
|             subElements.push( | ||||
|                 new Combine([ | ||||
|                     "<h3>", metatag.keys.join(", "), "</h3>", | ||||
|  |  | |||
							
								
								
									
										2
									
								
								State.ts
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								State.ts
									
										
									
									
									
								
							|  | @ -18,6 +18,7 @@ import LayerConfig from "./Customizations/JSON/LayerConfig"; | |||
| import TitleHandler from "./Logic/Actors/TitleHandler"; | ||||
| import PendingChangesUploader from "./Logic/Actors/PendingChangesUploader"; | ||||
| import {Relation} from "./Logic/Osm/ExtractRelations"; | ||||
| import UpdateTagsFromOsmAPI from "./Logic/Actors/UpdateTagsFromOsmAPI"; | ||||
| 
 | ||||
| /** | ||||
|  * Contains the global state: a bunch of UI-event sources | ||||
|  | @ -252,6 +253,7 @@ export default class State { | |||
| 
 | ||||
|         new TitleHandler(this.layoutToUse, this.selectedElement, this.allElements); | ||||
| 
 | ||||
|         new UpdateTagsFromOsmAPI(this.selectedElement.map(el => el?.properties?.id), this.allElements) | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue