If an OSM-object does not exist anyore, ignore changes to this object. Fix #577

This commit is contained in:
Pieter Vander Vennet 2021-12-05 05:19:59 +01:00
parent fc70909005
commit 76c84b3972

View file

@ -33,7 +33,7 @@ export class Changes {
private readonly previouslyCreated: OsmObject[] = [] private readonly previouslyCreated: OsmObject[] = []
private readonly _leftRightSensitive: boolean; private readonly _leftRightSensitive: boolean;
private _state : { allElements: ElementStorage; historicalUserLocations: FeatureSource } private _state: { allElements: ElementStorage; historicalUserLocations: FeatureSource }
constructor(leftRightSensitive: boolean = false) { constructor(leftRightSensitive: boolean = false) {
this._leftRightSensitive = leftRightSensitive; this._leftRightSensitive = leftRightSensitive;
@ -120,13 +120,13 @@ export class Changes {
}) })
} }
private calculateDistanceToChanges(change: OsmChangeAction, changeDescriptions: ChangeDescription[]){ private calculateDistanceToChanges(change: OsmChangeAction, changeDescriptions: ChangeDescription[]) {
if (this._state === undefined) { if (this._state === undefined) {
// No state loaded -> we can't calculate... // No state loaded -> we can't calculate...
return; return;
} }
if(!change.trackStatistics){ if (!change.trackStatistics) {
// Probably irrelevant, such as a new helper node // Probably irrelevant, such as a new helper node
return; return;
} }
@ -139,7 +139,7 @@ export class Changes {
const diff = (now.getTime() - visitTime.getTime()) / 1000 const diff = (now.getTime() - visitTime.getTime()) / 1000
return diff < Constants.nearbyVisitTime; return diff < Constants.nearbyVisitTime;
}) })
if(recentLocationPoints.length === 0){ if (recentLocationPoints.length === 0) {
// Probably no GPS enabled/no fix // Probably no GPS enabled/no fix
return; return;
} }
@ -149,24 +149,24 @@ export class Changes {
// We walk every change and determine the closest distance possible // We walk every change and determine the closest distance possible
// Only if the change itself does _not_ contain any coordinates, we fall back and search the original feature in the state // Only if the change itself does _not_ contain any coordinates, we fall back and search the original feature in the state
const changedObjectCoordinates : [number, number][] = [] const changedObjectCoordinates: [number, number][] = []
const feature = this._state.allElements.ContainingFeatures.get(change.mainObjectId) const feature = this._state.allElements.ContainingFeatures.get(change.mainObjectId)
if(feature !== undefined){ if (feature !== undefined) {
changedObjectCoordinates.push(GeoOperations.centerpointCoordinates(feature)) changedObjectCoordinates.push(GeoOperations.centerpointCoordinates(feature))
} }
for (const changeDescription of changeDescriptions) { for (const changeDescription of changeDescriptions) {
const chng : {lat: number, lon: number} | {coordinates : [number,number][]} | {members} = changeDescription.changes const chng: { lat: number, lon: number } | { coordinates: [number, number][] } | { members } = changeDescription.changes
if(chng === undefined){ if (chng === undefined) {
continue continue
} }
if(chng["lat"] !== undefined){ if (chng["lat"] !== undefined) {
changedObjectCoordinates.push([chng["lat"],chng["lon"]]) changedObjectCoordinates.push([chng["lat"], chng["lon"]])
} }
if(chng["coordinates"] !== undefined){ if (chng["coordinates"] !== undefined) {
changedObjectCoordinates.push(...chng["coordinates"]) changedObjectCoordinates.push(...chng["coordinates"])
} }
} }
return Math.min(...changedObjectCoordinates.map(coor => return Math.min(...changedObjectCoordinates.map(coor =>
@ -194,8 +194,8 @@ export class Changes {
public useLocationHistory(state: { public useLocationHistory(state: {
allElements: ElementStorage, allElements: ElementStorage,
historicalUserLocations: FeatureSource historicalUserLocations: FeatureSource
}){ }) {
this._state= state this._state = state
} }
public registerIdRewrites(mappings: Map<string, string>): void { public registerIdRewrites(mappings: Map<string, string>): void {
@ -212,7 +212,13 @@ export class Changes {
private async flushSelectChanges(pending: ChangeDescription[]): Promise<boolean> { private async flushSelectChanges(pending: ChangeDescription[]): Promise<boolean> {
const self = this; const self = this;
const neededIds = Changes.GetNeededIds(pending) const neededIds = Changes.GetNeededIds(pending)
const osmObjects = await Promise.all(neededIds.map(id => OsmObject.DownloadObjectAsync(id)));
const osmObjects = Utils.NoNull(await Promise.all(neededIds.map(async id =>
OsmObject.DownloadObjectAsync(id).catch(e => {
console.error("Could not download OSM-object", id, " dropping it from the changes")
pending = pending.filter(ch => ch.type + "/" + ch.id !== id)
return undefined;
}))));
if (this._leftRightSensitive) { if (this._leftRightSensitive) {
osmObjects.forEach(obj => SimpleMetaTagger.removeBothTagging(obj.tags)) osmObjects.forEach(obj => SimpleMetaTagger.removeBothTagging(obj.tags))
@ -250,34 +256,34 @@ export class Changes {
let j = 0; let j = 0;
const maxDistances = Constants.distanceToChangeObjectBins const maxDistances = Constants.distanceToChangeObjectBins
for (let i = 0; i < maxDistances.length; i++){ for (let i = 0; i < maxDistances.length; i++) {
const maxDistance = maxDistances[i]; const maxDistance = maxDistances[i];
// distances is sorted in ascending order, so as soon as one is to big, all the resting elements will be bigger too // distances is sorted in ascending order, so as soon as one is to big, all the resting elements will be bigger too
while(j < distances.length && distances[j] < maxDistance){ while (j < distances.length && distances[j] < maxDistance) {
perBinCount[i] ++ perBinCount[i]++
j++ j++
} }
} }
const perBinMessage = Utils.NoNull(perBinCount.map((count, i) => { const perBinMessage = Utils.NoNull(perBinCount.map((count, i) => {
if(count === 0){ if (count === 0) {
return undefined return undefined
} }
const maxD =maxDistances[i] const maxD = maxDistances[i]
let key = `change_within_${maxD}m` let key = `change_within_${maxD}m`
if(maxD === Number.MAX_VALUE){ if (maxD === Number.MAX_VALUE) {
key = `change_over_${maxDistances[i - 1]}m` key = `change_over_${maxDistances[i - 1]}m`
} }
return { return {
key , key,
value: count, value: count,
aggregate:true aggregate: true
} }
})) }))
// This method is only called with changedescriptions for this theme // This method is only called with changedescriptions for this theme
const theme = pending[0].meta.theme const theme = pending[0].meta.theme
const metatags : ChangesetTag[] = [{ const metatags: ChangesetTag[] = [{
key: "comment", key: "comment",
value: "Adding data with #MapComplete for theme #" + theme value: "Adding data with #MapComplete for theme #" + theme
}, },