Fix area caching (fixes #1485)

This commit is contained in:
John Firebaugh
2013-05-14 16:17:06 -07:00
parent 271ddace64
commit 6431fca8a3
5 changed files with 62 additions and 13 deletions
+9 -2
View File
@@ -34,6 +34,10 @@ iD.Entity.key = function(entity) {
return entity.id + ',' + entity.v;
};
iD.Entity.areaPath = d3.geo.path()
.projection(d3.geo.mercator()
.scale(12016420.517592335));
iD.Entity.prototype = {
tags: {},
@@ -95,9 +99,12 @@ iD.Entity.prototype = {
return this.extent(resolver).intersects(extent);
},
area: function(resolver, path) {
// Returns the (possibly negative) area of the entity in square pixels at an
// arbitrary unspecified zoom level -- so basically, only useful for relative
// comparisons.
area: function(resolver) {
return resolver.transient(this, 'area', function() {
return path.area(this);
return iD.Entity.areaPath.area(this.asGeoJSON(resolver, true));
});
},
+1 -1
View File
@@ -143,7 +143,7 @@ _.extend(iD.Way.prototype, {
childnodes = childnodes.concat([childnodes[0]]);
}
if (this.isArea() && (close || this.isClosed())) {
if (this.isArea() && childnodes.length >= 4 && (close || this.isClosed())) {
return {
type: 'Feature',
properties: this.tags,
+2 -2
View File
@@ -37,12 +37,12 @@ iD.svg.Areas = function(projection) {
if (multipolygon = iD.geo.isSimpleMultipolygonOuterMember(entity, graph)) {
areas[multipolygon.id] = {
entity: multipolygon.mergeTags(entity.tags),
area: Math.abs(entity.area(graph, path))
area: Math.abs(entity.area(graph))
};
} else if (!areas[entity.id]) {
areas[entity.id] = {
entity: entity,
area: Math.abs(entity.area(graph, path))
area: Math.abs(entity.area(graph))
};
}
}
+40 -2
View File
@@ -144,7 +144,7 @@ describe('iD.Entity', function () {
});
});
describe("#hasDeprecatedTags", function () {
describe("#hasDeprecatedTags", function () {
it("returns false if entity has no tags", function () {
expect(iD.Entity().deprecatedTags()).to.eql({});
});
@@ -152,7 +152,7 @@ describe('iD.Entity', function () {
it("returns true if entity has deprecated tags", function () {
expect(iD.Entity({ tags: { barrier: 'wire_fence' } }).deprecatedTags()).to.eql({ barrier: 'wire_fence' });
});
});
});
describe("#hasInterestingTags", function () {
it("returns false if the entity has no tags", function () {
@@ -171,4 +171,42 @@ describe('iD.Entity', function () {
expect(iD.Entity({tags: {'tiger:source': 'blah', 'tiger:foo': 'bar'}}).hasInterestingTags()).to.equal(false);
});
});
describe("#area", function() {
it("returns a relative measure of area", function () {
var graph = iD.Graph({
'a': iD.Node({id: 'a', loc: [-0.0002, 0.0001]}),
'b': iD.Node({id: 'b', loc: [ 0.0002, 0.0001]}),
'c': iD.Node({id: 'c', loc: [ 0.0002, -0.0001]}),
'd': iD.Node({id: 'd', loc: [-0.0002, -0.0001]}),
'e': iD.Node({id: 'a', loc: [-0.0004, 0.0002]}),
'f': iD.Node({id: 'b', loc: [ 0.0004, 0.0002]}),
'g': iD.Node({id: 'c', loc: [ 0.0004, -0.0002]}),
'h': iD.Node({id: 'd', loc: [-0.0004, -0.0002]}),
's': iD.Way({id: 's', tags: {area: 'yes'}, nodes: ['a', 'b', 'c', 'd', 'a']}),
'l': iD.Way({id: 'l', tags: {area: 'yes'}, nodes: ['e', 'f', 'g', 'h', 'e']})
});
var s = Math.abs(graph.entity('s').area(graph)),
l = Math.abs(graph.entity('l').area(graph));
expect(s).to.be.lt(l);
});
it("returns 0 for degenerate areas", function () {
var graph = iD.Graph({
'a': iD.Node({id: 'a', loc: [-0.0002, 0.0001]}),
'b': iD.Node({id: 'b', loc: [ 0.0002, 0.0001]}),
'c': iD.Node({id: 'c', loc: [ 0.0002, -0.0001]}),
'd': iD.Node({id: 'd', loc: [-0.0002, -0.0001]}),
'0': iD.Way({id: '0', tags: {area: 'yes'}, nodes: []}),
'1': iD.Way({id: '1', tags: {area: 'yes'}, nodes: ['a']}),
'2': iD.Way({id: '2', tags: {area: 'yes'}, nodes: ['a', 'b']})
});
expect(graph.entity('0').area(graph)).to.equal(0);
expect(graph.entity('1').area(graph)).to.equal(0);
expect(graph.entity('2').area(graph)).to.equal(0);
});
});
});
+10 -6
View File
@@ -53,12 +53,16 @@ describe("iD.svg.Areas", function () {
it("stacks smaller areas above larger ones", function () {
var graph = iD.Graph({
'a': iD.Node({id: 'a', loc: [0, 0]}),
'b': iD.Node({id: 'b', loc: [1, 0]}),
'c': iD.Node({id: 'c', loc: [1, 1]}),
'd': iD.Node({id: 'd', loc: [0, 1]}),
's': iD.Way({id: 's', tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'a']}),
'l': iD.Way({id: 'l', tags: {landuse: 'park'}, nodes: ['a', 'b', 'c', 'd', 'a']})
'a': iD.Node({id: 'a', loc: [-0.0002, 0.0001]}),
'b': iD.Node({id: 'b', loc: [ 0.0002, 0.0001]}),
'c': iD.Node({id: 'c', loc: [ 0.0002, -0.0001]}),
'd': iD.Node({id: 'd', loc: [-0.0002, -0.0001]}),
'e': iD.Node({id: 'a', loc: [-0.0004, 0.0002]}),
'f': iD.Node({id: 'b', loc: [ 0.0004, 0.0002]}),
'g': iD.Node({id: 'c', loc: [ 0.0004, -0.0002]}),
'h': iD.Node({id: 'd', loc: [-0.0004, -0.0002]}),
's': iD.Way({id: 's', tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'd', 'a']}),
'l': iD.Way({id: 'l', tags: {landuse: 'park'}, nodes: ['e', 'f', 'g', 'h', 'e']})
}),
areas = [graph.entity('s'), graph.entity('l')];