From 01bfc67ea5a0ad49100d42f0e8935a98f2427e29 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Mon, 10 Jul 2017 18:35:30 -0400 Subject: [PATCH] After splitting a way, update all matching relation members (closes #4140) --- modules/actions/split.js | 2 +- test/spec/actions/split.js | 77 +++++++++++++++++++++++++++++--------- 2 files changed, 60 insertions(+), 19 deletions(-) diff --git a/modules/actions/split.js b/modules/actions/split.js index 8a8efa493..3a2fb34fa 100644 --- a/modules/actions/split.js +++ b/modules/actions/split.js @@ -109,7 +109,7 @@ export function actionSplit(nodeId, newWayIds) { if (relation.isRestriction()) { var via = relation.memberByRole('via'); if (via && wayB.contains(via.id)) { - relation = relation.updateMember({id: wayB.id}, relation.memberById(wayA.id).index); + relation = relation.replaceMember(wayA, wayB); graph = graph.replace(relation); } } else { diff --git a/test/spec/actions/split.js b/test/spec/actions/split.js index 009c71195..0557108d3 100644 --- a/test/spec/actions/split.js +++ b/test/spec/actions/split.js @@ -456,17 +456,19 @@ describe('iD.actionSplit', function () { iD.Way({id: '-', nodes: ['a', 'b', 'c']}), iD.Way({id: '~', nodes: ['c', 'd']}), iD.Relation({id: 'r', tags: {type: type}, members: [ - {id: '-', role: 'from'}, - {id: '~', role: 'to'}, - {id: 'c', role: 'via'}]}) + {id: '-', role: 'from', type: 'way'}, + {id: '~', role: 'to', type: 'way'}, + {id: 'c', role: 'via', type: 'node'} + ]}) ]); graph = iD.actionSplit('b', ['='])(graph); expect(graph.entity('r').members).to.eql([ - {id: '=', role: 'from'}, - {id: '~', role: 'to'}, - {id: 'c', role: 'via'}]); + {id: '=', role: 'from', type: 'way'}, + {id: '~', role: 'to', type: 'way'}, + {id: 'c', role: 'via', type: 'node'} + ]); }); it('updates a restriction\'s \'to\' role', function () { @@ -488,17 +490,54 @@ describe('iD.actionSplit', function () { iD.Way({id: '-', nodes: ['a', 'b', 'c']}), iD.Way({id: '~', nodes: ['c', 'd']}), iD.Relation({id: 'r', tags: {type: type}, members: [ - {id: '~', role: 'from'}, - {id: '-', role: 'to'}, - {id: 'c', role: 'via'}]}) + {id: '~', role: 'from', type: 'way'}, + {id: '-', role: 'to', type: 'way'}, + {id: 'c', role: 'via', type: 'node'} + ]}) ]); graph = iD.actionSplit('b', ['='])(graph); expect(graph.entity('r').members).to.eql([ - {id: '~', role: 'from'}, - {id: '=', role: 'to'}, - {id: 'c', role: 'via'}]); + {id: '~', role: 'from', type: 'way'}, + {id: '=', role: 'to', type: 'way'}, + {id: 'c', role: 'via', type: 'node'} + ]); + }); + + + it('updates both \'to\' and \'from\' roles for u-turn restrictions', function () { + // Situation: + // a ----> b ----> c ~~~~ d + // A restriction from ---- to ---- via c. + // + // Split at b. + // + // Expected result: + // a ----> b ====> c ~~~~ d + // A restriction from ==== to ==== via c. + // + var graph = iD.Graph([ + iD.Node({id: 'a'}), + iD.Node({id: 'b'}), + iD.Node({id: 'c'}), + iD.Node({id: 'd'}), + iD.Way({id: '-', nodes: ['a', 'b', 'c']}), + iD.Way({id: '~', nodes: ['c', 'd']}), + iD.Relation({id: 'r', tags: {type: type}, members: [ + {id: '-', role: 'from', type: 'way'}, + {id: '-', role: 'to', type: 'way'}, + {id: 'c', role: 'via', type: 'node'} + ]}) + ]); + + graph = iD.actionSplit('b', ['='])(graph); + + expect(graph.entity('r').members).to.eql([ + {id: '=', role: 'from', type: 'way'}, + {id: '=', role: 'to', type: 'way'}, + {id: 'c', role: 'via', type: 'node'} + ]); }); it('leaves unaffected restrictions unchanged', function () { @@ -520,17 +559,19 @@ describe('iD.actionSplit', function () { iD.Way({id: '-', nodes: ['c', 'b', 'a']}), iD.Way({id: '~', nodes: ['c', 'd']}), iD.Relation({id: 'r', tags: {type: type}, members: [ - {id: '-', role: 'from'}, - {id: '~', role: 'to'}, - {id: 'c', role: 'via'}]}) + {id: '-', role: 'from', type: 'way'}, + {id: '~', role: 'to', type: 'way'}, + {id: 'c', role: 'via', type: 'node'} + ]}) ]); graph = iD.actionSplit('b', ['='])(graph); expect(graph.entity('r').members).to.eql([ - {id: '-', role: 'from'}, - {id: '~', role: 'to'}, - {id: 'c', role: 'via'}]); + {id: '-', role: 'from', type: 'way'}, + {id: '~', role: 'to', type: 'way'}, + {id: 'c', role: 'via', type: 'node'} + ]); }); }); });