Stack areas by area (#324)

This doesn't address stacking multipolygons, or interleaving
areas and multipolygons. More and more, I'm thinking we should
just merge the two into a unified "area" geometry.
This commit is contained in:
John Firebaugh
2013-01-25 17:08:42 -05:00
parent 432f77eb6d
commit 66ac8349ac
2 changed files with 27 additions and 30 deletions
+10 -30
View File
@@ -1,42 +1,22 @@
iD.svg.Areas = function(projection) {
var area_stack = {
building: 0,
manmade: 1,
natural: 1,
boundary: 2
};
function findKey(a) {
var vals = Object.keys(a.tags).filter(function(k) {
return area_stack[k] !== undefined;
});
if (vals.length > 0) return area_stack[vals[0]];
else return -1;
}
function areastack(a, b) {
if (!a || !b || !a.tags || !b.tags) return 0;
if (a.tags.layer !== undefined && b.tags.layer !== undefined) {
return a.tags.layer - b.tags.layer;
}
var as = 0, bs = 0;
as -= findKey(a);
bs -= findKey(b);
return as - bs;
}
return function drawAreas(surface, graph, entities, filter) {
var areas = [];
for (var i = 0; i < entities.length; i++) {
var entity = entities[i];
if (entity.geometry(graph) === 'area') {
areas.push(entity);
var points = graph.childNodes(entity).map(function(n) {
return projection(n.loc);
});
areas.push({
entity: entity,
area: entity.isDegenerate() ? 0 : d3.geom.polygon(points).area()
});
}
}
areas.sort(areastack);
areas.sort(function(a, b) { return a.area - b.area; });
var lineString = iD.svg.LineString(projection, graph);
@@ -62,6 +42,6 @@ iD.svg.Areas = function(projection) {
}
var fill = surface.select('.layer-fill'),
paths = drawPaths(fill, areas, filter, 'way area');
paths = drawPaths(fill, _.pluck(areas, 'entity'), filter, 'way area');
};
};
+17
View File
@@ -52,4 +52,21 @@ describe("iD.svg.Areas", function () {
expect(surface.selectAll('.other')[0].length).to.equal(1);
});
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({area: true, tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'a']}),
'l': iD.Way({area: true, tags: {landuse: 'park'}, nodes: ['a', 'b', 'c', 'd', 'a']})
}),
areas = [graph.entity('s'), graph.entity('l')];
surface.call(iD.svg.Areas(projection), graph, areas, filter);
expect(surface.select('.area:nth-child(1)')).to.be.classed('tag-landuse-park');
expect(surface.select('.area:nth-child(2)')).to.be.classed('tag-building-yes');
});
});