From 8bca85d3b203bf8939379143001957496b1414c8 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 31 Oct 2012 21:07:29 -0400 Subject: [PATCH] Entity as a mixin rather than a sub-object. --- NOTES.md | 13 +++++++++++++ index.html | 2 +- js/iD/Entity.js | 11 ++--------- js/iD/Node.js | 3 ++- js/iD/Relation.js | 6 ++++-- js/iD/Util.js | 8 ++++++++ js/iD/Way.js | 19 +++++++------------ js/iD/renderer/Map.js | 4 ++-- test/index.html | 3 +-- test/spec/Entity.js | 4 ---- test/spec/Way.js | 2 +- 11 files changed, 41 insertions(+), 34 deletions(-) diff --git a/NOTES.md b/NOTES.md index 08306ab32..90142960d 100644 --- a/NOTES.md +++ b/NOTES.md @@ -1,3 +1,16 @@ +## The Graph + +iD implements a [persistent data structure](http://en.wikipedia.org/wiki/Persistent_data_structure) +over the OSM data model. + +To be clear, this data model is something like + + + root -> relations (-> relations) -> ways -> nodes + \ \> nodes + \- ways -> nodes + \- nodes + ## Actions Actions are operations on OSM data like adding nodes, moving ways, diff --git a/index.html b/index.html index b92025444..82463d893 100755 --- a/index.html +++ b/index.html @@ -31,10 +31,10 @@ + - diff --git a/js/iD/Entity.js b/js/iD/Entity.js index 091be884d..27ddd284c 100755 --- a/js/iD/Entity.js +++ b/js/iD/Entity.js @@ -1,14 +1,7 @@ -iD.Entity = function () { - this.parents = {}; - this._id = iD.Util.id(); - this.id = NaN; - this.loaded = false; - this.type = ''; - this.modified = false; - this.deleted = false; -}; +iD.Entity = function () { }; iD.Entity.prototype = { + parents: {}, // a relation or way which contains this entity addParent: function (x) { this.parents[x._id] = x; diff --git a/js/iD/Node.js b/js/iD/Node.js index ebca16fdf..e6e963c1f 100644 --- a/js/iD/Node.js +++ b/js/iD/Node.js @@ -2,7 +2,6 @@ iD.Node = function(id, lat, lon, tags, loaded) { this.type = 'node'; this.id = id; this._id = iD.Util.id(); - this.entity = new iD.Entity(); this.lat = lat; this.lon = lon; this[0] = lon; @@ -19,3 +18,5 @@ iD.Node.prototype = { (this.lat >= extent[1][1]); } }; + +iD.Util.extend(iD.Node, iD.Entity); diff --git a/js/iD/Relation.js b/js/iD/Relation.js index 2e3db1709..fb90e8c3f 100644 --- a/js/iD/Relation.js +++ b/js/iD/Relation.js @@ -1,11 +1,11 @@ -iD.Relation = function(id, members, tags, loaded) { +iD.Relation = function(id, children, tags, loaded) { members = members || []; tags = tags || {}; this.type = 'relation'; this.id = id; this._id = iD.Util.id(); this.entity = new iD.Entity(); - this.members = members; + this.children = children; this.tags = tags; this.modified = this.id < 0; this.loaded = (loaded === undefined) ? true : loaded; @@ -15,6 +15,8 @@ iD.Relation.prototype = { intersects: function() { return true; } }; +iD.Util.extend(iD.Relation, iD.Entity); + iD.RelationMember = function(entity, role) { this.entity = entity; this.role = role; diff --git a/js/iD/Util.js b/js/iD/Util.js index 802b88e0f..f61ee5dab 100644 --- a/js/iD/Util.js +++ b/js/iD/Util.js @@ -30,3 +30,11 @@ iD.Util.friendlyName = function(entity) { return n.length === 0 ? 'unknown' : n.join('; '); }; +iD.Util.extend = function(child, parent) { + for (var property in parent.prototype) { + if (typeof child.prototype[property] == "undefined") { + child.prototype[property] = parent.prototype[property]; + } + } + return child; +}; diff --git a/js/iD/Way.js b/js/iD/Way.js index 9333ba7ba..491dc9761 100644 --- a/js/iD/Way.js +++ b/js/iD/Way.js @@ -12,27 +12,19 @@ iD.Way = function(id, nodes, tags, loaded) { this.type = 'way'; this.id = id; this._id = iD.Util.id(); - this.deleted = false; - this.entity = new iD.Entity(); this.tags = tags; - this.nodes = nodes; + this.children = nodes; this.loaded = (loaded === undefined) ? true : loaded; this.extent = {}; }; iD.Way.prototype = { - addNode: function(node) { - this.nodes.push(node); - this._bounds = null; - return this; - }, - // JOSM: http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/data/osm/Way.java#L466 isClosed: function() { // summary: Is this a closed way (first and last nodes the same)? - if (!this.nodes.length) return true; - return this.nodes[this.nodes.length - 1] === this.nodes[0]; + if (!this.children.length) return true; + return this.children[this.children.length - 1] === this.children[0]; }, isType: function(type) { @@ -56,9 +48,10 @@ iD.Way.prototype = { // --------------------- // Bounding-box handling intersects: function(extent) { + // TODO: rewrite with new id-mapping return true; // No-node ways are inside of nothing. - if (!this.nodes.length) return false; + if (!this.children.length) return false; var bounds = this.bounds(); // left return !( @@ -72,3 +65,5 @@ iD.Way.prototype = { bounds[0][1] > extent[1][1]); } }; + +iD.Util.extend(iD.Way, iD.Entity); diff --git a/js/iD/renderer/Map.js b/js/iD/renderer/Map.js index b0debdff1..370fe91ce 100755 --- a/js/iD/renderer/Map.js +++ b/js/iD/renderer/Map.js @@ -113,7 +113,7 @@ iD.Map = function(obj) { } function nodeline(d) { - return linegen(d.nodes.map(function(n) { + return linegen(d.children.map(function(n) { return connection.graph().index[n]; })); } @@ -163,7 +163,7 @@ iD.Map = function(obj) { }); var handles = layers[0].hit.selectAll('circle.handle') - .data(active_entity.length ? active_entity[0].nodes : [], key); + .data(active_entity.length ? active_entity[0].children : [], key); handles.exit().remove(); fills.exit().remove(); diff --git a/test/index.html b/test/index.html index e233bc6bb..24c10d7d3 100644 --- a/test/index.html +++ b/test/index.html @@ -13,16 +13,15 @@ + - - diff --git a/test/spec/Entity.js b/test/spec/Entity.js index 7632c760b..784109279 100644 --- a/test/spec/Entity.js +++ b/test/spec/Entity.js @@ -5,10 +5,6 @@ describe('Entity', function () { entity = new iD.Entity(); }); - it('has no entity type', function () { - expect(entity.type).toEqual(''); - }); - describe('#parentWays', function () { it('returns an array of parents with entityType way', function () { entity.addParent({_id: 1, type: 'way'}); diff --git a/test/spec/Way.js b/test/spec/Way.js index f2686c85d..40662ab49 100644 --- a/test/spec/Way.js +++ b/test/spec/Way.js @@ -11,7 +11,7 @@ describe('Way', function() { }); it('has zero nodes by default', function() { - expect(way.nodes.length).toEqual(0); + expect(way.children.length).toEqual(0); }); describe('#isClosed', function() {