Add feature which loads the selected element from overpass to update the tags to the latest version

This commit is contained in:
pietervdvn 2021-04-21 01:26:13 +02:00
parent d7277838e4
commit c6b4ba43fb
4 changed files with 91 additions and 25 deletions

View 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)
}
})
})
}
}

View file

@ -23,19 +23,34 @@ export class ElementStorage {
*/ */
addOrGetElement(feature: any): UIEventSource<any> { addOrGetElement(feature: any): UIEventSource<any> {
const elementId = feature.properties.id; const elementId = feature.properties.id;
if (this._elements.has(elementId)) { const newProperties = feature.properties;
const es = this._elements.get(elementId);
if (es.data == feature.properties) { const es = this.addOrGetById(elementId, newProperties)
// Reference comparison gives the same object! we can just return the event source
// 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; 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; const keptKeys = es.data;
// The element already exists // The element already exists
// We add all the new keys to the old keys // We use the new feature to overwrite all the properties in the already existing eventsource
let somethingChanged = false; let somethingChanged = false;
for (const k in feature.properties) { for (const k in newProperties) {
const v = feature.properties[k]; const v = newProperties[k];
if (keptKeys[k] !== v) { if (keptKeys[k] !== v) {
keptKeys[k] = v; keptKeys[k] = v;
somethingChanged = true; somethingChanged = true;
@ -44,13 +59,7 @@ export class ElementStorage {
if (somethingChanged) { if (somethingChanged) {
es.ping(); es.ping();
} }
return es; return es;
} else {
const eventSource = new UIEventSource<any>(feature.properties, "tags of " + feature.properties.id);
this._elements.set(feature.properties.id, eventSource);
return eventSource;
}
} }
getEventSourceById(elementId): UIEventSource<any> { getEventSourceById(elementId): UIEventSource<any> {

View file

@ -7,6 +7,7 @@ import {Utils} from "../Utils";
import opening_hours from "opening_hours"; import opening_hours from "opening_hours";
import {UIElement} from "../UI/UIElement"; import {UIElement} from "../UI/UIElement";
import Combine from "../UI/Base/Combine"; import Combine from "../UI/Base/Combine";
import UpdateTagsFromOsmAPI from "./Actors/UpdateTagsFromOsmAPI";
export default class SimpleMetaTagger { export default class SimpleMetaTagger {
public readonly keys: string[]; 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( subElements.push(
new Combine([ new Combine([
"<h3>", metatag.keys.join(", "), "</h3>", "<h3>", metatag.keys.join(", "), "</h3>",

View file

@ -18,6 +18,7 @@ import LayerConfig from "./Customizations/JSON/LayerConfig";
import TitleHandler from "./Logic/Actors/TitleHandler"; import TitleHandler from "./Logic/Actors/TitleHandler";
import PendingChangesUploader from "./Logic/Actors/PendingChangesUploader"; import PendingChangesUploader from "./Logic/Actors/PendingChangesUploader";
import {Relation} from "./Logic/Osm/ExtractRelations"; import {Relation} from "./Logic/Osm/ExtractRelations";
import UpdateTagsFromOsmAPI from "./Logic/Actors/UpdateTagsFromOsmAPI";
/** /**
* Contains the global state: a bunch of UI-event sources * 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 TitleHandler(this.layoutToUse, this.selectedElement, this.allElements);
new UpdateTagsFromOsmAPI(this.selectedElement.map(el => el?.properties?.id), this.allElements)
} }