modules/actions/merge.js (57 lines of code) (raw):
import { utilArrayGroupBy, utilArrayUniq } from '@id-sdk/util';
import { osmTagSuggestingArea } from '../osm/tags';
export function actionMerge(ids) {
function groupEntitiesByGeometry(graph) {
var entities = ids.map(function(id) { return graph.entity(id); });
return Object.assign(
{ point: [], area: [], line: [], relation: [] },
utilArrayGroupBy(entities, function(entity) { return entity.geometry(graph); })
);
}
var action = function(graph) {
var geometries = groupEntitiesByGeometry(graph);
var target = geometries.area[0] || geometries.line[0];
var points = geometries.point;
points.forEach(function(point) {
target = target.mergeTags(point.tags);
graph = graph.replace(target);
graph.parentRelations(point).forEach(function(parent) {
graph = graph.replace(parent.replaceMember(point, target));
});
var nodes = utilArrayUniq(graph.childNodes(target));
var removeNode = point;
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
if (graph.parentWays(node).length > 1 ||
graph.parentRelations(node).length ||
node.hasInterestingTags()) {
continue;
}
// Found an uninteresting child node on the target way.
// Move orig point into its place to preserve point's history. #3683
graph = graph.replace(point.update({ tags: {}, loc: node.loc }));
target = target.replaceNode(node.id, point.id);
graph = graph.replace(target);
removeNode = node;
break;
}
graph = graph.remove(removeNode);
});
if (target.tags.area === 'yes') {
var tags = Object.assign({}, target.tags); // shallow copy
delete tags.area;
if (osmTagSuggestingArea(tags)) {
// remove the `area` tag if area geometry is now implied - #3851
target = target.update({ tags: tags });
graph = graph.replace(target);
}
}
return graph;
};
action.disabled = function(graph) {
var geometries = groupEntitiesByGeometry(graph);
if (geometries.point.length === 0 ||
(geometries.area.length + geometries.line.length) !== 1 ||
geometries.relation.length !== 0) {
return 'not_eligible';
}
};
return action;
}