mirror of
https://github.com/FoggedLens/iD.git
synced 2026-03-30 17:00:35 +02:00
ability to create multipolygons
This commit is contained in:
@@ -124,6 +124,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>
|
||||
|
||||
106
js/id/actions/merge_polygon.js
Normal file
106
js/id/actions/merge_polygon.js
Normal file
@@ -0,0 +1,106 @@
|
||||
iD.actions.MergePolygon = function(ids) {
|
||||
|
||||
function groupEntities(graph) {
|
||||
var entities = ids.map(graph.getEntity);
|
||||
return _.extend({
|
||||
closedWay: [],
|
||||
multipolygon: [],
|
||||
other: []
|
||||
}, _.groupBy(entities, function(entity) {
|
||||
if (entity.type === 'way' && entity.isClosed()) {
|
||||
return 'closedWay';
|
||||
} else if (entity.type === 'relation' && entity.isMultipolygon()) {
|
||||
return 'multipolygon';
|
||||
} else {
|
||||
return 'other';
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
// contained is an array of arrays of boolean values,
|
||||
// where contained[j][k] is true iff the jth way is
|
||||
// contained by the kth way.
|
||||
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));
|
||||
});
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
while (polygons.length) {
|
||||
extractUncontained(polygons);
|
||||
polygons = polygons.filter(isContained);
|
||||
contained = contained.filter(isContained).map(filterContained);
|
||||
}
|
||||
|
||||
function isContained(d, i) {
|
||||
return _.any(contained[i]);
|
||||
}
|
||||
|
||||
function filterContained(d, i) {
|
||||
return d.filter(isContained);
|
||||
}
|
||||
|
||||
function extractUncontained(polygons) {
|
||||
polygons.forEach(function(d, i) {
|
||||
if (!isContained(d, i)) {
|
||||
members.push({
|
||||
type: 'way',
|
||||
id: d.id,
|
||||
role: outer ? 'outer' : 'inner'
|
||||
});
|
||||
}
|
||||
});
|
||||
outer = !outer;
|
||||
}
|
||||
|
||||
// Move all tags to one relation
|
||||
var relation = entities.multipolygon[0] ||
|
||||
iD.Relation({ tags: { type: 'multipolygon' }});
|
||||
|
||||
entities.multipolygon.slice(1).forEach(function(m) {
|
||||
relation = relation.mergeTags(m.tags);
|
||||
graph = graph.remove(m);
|
||||
});
|
||||
|
||||
members.forEach(function(m) {
|
||||
var entity = graph.entity(m.id);
|
||||
relation = relation.mergeTags(entity.tags);
|
||||
graph = graph.replace(entity.update({ tags: {} }));
|
||||
});
|
||||
|
||||
delete relation.tags.area;
|
||||
|
||||
return graph.replace(relation.update({ members: members }));
|
||||
};
|
||||
|
||||
action.disabled = function(graph) {
|
||||
var entities = groupEntities(graph);
|
||||
if (entities.other.length > 0 ||
|
||||
entities.closedWay.length + entities.multipolygon.length < 2)
|
||||
return 'not_eligible';
|
||||
};
|
||||
|
||||
return action;
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
iD.operations.Merge = function(selection, context) {
|
||||
var join = iD.actions.Join(selection),
|
||||
merge = iD.actions.Merge(selection);
|
||||
merge = iD.actions.Merge(selection),
|
||||
mergePolygon = iD.actions.MergePolygon(selection);
|
||||
|
||||
var operation = function() {
|
||||
var annotation = t('operations.merge.annotation', {n: selection.length}),
|
||||
@@ -8,8 +9,10 @@ iD.operations.Merge = function(selection, context) {
|
||||
|
||||
if (!join.disabled(context.graph())) {
|
||||
action = join;
|
||||
} else {
|
||||
} else if (!merge.disabled(context.graph())) {
|
||||
action = merge;
|
||||
} else {
|
||||
action = mergePolygon;
|
||||
}
|
||||
|
||||
var difference = context.perform(action, annotation);
|
||||
@@ -22,7 +25,8 @@ iD.operations.Merge = function(selection, context) {
|
||||
|
||||
operation.disabled = function() {
|
||||
return join.disabled(context.graph()) &&
|
||||
merge.disabled(context.graph());
|
||||
merge.disabled(context.graph()) &&
|
||||
mergePolygon.disabled(context.graph());
|
||||
};
|
||||
|
||||
operation.tooltip = function() {
|
||||
|
||||
Reference in New Issue
Block a user