diff --git a/js/id/graph/graph.js b/js/id/graph/graph.js index d35f616a0..2705fd029 100644 --- a/js/id/graph/graph.js +++ b/js/id/graph/graph.js @@ -8,15 +8,12 @@ iD.Graph = function(other, mutable) { this.rebase(other.base(), other.entities); } else { - if (_.isArray(other)) { - this.entities = Object.create({}); - for (var i = 0; i < other.length; i++) { - this.entities[other[i].id] = other[i]; - } - } else { - this.entities = Object.create(other || {}); - } + this.entities = other || Object.create({}); this._parentWays = Object.create({}); + + for (var i in this.entities) { + this._updateCalculated(undefined, this.entities[i]); + } } this.transients = {}; @@ -119,19 +116,53 @@ iD.Graph.prototype = { rebase: function(base, entities) { }, + _updateCalculated: function(oldentity, entity) { + + var type = entity && entity.type || oldentity && oldentity.type, + removed, added, parentWays, i; + + + if (type === 'way') { + + // Update parentWays + if (oldentity && entity) { + removed = _.difference(oldentity.nodes, entity.nodes); + added = _.difference(entity.nodes, oldentity.nodes); + } else if (oldentity) { + removed = oldentity.nodes; + added = []; + } else if (entity) { + removed = []; + added = entity.nodes; + } + for (i = 0; i < removed.length; i++) { + this._parentWays[removed[i]] = _.without(this._parentWays[removed[i]], oldentity.id); + } + for (i = 0; i < added.length; i++) { + parentWays = _.without(this._parentWays[added[i]], entity.id); + parentWays.push(entity.id); + this._parentWays[added[i]] = parentWays; + } + } else if (type === 'node') { + + } else if (type === 'relation') { + + // TODO: iterate over members + + } + }, + replace: function(entity) { return this.update(function () { + this._updateCalculated(this.entities[entity.id], entity); this.entities[entity.id] = entity; }); }, remove: function(entity) { return this.update(function () { - if (entity.created()) { - delete this.entities[entity.id]; - } else { - this.entities[entity.id] = undefined; - } + this._updateCalculated(entity, undefined); + this.entities[entity.id] = undefined; }); }, diff --git a/js/id/graph/history.js b/js/id/graph/history.js index e5bfd353f..95e499ef2 100644 --- a/js/id/graph/history.js +++ b/js/id/graph/history.js @@ -30,12 +30,13 @@ iD.History = function() { }, merge: function (graph) { - var base = stack[0].graph.base(), - mergee = graph.base(); + var base = stack[0].graph.base(); - for (var i in base) { - _.defaults(base[i], mergee[i]); + _.defaults(base.entities, graph.entities); + for (var i in graph.entities) { + base.parentWays[i] = _.unique((base.parentWays[id] || []).concat(graph._parentWays[i] || [])); } + _.defaults(base.parentWays, graph._parentWays); for (i = 1; i < stack.length; i++) { stack[i].graph.rebase(base); diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index e27fdc5b9..bc4ca8e03 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -123,7 +123,7 @@ iD.Map = function() { function connectionLoad(err, result) { history.merge(result); - redraw(Object.keys(iD.util.getPrototypeOf(result.entities))); + redraw(Object.keys(result.entities)); } function zoomPan() {