First cut on multipolygon rendering

This commit is contained in:
John Firebaugh
2013-01-17 11:01:20 -08:00
parent 545789efcc
commit 9a76b81125
8 changed files with 121 additions and 6 deletions
+17 -5
View File
@@ -142,29 +142,37 @@ path.stroke.tag-railway-subway {
stroke-dasharray: 8,8;
}
path.area {
path.area,
path.multipolygon {
stroke-width:2;
stroke:#fff;
fill:#fff;
fill-opacity:0.3;
}
path.multipolygon {
fill-rule: evenodd;
}
path.area.selected {
stroke-width:4 !important;
}
path.area.tag-natural {
path.area.tag-natural,
path.multipolygon.tag-natural {
stroke: #ADD6A5;
fill: #ADD6A5;
stroke-width:1;
}
path.area.tag-natural-water {
path.area.tag-natural-water,
path.multipolygon.tag-natural-water {
stroke: #6382FF;
fill: #ADBEFF;
}
path.area.tag-building {
path.area.tag-building,
path.multipolygon.tag-building {
stroke: #9E176A;
stroke-width: 1;
fill: #ff6ec7;
@@ -173,7 +181,11 @@ path.area.tag-building {
path.area.tag-landuse,
path.area.tag-natural-wood,
path.area.tag-natural-tree,
path.area.tag-natural-grassland {
path.area.tag-natural-grassland,
path.multipolygon.tag-landuse,
path.multipolygon.tag-natural-wood,
path.multipolygon.tag-natural-tree,
path.multipolygon.tag-natural-grassland {
stroke: #006B34;
stroke-width: 1;
fill: #189E59;
+1
View File
@@ -41,6 +41,7 @@
<script src="js/id/svg/areas.js"></script>
<script src="js/id/svg/lines.js"></script>
<script src="js/id/svg/midpoints.js"></script>
<script src="js/id/svg/multipolygons.js"></script>
<script src="js/id/svg/points.js"></script>
<script src="js/id/svg/surface.js"></script>
<script src="js/id/svg/tag_classes.js"></script>
+2
View File
@@ -21,6 +21,7 @@ iD.Map = function() {
vertices = iD.svg.Vertices(roundedProjection),
lines = iD.svg.Lines(roundedProjection),
areas = iD.svg.Areas(roundedProjection),
multipolygons = iD.svg.Multipolygons(roundedProjection),
midpoints = iD.svg.Midpoints(roundedProjection),
tail = d3.tail(),
surface, tilegroup;
@@ -102,6 +103,7 @@ iD.Map = function() {
.call(vertices, graph, all, filter)
.call(lines, graph, all, filter)
.call(areas, graph, all, filter)
.call(multipolygons, graph, all, filter)
.call(midpoints, graph, all, filter);
}
+54
View File
@@ -0,0 +1,54 @@
iD.svg.Multipolygons = function(projection) {
return function(surface, graph, entities, filter) {
var multipolygons = [];
for (var i = 0; i < entities.length; i++) {
var entity = entities[i];
if (entity.geometry() === 'relation' && entity.tags.type === 'multipolygon') {
multipolygons.push(entity);
}
}
var lineStrings = {};
function lineString(entity) {
if (lineStrings[entity.id] !== undefined) {
return lineStrings[entity.id];
}
var multipolygon = entity.multipolygon(graph);
if (entity.members.length == 0 || !multipolygon) {
return (lineStrings[entity.id] = null);
}
multipolygon = _.flatten(multipolygon, true);
return (lineStrings[entity.id] =
multipolygon.map(function (ring) {
return 'M' + ring.map(function (node) { return projection(node.loc); }).join('L');
}).join(""));
}
function drawPaths(group, multipolygons, filter, classes) {
var paths = group.selectAll('path.multipolygon')
.filter(filter)
.data(multipolygons, iD.Entity.key);
paths.enter()
.append('path')
.attr('class', classes);
paths
.order()
.attr('d', lineString)
.call(iD.svg.TagClasses());
paths.exit()
.remove();
return paths;
}
var fill = surface.select('.layer-fill'),
paths = drawPaths(fill, multipolygons, filter, 'relation multipolygon');
};
};
+1 -1
View File
@@ -1,7 +1,7 @@
iD.svg.TagClasses = function() {
var keys = iD.util.trueObj([
'highway', 'railway', 'motorway', 'amenity', 'natural',
'landuse', 'building', 'oneway', 'bridge'
'landuse', 'building', 'oneway', 'bridge', 'boundary'
]), tagClassRe = /^tag-/;
return function tagClassesSelection(selection) {
+2
View File
@@ -43,6 +43,7 @@
<script src="../js/id/svg/areas.js"></script>
<script src="../js/id/svg/lines.js"></script>
<script src="../js/id/svg/midpoints.js"></script>
<script src="../js/id/svg/multipolygons.js"></script>
<script src="../js/id/svg/points.js"></script>
<script src="../js/id/svg/surface.js"></script>
<script src="../js/id/svg/tag_classes.js"></script>
@@ -153,6 +154,7 @@
<script src="spec/svg.js"></script>
<script src="spec/svg/areas.js"></script>
<script src="spec/svg/multipolygons.js"></script>
<script src="spec/svg/points.js"></script>
<script src="spec/svg/vertices.js"></script>
<script src="spec/svg/tag_classes.js"></script>
+1
View File
@@ -62,6 +62,7 @@
<script src="spec/svg.js"></script>
<script src="spec/svg/areas.js"></script>
<script src="spec/svg/multipolygons.js"></script>
<script src="spec/svg/points.js"></script>
<script src="spec/svg/vertices.js"></script>
<script src="spec/svg/tag_classes.js"></script>
+43
View File
@@ -0,0 +1,43 @@
describe("iD.svg.Multipolygons", function () {
var surface,
projection = Object,
filter = d3.functor(true);
beforeEach(function () {
surface = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
.call(iD.svg.Surface());
});
it("adds relation and multipolygon classes", function () {
var relation = iD.Relation({tags: {type: 'multipolygon'}}),
graph = iD.Graph([relation]);
surface.call(iD.svg.Multipolygons(projection), graph, [relation], filter);
expect(surface.select('path')).to.be.classed('relation');
expect(surface.select('path')).to.be.classed('multipolygon');
});
it("adds tag classes", function () {
var relation = iD.Relation({tags: {type: 'multipolygon', boundary: "administrative"}}),
graph = iD.Graph([relation]);
surface.call(iD.svg.Multipolygons(projection), graph, [relation], filter);
expect(surface.select('.relation')).to.be.classed('tag-boundary');
expect(surface.select('.relation')).to.be.classed('tag-boundary-administrative');
});
it("preserves non-multipolygon paths", function () {
var relation = iD.Relation({tags: {type: 'multipolygon'}}),
graph = iD.Graph([relation]);
surface.select('.layer-fill')
.append('path')
.attr('class', 'other');
surface.call(iD.svg.Multipolygons(projection), graph, [relation], filter);
expect(surface.selectAll('.other')[0].length).to.equal(1);
});
});