mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-12 16:52:50 +00:00
Disable merge operation when it would damage relations
The operation is disabled when attempting to join ways which don't belong to identical sets of relations. Restriction relations are excluded, because they are already handled with slightly different logic. Fixes #8674 Fixes #8645 Fixes #3825 Fixes #1512
This commit is contained in:
@@ -316,6 +316,7 @@ en:
|
||||
relation: These features can't be merged because they have conflicting relation roles.
|
||||
incomplete_relation: These features can't be merged because at least one hasn't been fully downloaded.
|
||||
conflicting_tags: These features can't be merged because some of their tags have conflicting values.
|
||||
conflicting_relations: These features can't be merged because they belong to conflicting relations.
|
||||
paths_intersect: These features can't be merged because the resulting path would intersect itself.
|
||||
too_many_vertices: These features can't be merged because the resulting path would have too many points.
|
||||
move:
|
||||
|
||||
2
dist/locales/en.min.json
vendored
2
dist/locales/en.min.json
vendored
File diff suppressed because one or more lines are too long
@@ -3,7 +3,7 @@ import { actionDeleteWay } from './delete_way';
|
||||
import { osmIsInterestingTag } from '../osm/tags';
|
||||
import { osmJoinWays } from '../osm/multipolygon';
|
||||
import { geoPathIntersections } from '../geo';
|
||||
import { utilArrayGroupBy, utilArrayIntersection } from '../util';
|
||||
import { utilArrayGroupBy, utilArrayIdentical, utilArrayIntersection } from '../util';
|
||||
|
||||
|
||||
// Join ways at the end node they share.
|
||||
@@ -129,9 +129,27 @@ export function actionJoin(ids) {
|
||||
return 'not_adjacent';
|
||||
}
|
||||
|
||||
var i;
|
||||
|
||||
// All joined ways must belong to the same set of (non-restriction) relations.
|
||||
// Restriction relations have different logic, below, which allows some cases
|
||||
// this prohibits, and prohibits some cases this allows.
|
||||
var sortedParentRelations = function (id) {
|
||||
return graph.parentRelations(graph.entity(id))
|
||||
.filter((rel) => !rel.isRestriction())
|
||||
.sort((a, b) => a.id - b.id);
|
||||
};
|
||||
var relsA = sortedParentRelations(ids[0]);
|
||||
for (i = 1; i < ids.length; i++) {
|
||||
var relsB = sortedParentRelations(ids[i]);
|
||||
if (!utilArrayIdentical(relsA, relsB)) {
|
||||
return 'conflicting_relations';
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through all combinations of path-pairs
|
||||
// to check potential intersections between all pairs
|
||||
for (var i = 0; i < ids.length - 1; i++) {
|
||||
for (i = 0; i < ids.length - 1; i++) {
|
||||
for (var j = i + 1; j < ids.length; j++) {
|
||||
var path1 = graph.childNodes(graph.entity(ids[i]))
|
||||
.map(function(e) { return e.loc; });
|
||||
|
||||
@@ -74,6 +74,9 @@ export function operationMerge(context, selectedIDs) {
|
||||
operation.tooltip = function() {
|
||||
var disabled = operation.disabled();
|
||||
if (disabled) {
|
||||
if (disabled === 'conflicting_relations') {
|
||||
return t('operations.merge.conflicting_relations');
|
||||
}
|
||||
if (disabled === 'restriction') {
|
||||
return t('operations.merge.restriction',
|
||||
{ relation: presetManager.item('type/restriction').name() });
|
||||
|
||||
@@ -142,6 +142,47 @@ describe('iD.actionJoin', function () {
|
||||
expect(iD.actionJoin(['-', '=']).disabled(graph)).to.equal('restriction');
|
||||
});
|
||||
|
||||
it('returns \'conflicting_relations\' when a relation would be extended', function () {
|
||||
// a --> b ==> c
|
||||
// members: -
|
||||
// not member: =
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'a', loc: [0,0]}),
|
||||
iD.osmNode({id: 'b', loc: [2,0]}),
|
||||
iD.osmNode({id: 'c', loc: [4,0]}),
|
||||
iD.osmWay({id: '-', nodes: ['a', 'b']}),
|
||||
iD.osmWay({id: '=', nodes: ['b', 'c']}),
|
||||
iD.osmRelation({id: 'r', tags: {}, members: [
|
||||
{type: 'way', id: '-'},
|
||||
]})
|
||||
]);
|
||||
|
||||
expect(iD.actionJoin(['-', '=']).disabled(graph)).to.equal('conflicting_relations');
|
||||
});
|
||||
|
||||
it('returns \'conflicting_relations\' when a relation would be forked', function () {
|
||||
// a --> b ==> c
|
||||
// |
|
||||
// d
|
||||
// members: -, =
|
||||
// not member: |
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'a', loc: [0,0]}),
|
||||
iD.osmNode({id: 'b', loc: [2,0]}),
|
||||
iD.osmNode({id: 'c', loc: [4,0]}),
|
||||
iD.osmNode({id: 'd', loc: [2,2]}),
|
||||
iD.osmWay({id: '-', nodes: ['a', 'b']}),
|
||||
iD.osmWay({id: '=', nodes: ['b', 'c']}),
|
||||
iD.osmWay({id: '|', nodes: ['b', 'd']}),
|
||||
iD.osmRelation({id: 'r', tags: {}, members: [
|
||||
{type: 'way', id: '-'},
|
||||
{type: 'way', id: '='},
|
||||
]})
|
||||
]);
|
||||
|
||||
expect(iD.actionJoin(['-', '|']).disabled(graph)).to.equal('conflicting_relations');
|
||||
});
|
||||
|
||||
it('returns \'paths_intersect\' if resulting way intersects itself', function () {
|
||||
// d
|
||||
// |
|
||||
|
||||
Reference in New Issue
Block a user