mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-25 01:24:05 +02:00
Introduce Entity transients; fix #187
This commit is contained in:
+41
-2
@@ -1,13 +1,23 @@
|
||||
iD.Entity = function(a, b, c) {
|
||||
if (!(this instanceof iD.Entity)) return new iD.Entity(a, b, c);
|
||||
|
||||
_.extend(this, {tags: {}}, a, b, c);
|
||||
this.tags = {};
|
||||
this.transients = {};
|
||||
|
||||
var sources = [a, b, c], source;
|
||||
for (var i = 0; i < sources.length; ++i) {
|
||||
source = sources[i];
|
||||
for (var prop in source) {
|
||||
if (prop !== 'transients' && Object.prototype.hasOwnProperty.call(source, prop)) {
|
||||
this[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.id) {
|
||||
this.id = iD.util.id(this.type);
|
||||
this._updated = true;
|
||||
}
|
||||
delete this._extent;
|
||||
|
||||
if (iD.debug) {
|
||||
Object.freeze(this);
|
||||
@@ -31,6 +41,35 @@ iD.Entity.prototype = {
|
||||
return this._updated && +this.id.slice(1) > 0;
|
||||
},
|
||||
|
||||
intersects: function(extent, resolver) {
|
||||
if (this.type === 'node') {
|
||||
return this.loc[0] > extent[0][0] &&
|
||||
this.loc[0] < extent[1][0] &&
|
||||
this.loc[1] < extent[0][1] &&
|
||||
this.loc[1] > extent[1][1];
|
||||
} else if (this.type === 'way') {
|
||||
var _extent = this.transients.extent;
|
||||
|
||||
if (!_extent) {
|
||||
_extent = this.transients.extent = [[-Infinity, Infinity], [Infinity, -Infinity]];
|
||||
for (var i = 0, l = this.nodes.length; i < l; i++) {
|
||||
var node = resolver.entity(this.nodes[i]);
|
||||
if (node.loc[0] > _extent[0][0]) _extent[0][0] = node.loc[0];
|
||||
if (node.loc[0] < _extent[1][0]) _extent[1][0] = node.loc[0];
|
||||
if (node.loc[1] < _extent[0][1]) _extent[0][1] = node.loc[1];
|
||||
if (node.loc[1] > _extent[1][1]) _extent[1][1] = node.loc[1];
|
||||
}
|
||||
}
|
||||
|
||||
return _extent[0][0] > extent[0][0] &&
|
||||
_extent[1][0] < extent[1][0] &&
|
||||
_extent[0][1] < extent[0][1] &&
|
||||
_extent[1][1] > extent[1][1];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
hasInterestingTags: function() {
|
||||
return _.keys(this.tags).some(function (key) {
|
||||
return key != "attribution" &&
|
||||
|
||||
+2
-35
@@ -55,46 +55,13 @@ iD.Graph.prototype = {
|
||||
return iD.Graph(entities, annotation);
|
||||
},
|
||||
|
||||
nodeIntersect: function(entity, extent) {
|
||||
return entity.loc[0] > extent[0][0] &&
|
||||
entity.loc[0] < extent[1][0] &&
|
||||
entity.loc[1] < extent[0][1] &&
|
||||
entity.loc[1] > extent[1][1];
|
||||
},
|
||||
|
||||
wayIntersect: function(entity, extent) {
|
||||
return entity._extent[0][0] > extent[0][0] &&
|
||||
entity._extent[1][0] < extent[1][0] &&
|
||||
entity._extent[0][1] < extent[0][1] &&
|
||||
entity._extent[1][1] > extent[1][1];
|
||||
},
|
||||
|
||||
indexWay: function(way) {
|
||||
if (way.type === 'way' && !way._extent) {
|
||||
// top left, bottom right
|
||||
var extent = [[-Infinity, Infinity], [Infinity, -Infinity]];
|
||||
var w = way;
|
||||
for (var j = 0, l = w.nodes.length; j < l; j++) {
|
||||
if (w.nodes[j].loc[0] > extent[0][0]) extent[0][0] = w.nodes[j].loc[0];
|
||||
if (w.nodes[j].loc[0] < extent[1][0]) extent[1][0] = w.nodes[j].loc[0];
|
||||
if (w.nodes[j].loc[1] < extent[0][1]) extent[0][1] = w.nodes[j].loc[1];
|
||||
if (w.nodes[j].loc[1] > extent[1][1]) extent[1][1] = w.nodes[j].loc[1];
|
||||
}
|
||||
way._extent = extent;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
// get all objects that intersect an extent.
|
||||
intersects: function(extent) {
|
||||
var items = [];
|
||||
for (var i in this.entities) {
|
||||
var entity = this.entities[i];
|
||||
if (entity.type === 'node' && this.nodeIntersect(entity, extent)) {
|
||||
items.push(entity);
|
||||
} else if (entity.type === 'way') {
|
||||
var w = this.fetch(entity.id);
|
||||
if (this.indexWay(w) && this.wayIntersect(w, extent)) items.push(w);
|
||||
if (entity.intersects(extent, this)) {
|
||||
items.push(this.fetch(entity.id));
|
||||
}
|
||||
}
|
||||
return items;
|
||||
|
||||
@@ -23,7 +23,17 @@ describe('Entity', function () {
|
||||
var attrs = {tags: {foo: 'bar'}},
|
||||
e = iD.Entity().update(attrs);
|
||||
expect(attrs).to.eql({tags: {foo: 'bar'}});
|
||||
})
|
||||
});
|
||||
|
||||
it("doesn't copy transients", function () {
|
||||
var entity = iD.Entity();
|
||||
entity.transients['foo'] = 'bar';
|
||||
expect(entity.update({}).transients).not.to.have.property('foo');
|
||||
});
|
||||
|
||||
it("doesn't copy prototype properties", function () {
|
||||
expect(iD.Entity().update({})).not.to.have.ownProperty('update');
|
||||
});
|
||||
});
|
||||
|
||||
describe("#created", function () {
|
||||
@@ -102,6 +112,16 @@ describe('Node', function () {
|
||||
it("sets tags as specified", function () {
|
||||
expect(iD.Node({tags: {foo: 'bar'}}).tags).to.eql({foo: 'bar'});
|
||||
});
|
||||
|
||||
describe("#intersects", function () {
|
||||
it("returns true for a node within the given extent", function () {
|
||||
expect(iD.Node({loc: [0, 0]}).intersects([[-180, 90], [180, -90]])).to.equal(true);
|
||||
});
|
||||
|
||||
it("returns false for a node outside the given extend", function () {
|
||||
expect(iD.Node({loc: [0, 0]}).intersects([[100, 90], [180, -90]])).to.equal(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Way', function () {
|
||||
@@ -133,6 +153,22 @@ describe('Way', function () {
|
||||
it("sets tags as specified", function () {
|
||||
expect(iD.Way({tags: {foo: 'bar'}}).tags).to.eql({foo: 'bar'});
|
||||
});
|
||||
|
||||
describe("#intersects", function () {
|
||||
it("returns true for a way with a node within the given extent", function () {
|
||||
var node = iD.Node({loc: [0, 0]}),
|
||||
way = iD.Way({nodes: [node.id]}),
|
||||
graph = iD.Graph([node, way]);
|
||||
expect(way.intersects([[-180, 90], [180, -90]], graph)).to.equal(true);
|
||||
});
|
||||
|
||||
it("returns false for way with no nodes within the given extent", function () {
|
||||
var node = iD.Node({loc: [0, 0]}),
|
||||
way = iD.Way({nodes: [node.id]}),
|
||||
graph = iD.Graph([node, way]);
|
||||
expect(way.intersects([[100, 90], [180, -90]], graph)).to.equal(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Relation', function () {
|
||||
|
||||
Reference in New Issue
Block a user