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> {
|
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) {
|
|
||||||
// Reference comparison gives the same object! we can just return the event source
|
|
||||||
return es;
|
|
||||||
}
|
|
||||||
|
|
||||||
const keptKeys = es.data;
|
const es = this.addOrGetById(elementId, newProperties)
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
return es;
|
// At last, we overwrite the tag of the new feature to use the tags in the already existing event source
|
||||||
} else {
|
feature.properties = es.data
|
||||||
const eventSource = new UIEventSource<any>(feature.properties, "tags of " + feature.properties.id);
|
return es;
|
||||||
this._elements.set(feature.properties.id, eventSource);
|
}
|
||||||
|
|
||||||
|
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;
|
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> {
|
getEventSourceById(elementId): UIEventSource<any> {
|
||||||
|
|
|
@ -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>",
|
||||||
|
|
2
State.ts
2
State.ts
|
@ -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)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue