forked from MapComplete/MapComplete
More work on refactoring the changes handling
This commit is contained in:
parent
42391b4ff1
commit
b55f9a25c6
19 changed files with 181 additions and 105 deletions
|
@ -37,7 +37,7 @@ export default class ChangeTagAction extends OsmChangeAction {
|
|||
return {k: key.trim(), v: value.trim()};
|
||||
}
|
||||
|
||||
Perform(changes: Changes): ChangeDescription [] {
|
||||
CreateChangeDescriptions(changes: Changes): ChangeDescription [] {
|
||||
const changedTags: { k: string, v: string }[] = this._tagsFilter.asChange(this._currentTags).map(ChangeTagAction.checkChange)
|
||||
const typeId = this._elementId.split("/")
|
||||
const type = typeId[0]
|
||||
|
|
|
@ -4,23 +4,27 @@ import {Changes} from "../Changes";
|
|||
import {ChangeDescription} from "./ChangeDescription";
|
||||
import {And} from "../../Tags/And";
|
||||
|
||||
export default class CreateNewNodeAction implements OsmChangeAction {
|
||||
export default class CreateNewNodeAction extends OsmChangeAction {
|
||||
|
||||
private readonly _basicTags: Tag[];
|
||||
private readonly _lat: number;
|
||||
private readonly _lon: number;
|
||||
|
||||
public newElementId : string = undefined
|
||||
|
||||
constructor(basicTags: Tag[], lat: number, lon: number) {
|
||||
super()
|
||||
this._basicTags = basicTags;
|
||||
this._lat = lat;
|
||||
this._lon = lon;
|
||||
}
|
||||
|
||||
Perform(changes: Changes): ChangeDescription[] {
|
||||
CreateChangeDescriptions(changes: Changes): ChangeDescription[] {
|
||||
const id = changes.getNewID()
|
||||
const properties = {
|
||||
id: "node/" + id
|
||||
}
|
||||
this.newElementId = "node/"+id
|
||||
for (const kv of this._basicTags) {
|
||||
if (typeof kv.value !== "string") {
|
||||
throw "Invalid value: don't use a regex in a preset"
|
||||
|
|
|
@ -7,10 +7,17 @@ import {ChangeDescription} from "./ChangeDescription";
|
|||
|
||||
export default abstract class OsmChangeAction {
|
||||
|
||||
private isUsed = false
|
||||
|
||||
public Perform(changes: Changes) {
|
||||
if (this.isUsed) {
|
||||
throw "This ChangeAction is already used: " + this.constructor.name
|
||||
}
|
||||
this.isUsed = true;
|
||||
return this.CreateChangeDescriptions(changes)
|
||||
}
|
||||
|
||||
protected abstract CreateChangeDescriptions(changes: Changes): ChangeDescription[]
|
||||
|
||||
|
||||
public abstract Perform(changes: Changes): ChangeDescription[]
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -12,7 +12,7 @@ export default class RelationSplitlHandler extends OsmChangeAction{
|
|||
super()
|
||||
}
|
||||
|
||||
Perform(changes: Changes): ChangeDescription[] {
|
||||
CreateChangeDescriptions(changes: Changes): ChangeDescription[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ export default class SplitAction extends OsmChangeAction {
|
|||
return wayParts.filter(wp => wp.length > 0)
|
||||
}
|
||||
|
||||
Perform(changes: Changes): ChangeDescription[] {
|
||||
CreateChangeDescriptions(changes: Changes): ChangeDescription[] {
|
||||
const splitPoints = this._splitPoints
|
||||
// We mark the new split points with a new id
|
||||
console.log(splitPoints)
|
||||
|
@ -72,7 +72,6 @@ export default class SplitAction extends OsmChangeAction {
|
|||
|
||||
// Next up is creating actual parts from this
|
||||
const wayParts: SplitInfo[][] = SplitAction.SegmentSplitInfo(splitInfo);
|
||||
console.log("WayParts", wayParts, "by", splitInfo)
|
||||
// Allright! At this point, we have our new ways!
|
||||
// Which one is the longest of them (and can keep the id)?
|
||||
|
||||
|
@ -144,7 +143,7 @@ console.log("WayParts", wayParts, "by", splitInfo)
|
|||
|
||||
// At last, we still have to check that we aren't part of a relation...
|
||||
// At least, the order of the ways is identical, so we can keep the same roles
|
||||
changeDescription.push(...new RelationSplitlHandler(partOf, newWayIds, originalNodes).Perform(changes))
|
||||
changeDescription.push(...new RelationSplitlHandler(partOf, newWayIds, originalNodes).CreateChangeDescriptions(changes))
|
||||
|
||||
// And we have our objects!
|
||||
// Time to upload
|
||||
|
|
|
@ -4,7 +4,6 @@ import {UIEventSource} from "../UIEventSource";
|
|||
import Constants from "../../Models/Constants";
|
||||
import OsmChangeAction from "./Actions/OsmChangeAction";
|
||||
import {ChangeDescription} from "./Actions/ChangeDescription";
|
||||
import {LocalStorageSource} from "../Web/LocalStorageSource";
|
||||
import {Utils} from "../../Utils";
|
||||
|
||||
/**
|
||||
|
@ -23,25 +22,23 @@ export class Changes {
|
|||
|
||||
public readonly pendingChanges = new UIEventSource<ChangeDescription[]>([]) // LocalStorageSource.GetParsed<ChangeDescription[]>("pending-changes", [])
|
||||
private readonly isUploading = new UIEventSource(false);
|
||||
|
||||
private readonly previouslyCreated : OsmObject[] = []
|
||||
|
||||
constructor() {
|
||||
this.isUploading.addCallbackAndRun(u => {
|
||||
if (u) {
|
||||
console.trace("Uploading set!")
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
public static createChangesetFor(csId: string,
|
||||
private static createChangesetFor(csId: string,
|
||||
allChanges: {
|
||||
modifiedObjects?: OsmObject[],
|
||||
newElements?: OsmObject[],
|
||||
deletedElements?: OsmObject[]
|
||||
modifiedObjects: OsmObject[],
|
||||
newObjects: OsmObject[],
|
||||
deletedObjects: OsmObject[]
|
||||
}): string {
|
||||
|
||||
const changedElements = allChanges.modifiedObjects ?? []
|
||||
const newElements = allChanges.newElements ?? []
|
||||
const deletedElements = allChanges.deletedElements ?? []
|
||||
const newElements = allChanges.newObjects ?? []
|
||||
const deletedElements = allChanges.deletedObjects ?? []
|
||||
|
||||
let changes = `<osmChange version='0.6' generator='Mapcomplete ${Constants.vNumber}'>`;
|
||||
if (newElements.length > 0) {
|
||||
|
@ -73,7 +70,7 @@ export class Changes {
|
|||
.map(c => c.type + "/" + c.id))
|
||||
}
|
||||
|
||||
private static CreateChangesetObjects(changes: ChangeDescription[], downloadedOsmObjects: OsmObject[]): {
|
||||
private CreateChangesetObjects(changes: ChangeDescription[], downloadedOsmObjects: OsmObject[]): {
|
||||
newObjects: OsmObject[],
|
||||
modifiedObjects: OsmObject[]
|
||||
deletedObjects: OsmObject[]
|
||||
|
@ -87,12 +84,21 @@ export class Changes {
|
|||
states.set(o.type + "/" + o.id, "unchanged")
|
||||
}
|
||||
|
||||
for (const o of this.previouslyCreated) {
|
||||
objects.set(o.type + "/" + o.id, o)
|
||||
states.set(o.type + "/" + o.id, "unchanged")
|
||||
}
|
||||
|
||||
let changed = false;
|
||||
for (const change of changes) {
|
||||
const id = change.type + "/" + change.id
|
||||
if (!objects.has(id)) {
|
||||
if(change.id >= 0){
|
||||
throw "Did not get an object that should be known: "+id
|
||||
}
|
||||
// This is a new object that should be created
|
||||
states.set(id, "created")
|
||||
console.log("Creating object for changeDescription", change)
|
||||
let osmObj: OsmObject = undefined;
|
||||
switch (change.type) {
|
||||
case "node":
|
||||
|
@ -116,6 +122,7 @@ export class Changes {
|
|||
throw "Hmm? This is a bug"
|
||||
}
|
||||
objects.set(id, osmObj)
|
||||
this.previouslyCreated.push(osmObj)
|
||||
}
|
||||
|
||||
const state = states.get(id)
|
||||
|
@ -195,8 +202,8 @@ export class Changes {
|
|||
newObjects: [],
|
||||
modifiedObjects: [],
|
||||
deletedObjects: []
|
||||
|
||||
}
|
||||
|
||||
objects.forEach((v, id) => {
|
||||
|
||||
const state = states.get(id)
|
||||
|
@ -228,20 +235,18 @@ export class Changes {
|
|||
*/
|
||||
public flushChanges(flushreason: string = undefined) {
|
||||
if (this.pendingChanges.data.length === 0) {
|
||||
console.log("No pending changes")
|
||||
return;
|
||||
}
|
||||
if (flushreason !== undefined) {
|
||||
console.log(flushreason)
|
||||
}
|
||||
|
||||
|
||||
if (this.isUploading.data) {
|
||||
console.log("Is uploading... Abort")
|
||||
console.log("Is already uploading... Abort")
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this.isUploading.setData(true)
|
||||
|
||||
console.log("Beginning upload...");
|
||||
|
||||
console.log("Beginning upload... "+flushreason ?? "");
|
||||
// At last, we build the changeset and upload
|
||||
const self = this;
|
||||
const pending = self.pendingChanges.data;
|
||||
|
@ -249,8 +254,12 @@ export class Changes {
|
|||
console.log("Needed ids", neededIds)
|
||||
OsmObject.DownloadAll(neededIds, true).addCallbackAndRunD(osmObjects => {
|
||||
console.log("Got the fresh objects!", osmObjects, "pending: ", pending)
|
||||
const changes = Changes.CreateChangesetObjects(pending, osmObjects)
|
||||
console.log("Changes", changes)
|
||||
const changes: {
|
||||
newObjects: OsmObject[],
|
||||
modifiedObjects: OsmObject[]
|
||||
deletedObjects: OsmObject[]
|
||||
|
||||
} = self.CreateChangesetObjects(pending, osmObjects)
|
||||
if (changes.newObjects.length + changes.deletedObjects.length + changes.modifiedObjects.length === 0) {
|
||||
console.log("No changes to be made")
|
||||
this.pendingChanges.setData([])
|
||||
|
@ -262,11 +271,8 @@ export class Changes {
|
|||
State.state.osmConnection.UploadChangeset(
|
||||
State.state.layoutToUse.data,
|
||||
State.state.allElements,
|
||||
(csId) => {
|
||||
return Changes.createChangesetFor(csId, changes);
|
||||
},
|
||||
(csId) => Changes.createChangesetFor(csId, changes),
|
||||
() => {
|
||||
// When done
|
||||
console.log("Upload successfull!")
|
||||
self.pendingChanges.setData([]);
|
||||
self.isUploading.setData(false)
|
||||
|
|
|
@ -23,7 +23,7 @@ export abstract class OsmObject {
|
|||
this.id = id;
|
||||
this.type = type;
|
||||
this.tags = {
|
||||
id: id
|
||||
id: `${this.type}/${id}`
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,9 @@ export abstract class OsmObject {
|
|||
const splitted = id.split("/");
|
||||
const type = splitted[0];
|
||||
const idN = Number(splitted[1]);
|
||||
if(idN <0){
|
||||
return;
|
||||
}
|
||||
|
||||
OsmObject.objectCache.set(id, src);
|
||||
const newContinuation = (element: OsmObject) => {
|
||||
|
@ -69,7 +72,7 @@ export abstract class OsmObject {
|
|||
new OsmRelation(idN).Download(newContinuation);
|
||||
break;
|
||||
default:
|
||||
throw "Invalid road type:" + type;
|
||||
throw "Invalid object type:" + type + id;
|
||||
|
||||
}
|
||||
return src;
|
||||
|
@ -105,7 +108,7 @@ export abstract class OsmObject {
|
|||
if (OsmObject.referencingRelationsCache.has(id)) {
|
||||
return OsmObject.referencingRelationsCache.get(id);
|
||||
}
|
||||
const relsSrc = new UIEventSource<OsmRelation[]>([])
|
||||
const relsSrc = new UIEventSource<OsmRelation[]>(undefined)
|
||||
OsmObject.referencingRelationsCache.set(id, relsSrc);
|
||||
Utils.downloadJson(`${OsmObject.backendURL}api/0.6/${id}/relations`)
|
||||
.then(data => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue