handle extending multipolygons with multiway rings

This commit is contained in:
Ansis Brammanis
2013-04-03 13:18:48 -04:00
parent 62ee84c1a2
commit 0de68c9e4a
3 changed files with 39 additions and 21 deletions
+28 -18
View File
@@ -20,14 +20,27 @@ iD.actions.MergePolygon = function(ids) {
var action = function(graph) {
var entities = groupEntities(graph);
// an array of all the polygons to be merged
var polygons = _.unique(entities.multipolygon.reduce(function(polygons, m) {
return polygons.concat(m.members.filter(function(d) {
return d.type === 'way';
}).map(function(d) {
return graph.entity(d.id);
}));
}, entities.closedWay));
// An array of objects representing all the polygons that are part of the multipolygon.
//
// Each object has two properties:
// ids - an array of ids of entities that are part of that polygon
// locs - an array of the locations forming the polygon
var polygons = entities.multipolygon.reduce(function(polygons, m) {
m.multipolygon(graph).forEach(function(group) {
group.forEach(function(ring) {
polygons.push({
ids: ring.ids,
locs: ring
});
});
});
return polygons;
}, []).concat(entities.closedWay.map(function(d) {
return {
ids: [d.id],
locs: graph.childNodes(d).map(function(n) { return n.loc; })
};
}));
// contained is an array of arrays of boolean values,
// where contained[j][k] is true iff the jth way is
@@ -35,15 +48,10 @@ iD.actions.MergePolygon = function(ids) {
var contained = polygons.map(function(w, i) {
return polygons.map(function(d, n) {
if (i === n) return null;
return iD.geo.polygonContainsPolygon(getLocs(d), getLocs(w));
return iD.geo.polygonContainsPolygon(d.locs, w.locs);
});
});
function getLocs(way) {
return graph.childNodes(way).map(function(d) { return d.loc; });
}
// Sort all polygons as either outer or inner ways
var members = [];
outer = true;
@@ -65,10 +73,12 @@ iD.actions.MergePolygon = function(ids) {
function extractUncontained(polygons) {
polygons.forEach(function(d, i) {
if (!isContained(d, i)) {
members.push({
type: 'way',
id: d.id,
role: outer ? 'outer' : 'inner'
d.ids.forEach(function(id) {
members.push({
type: 'way',
id: id,
role: outer ? 'outer' : 'inner'
});
});
}
});
+10 -3
View File
@@ -169,10 +169,12 @@ _.extend(iD.Relation.prototype, {
.map(function(m) { return { role: m.role || 'outer', id: m.id, nodes: resolver.childNodes(resolver.entity(m.id)) }; });
function join(ways) {
var joined = [], current, first, last, i, how, what;
var joined = [], way, current, first, last, i, how, what;
while (ways.length) {
current = ways.pop().nodes.slice();
way = ways.pop();
current = way.nodes.slice();
current.ids = [way.id];
joined.push(current);
while (ways.length && _.first(current) !== _.last(current)) {
@@ -206,12 +208,17 @@ _.extend(iD.Relation.prototype, {
if (!what)
break; // Invalid geometry (unclosed ring)
current.ids.push(ways[i].id);
ways.splice(i, 1);
how.apply(current, what);
}
}
return joined.map(function(nodes) { return _.pluck(nodes, 'loc'); });
return joined.map(function(nodes) {
var locs = _.pluck(nodes, 'loc');
locs.ids = nodes.ids;
return locs;
});
}
function findOuter(inner) {
+1
View File
@@ -110,6 +110,7 @@
<script src='../js/id/actions/disconnect.js'></script>
<script src='../js/id/actions/join.js'></script>
<script src='../js/id/actions/merge.js'></script>
<script src='../js/id/actions/merge_polygon.js'></script>
<script src='../js/id/actions/move_node.js'></script>
<script src='../js/id/actions/move.js'></script>
<script src='../js/id/actions/rotate_way.js'></script>