From d2d464d9ee8c220e524bbf52c8697cd3dcc3d3c6 Mon Sep 17 00:00:00 2001 From: Martin Raifer Date: Fri, 6 Apr 2018 11:30:16 +0200 Subject: [PATCH 1/4] only drop restrictions from FROM towards VIA when adding new only partially adresses bugs in #4968: * doesn't crash anymore in complex situations (short FROM ways where both ends connect to a TO way) * adding a only-restriction at one end of a short FROM doesn't delete restrictions on the other end of the same FROM anymore --- modules/osm/intersection.js | 14 ++++++-------- modules/ui/fields/restrictions.js | 4 ++-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/modules/osm/intersection.js b/modules/osm/intersection.js index 9d0b7a83c..384961f53 100644 --- a/modules/osm/intersection.js +++ b/modules/osm/intersection.js @@ -408,22 +408,20 @@ export function osmIntersection(graph, startVertexId, maxDistance) { var isAlongOnlyPath = false; if (t.id === way.id) { // match VIA, TO - if (v.length === 1 && v[0].type === 'node' && v[0].id === entity.id) { - matchesViaTo = true; // match VIA node - - } else { // match all VIA ways + if (v.length === 1 && v[0].type === 'node') { // match VIA node + matchesViaTo = v[0].id === entity.id; + } else { // match all VIA ways var pathVias = []; - for (k = 1; k < currPath.length; k++) { // k = 1 skips FROM way - if (currPath[k][0] === 'w') pathVias.push(currPath[k]); + for (k = 2; k < currPath.length; k+=2) { // k = 1 skips FROM way + pathVias.push(currPath[k]); } var restrictionVias = []; for (k = 0; k < v.length; k++) { - if (v[k].type === 'way') restrictionVias.push(v[k].id); + restrictionVias.push(v[k].id); } var diff = _difference(pathVias, restrictionVias); matchesViaTo = !diff.length; } - } else if (isOnly) { for (k = 0; k < v.length; k++) { // way doesn't match TO, but is one of the via ways along the path of an "only" diff --git a/modules/ui/fields/restrictions.js b/modules/ui/fields/restrictions.js index 23e3e0f5e..32e6e9790 100644 --- a/modules/ui/fields/restrictions.js +++ b/modules/ui/fields/restrictions.js @@ -359,13 +359,13 @@ export function uiFieldRestrictions(field, context) { datumOnly.only = true; restrictionType = restrictionType.replace(/^no/, 'only'); - // Adding an ONLY restriction should destroy all other direct restrictions from the FROM. + // Adding an ONLY restriction should destroy all other direct restrictions from the FROM towards the VIA. // We will remember them in _oldTurns, and restore them if the user clicks again. turns = _intersection.turns(_fromWayID, 2); extraActions = []; _oldTurns = []; for (i = 0; i < turns.length; i++) { - if (turns[i].direct) { + if (turns[i].direct && turns[i].path[1] === datum.path[1]) { turns[i].restrictionType = osmInferRestriction(vgraph, turns[i], projection); _oldTurns.push(turns[i]); extraActions.push(actionUnrestrictTurn(turns[i])); From 56dba67b426512c684751afbc7336f71d34ebb7b Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Tue, 10 Apr 2018 22:11:06 -0400 Subject: [PATCH 2/4] Add via 2 way tests --- test/spec/osm/intersection.js | 240 +++++++++++++++++++++++++++++++++- 1 file changed, 235 insertions(+), 5 deletions(-) diff --git a/test/spec/osm/intersection.js b/test/spec/osm/intersection.js index 01a822b2f..ab0655e14 100644 --- a/test/spec/osm/intersection.js +++ b/test/spec/osm/intersection.js @@ -680,7 +680,7 @@ describe('iD.osmIntersection', function() { members: [ { role: 'from', id: '|', type: 'way' }, { role: 'via', id: 'e', type: 'node' }, - { role: 'to', id: '≈', type: 'way' }, + { role: 'to', id: '≈', type: 'way' } ] }) ]); @@ -789,7 +789,7 @@ describe('iD.osmIntersection', function() { members: [ { role: 'from', id: '/', type: 'way' }, { role: 'via', id: '|', type: 'way' }, - { role: 'to', id: '≈', type: 'way' }, + { role: 'to', id: '≈', type: 'way' } ] }) ]); @@ -889,7 +889,7 @@ describe('iD.osmIntersection', function() { members: [ { role: 'from', id: '|', type: 'way' }, { role: 'via', id: 'e', type: 'node' }, - { role: 'to', id: '≈', type: 'way' }, + { role: 'to', id: '≈', type: 'way' } ] }) ]); @@ -1045,7 +1045,7 @@ describe('iD.osmIntersection', function() { members: [ { role: 'from', id: '=', type: 'way' }, { role: 'via', id: '|', type: 'way' }, - { role: 'to', id: '≈', type: 'way' }, + { role: 'to', id: '≈', type: 'way' } ] }), iD.osmRelation({ @@ -1054,7 +1054,7 @@ describe('iD.osmIntersection', function() { members: [ { role: 'from', id: '/', type: 'way' }, { role: 'via', id: '|', type: 'way' }, - { role: 'to', id: '≈', type: 'way' }, + { role: 'to', id: '≈', type: 'way' } ] }) ]); @@ -1170,6 +1170,236 @@ describe('iD.osmIntersection', function() { }); }); + describe('complex intersection - via 2 ways', function() { + // + // a <--- b <=== c + // | + // * + // ‖ + // d ~~~> e ≈≈≈> f + // + var graph = iD.coreGraph([ + iD.osmNode({id: 'a'}), + iD.osmNode({id: 'b'}), + iD.osmNode({id: 'c'}), + iD.osmNode({id: 'd'}), + iD.osmNode({id: 'e'}), + iD.osmNode({id: 'f'}), + iD.osmNode({id: '*'}), + iD.osmWay({id: '-', nodes: ['b', 'a'], tags: {highway: 'residential', oneway: 'yes'}}), + iD.osmWay({id: '=', nodes: ['c', 'b'], tags: {highway: 'residential', oneway: 'yes'}}), + iD.osmWay({id: '~', nodes: ['d', 'e'], tags: {highway: 'residential', oneway: 'yes'}}), + iD.osmWay({id: '≈', nodes: ['e', 'f'], tags: {highway: 'residential', oneway: 'yes'}}), + iD.osmWay({id: '|', nodes: ['b', '*'], tags: {highway: 'residential'}}), + iD.osmWay({id: '‖', nodes: ['*', 'e'], tags: {highway: 'residential'}}) + ]); + + it('with no restrictions, allows via node and via way turns', function() { + var turns; + turns = iD.osmIntersection(graph, 'b').turns('=', 2); + expect(turns.length).to.eql(4); + + expect(turns[0]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[0].key).to.eql('=_b_-'); // straight to - + expect(turns[0].u).to.be.not.ok; + + expect(turns[1]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[1].key).to.eql('=_b_|'); // left to | + expect(turns[1].u).to.be.not.ok; + + expect(turns[2]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[2].key).to.eql('=_b_|_*_‖'); // left to ‖ via | + expect(turns[2].u).to.be.not.ok; + + expect(turns[3]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[3].key).to.eql('=_b_|_*_‖_e_≈'); // u-turn via |,‖ to ≈ + expect(turns[3].u).to.be.not.ok; + }); + + + it('supports `no_` via 2 way restriction (ordered)', function() { + // 'r1': `no_u_turn` FROM '=' VIA WAYS '|','‖' TO '≈' + var r1 = iD.osmRelation({ + id: 'r1', + tags: { type: 'restriction', restriction: 'no_u_turn' }, + members: [ + { role: 'from', id: '=', type: 'way' }, + { role: 'via', id: '|', type: 'way' }, + { role: 'via', id: '‖', type: 'way' }, + { role: 'to', id: '≈', type: 'way' } + ] + }); + graph = graph.replace(r1); + + var turns; + turns = iD.osmIntersection(graph, 'b').turns('=', 2); + expect(turns.length).to.eql(4); + + expect(turns[0]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[0].key).to.eql('=_b_-'); // straight to - + expect(turns[0].u).to.be.not.ok; + + expect(turns[1]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[1].key).to.eql('=_b_|'); // left to | + expect(turns[1].u).to.be.not.ok; + + expect(turns[2]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[2].key).to.eql('=_b_|_*_‖'); // left to ‖ via | + expect(turns[2].u).to.be.not.ok; + + expect(turns[3]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[3].key).to.eql('=_b_|_*_‖_e_≈'); // u-turn via |,‖ to ≈ + expect(turns[3].u).to.be.not.ok; + expect(turns[3].restrictionID).to.eql('r1'); + expect(turns[3].direct).to.be.true; // direct + expect(turns[3].no).to.be.true; // restricted! + expect(turns[3].only).to.be.not.ok; + }); + + + it('supports `no_` via 2 way restriction (unordered)', function() { + // 'r1': `no_u_turn` FROM '=' VIA WAYS '|','‖' TO '≈' + var r1 = iD.osmRelation({ + id: 'r1', + tags: { type: 'restriction', restriction: 'no_u_turn' }, + members: [ + { role: 'from', id: '=', type: 'way' }, + { role: 'via', id: '‖', type: 'way' }, // out of order + { role: 'via', id: '|', type: 'way' }, // out of order + { role: 'to', id: '≈', type: 'way' } + ] + }); + graph = graph.replace(r1); + + var turns; + turns = iD.osmIntersection(graph, 'b').turns('=', 2); + expect(turns.length).to.eql(4); + + expect(turns[0]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[0].key).to.eql('=_b_-'); // straight to - + expect(turns[0].u).to.be.not.ok; + + expect(turns[1]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[1].key).to.eql('=_b_|'); // left to | + expect(turns[1].u).to.be.not.ok; + + expect(turns[2]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[2].key).to.eql('=_b_|_*_‖'); // left to ‖ via | + expect(turns[2].u).to.be.not.ok; + + expect(turns[3]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[3].key).to.eql('=_b_|_*_‖_e_≈'); // u-turn via |,‖ to ≈ + expect(turns[3].u).to.be.not.ok; + expect(turns[3].restrictionID).to.eql('r1'); + expect(turns[3].direct).to.be.true; // direct + expect(turns[3].no).to.be.true; // restricted! + expect(turns[3].only).to.be.not.ok; + }); + + + it('supports `only_` via 2 way restriction (ordered)', function() { + // 'r1': `only_u_turn` FROM '=' VIA WAYS '|','‖' TO '≈' + var r1 = iD.osmRelation({ + id: 'r1', + tags: { type: 'restriction', restriction: 'only_u_turn' }, + members: [ + { role: 'from', id: '=', type: 'way' }, + { role: 'via', id: '|', type: 'way' }, + { role: 'via', id: '‖', type: 'way' }, + { role: 'to', id: '≈', type: 'way' } + ] + }); + graph = graph.replace(r1); + + var turns; + turns = iD.osmIntersection(graph, 'b').turns('=', 2); + expect(turns.length).to.eql(4); + + expect(turns[0]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[0].key).to.eql('=_b_-'); // straight to - + expect(turns[0].u).to.be.not.ok; + expect(turns[0].restrictionID).to.eql('r1'); + expect(turns[0].direct).to.be.false; // indirect + expect(turns[0].no).to.be.true; // restricted! + expect(turns[0].only).to.be.not.ok; + + expect(turns[1]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[1].key).to.eql('=_b_|'); // left to | + expect(turns[1].u).to.be.not.ok; + expect(turns[1].restrictionID).to.eql('r1'); + expect(turns[1].direct).to.be.false; // indirect + expect(turns[1].no).to.be.not.ok; + expect(turns[1].only).to.be.true; // only (along via path) + + expect(turns[2]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[2].key).to.eql('=_b_|_*_‖'); // left to ‖ via | + expect(turns[2].u).to.be.not.ok; + expect(turns[2].restrictionID).to.eql('r1'); + expect(turns[2].direct).to.be.false; // indirect + expect(turns[2].no).to.be.not.ok; + expect(turns[2].only).to.be.true; // only (along via path) + + expect(turns[3]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[3].key).to.eql('=_b_|_*_‖_e_≈'); // u-turn via |,‖ to ≈ + expect(turns[3].u).to.be.not.ok; + expect(turns[3].restrictionID).to.eql('r1'); + expect(turns[3].direct).to.be.true; // direct + expect(turns[3].no).to.be.not.ok; + expect(turns[3].only).to.be.true; // only! + }); + + it('supports `only_` via 2 way restriction (unordered)', function() { + // 'r1': `only_u_turn` FROM '=' VIA WAYS '‖','|' TO '≈' + var r1 = iD.osmRelation({ + id: 'r1', + tags: { type: 'restriction', restriction: 'only_u_turn' }, + members: [ + { role: 'from', id: '=', type: 'way' }, + { role: 'via', id: '‖', type: 'way' }, // out of order + { role: 'via', id: '|', type: 'way' }, // out of order + { role: 'to', id: '≈', type: 'way' } + ] + }); + graph = graph.replace(r1); + + var turns; + turns = iD.osmIntersection(graph, 'b').turns('=', 2); + expect(turns.length).to.eql(4); + + expect(turns[0]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[0].key).to.eql('=_b_-'); // straight to - + expect(turns[0].u).to.be.not.ok; + expect(turns[0].restrictionID).to.eql('r1'); + expect(turns[0].direct).to.be.false; // indirect + expect(turns[0].no).to.be.true; // restricted! + expect(turns[0].only).to.be.not.ok; + + expect(turns[1]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[1].key).to.eql('=_b_|'); // left to | + expect(turns[1].u).to.be.not.ok; + expect(turns[1].restrictionID).to.eql('r1'); + expect(turns[1].direct).to.be.false; // indirect + expect(turns[1].no).to.be.not.ok; + expect(turns[1].only).to.be.true; // only (along via path) + + expect(turns[2]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[2].key).to.eql('=_b_|_*_‖'); // left to ‖ via | + expect(turns[2].u).to.be.not.ok; + expect(turns[2].restrictionID).to.eql('r1'); + expect(turns[2].direct).to.be.false; // indirect + expect(turns[2].no).to.be.not.ok; + expect(turns[2].only).to.be.true; // only (along via path) + + expect(turns[3]).to.be.an.instanceOf(iD.osmTurn); + expect(turns[3].key).to.eql('=_b_|_*_‖_e_≈'); // u-turn via |,‖ to ≈ + expect(turns[3].u).to.be.not.ok; + expect(turns[3].restrictionID).to.eql('r1'); + expect(turns[3].direct).to.be.true; // direct + expect(turns[3].no).to.be.not.ok; + expect(turns[3].only).to.be.true; // only! + }); + }); + }); }); From 540f0f11dd003b1927b2dab704b9325ecaa16f29 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Wed, 11 Apr 2018 00:24:20 -0400 Subject: [PATCH 3/4] Add failing test for alternate path matching a restrictionID --- test/spec/osm/intersection.js | 164 ++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) diff --git a/test/spec/osm/intersection.js b/test/spec/osm/intersection.js index ab0655e14..3b18f397f 100644 --- a/test/spec/osm/intersection.js +++ b/test/spec/osm/intersection.js @@ -1400,6 +1400,170 @@ describe('iD.osmIntersection', function() { }); }); + + describe('complex intersection - via 2 ways with loops - gotchas', function() { + // + // e + // / \ + // / \ + // a --- b === c ~~~ d + // + var graph = iD.coreGraph([ + iD.osmNode({id: 'a'}), + iD.osmNode({id: 'b'}), + iD.osmNode({id: 'c'}), + iD.osmNode({id: 'd'}), + iD.osmNode({id: 'e'}), + iD.osmWay({id: '-', nodes: ['a', 'b'], tags: {highway: 'residential'}}), + iD.osmWay({id: '=', nodes: ['b', 'c'], tags: {highway: 'residential'}}), + iD.osmWay({id: '~', nodes: ['c', 'd'], tags: {highway: 'residential'}}), + iD.osmWay({id: '/', nodes: ['b', 'e'], tags: {highway: 'residential'}}), + iD.osmWay({id: '\\', nodes: ['e', 'c'], tags: {highway: 'residential'}}) + ]); + + it('with no restrictions, finds all turns', function() { + var turns = iD.osmIntersection(graph, 'c').turns('=', 2); + expect(turns.length).to.eql(10); + + expect(turns[0].key).to.eql('=_b_='); + expect(turns[0].u).to.be.true; + + expect(turns[1].key).to.eql('=_b_/'); + expect(turns[1].u).to.be.not.ok; + + expect(turns[2].key).to.eql('=_b_/_e_\\'); + expect(turns[2].u).to.be.not.ok; + + expect(turns[3].key).to.eql('=_b_/_e_\\_c_~'); + expect(turns[3].u).to.be.not.ok; + + expect(turns[4].key).to.eql('=_b_-'); + expect(turns[4].u).to.be.not.ok; + + expect(turns[5].key).to.eql('=_c_='); + expect(turns[5].u).to.be.true; + + expect(turns[6].key).to.eql('=_c_~'); + expect(turns[6].u).to.be.not.ok; + + expect(turns[7].key).to.eql('=_c_\\'); + expect(turns[7].u).to.be.not.ok; + + expect(turns[8].key).to.eql('=_c_\\_e_/'); + expect(turns[8].u).to.be.not.ok; + + expect(turns[9].key).to.eql('=_c_\\_e_/_b_-'); + expect(turns[9].u).to.be.not.ok; + }); + + it('matches from-via-to strictly when alternate paths exist between from and to', function() { + var r1 = iD.osmRelation({ + id: 'r1', + tags: { type: 'restriction', restriction: 'no_straight_on' }, + members: [ + { role: 'from', id: '=', type: 'way' }, + { role: 'via', id: 'c', type: 'node' }, + { role: 'to', id: '~', type: 'way' } + ] + }); + graph = graph.replace(r1); + + var turns = iD.osmIntersection(graph, 'c').turns('=', 2); + expect(turns.length).to.eql(10); + + expect(turns[0].key).to.eql('=_b_='); + expect(turns[0].u).to.be.true; + + expect(turns[1].key).to.eql('=_b_/'); + expect(turns[1].u).to.be.not.ok; + + expect(turns[2].key).to.eql('=_b_/_e_\\'); + expect(turns[2].u).to.be.not.ok; + + expect(turns[3].key).to.eql('=_b_/_e_\\_c_~'); + expect(turns[3].u).to.be.not.ok; + expect(turns[3].restrictionID).to.be.undefined; // the alternate path should not match + expect(turns[3].direct).to.be.undefined; + + expect(turns[4].key).to.eql('=_b_-'); + expect(turns[4].u).to.be.not.ok; + + expect(turns[5].key).to.eql('=_c_='); + expect(turns[5].u).to.be.true; + + expect(turns[6].key).to.eql('=_c_~'); + expect(turns[6].u).to.be.not.ok; + expect(turns[6].restrictionID).to.eql('r1'); + expect(turns[6].direct).to.be.true; // direct + expect(turns[6].no).to.be.true; // restricted! + expect(turns[6].only).to.be.not.ok; + + expect(turns[7].key).to.eql('=_c_\\'); + expect(turns[7].u).to.be.not.ok; + + expect(turns[8].key).to.eql('=_c_\\_e_/'); + expect(turns[8].u).to.be.not.ok; + + expect(turns[9].key).to.eql('=_c_\\_e_/_b_-'); + expect(turns[9].u).to.be.not.ok; + }); + + + it('`only_` restriction is only effective towards the via', function() { + var r1 = iD.osmRelation({ + id: 'r1', + tags: { type: 'restriction', restriction: 'only_straight_on' }, + members: [ + { role: 'from', id: '=', type: 'way' }, + { role: 'via', id: 'c', type: 'node' }, + { role: 'to', id: '~', type: 'way' } + ] + }); + graph = graph.replace(r1); + + var turns = iD.osmIntersection(graph, 'c').turns('=', 2); + expect(turns.length).to.eql(8); + + expect(turns[0].key).to.eql('=_b_='); // not towards via + expect(turns[0].u).to.be.true; + + expect(turns[1].key).to.eql('=_b_/'); // not towards via + expect(turns[1].u).to.be.not.ok; + + expect(turns[2].key).to.eql('=_b_/_e_\\'); // not towards via + expect(turns[2].u).to.be.not.ok; + + expect(turns[3].key).to.eql('=_b_/_e_\\_c_~'); // not towards via + expect(turns[3].u).to.be.not.ok; + expect(turns[3].restrictionID).to.be.undefined; // the alternate path should not match + expect(turns[3].direct).to.be.undefined; + + expect(turns[4].key).to.eql('=_b_-'); // not towards via + expect(turns[4].u).to.be.not.ok; + + expect(turns[5].key).to.eql('=_c_='); + expect(turns[5].u).to.be.true; + expect(turns[5].restrictionID).to.eql('r1'); + expect(turns[5].direct).to.be.false; // indirect + expect(turns[5].no).to.be.true; // restricted! + expect(turns[5].only).to.be.not.ok; + + expect(turns[6].key).to.eql('=_c_~'); + expect(turns[6].u).to.be.not.ok; + expect(turns[6].restrictionID).to.eql('r1'); + expect(turns[6].direct).to.be.true; // direct + expect(turns[6].no).to.be.not.ok; + expect(turns[6].only).to.be.true; // only! + + expect(turns[7].key).to.eql('=_c_\\'); + expect(turns[7].u).to.be.not.ok; + expect(turns[7].restrictionID).to.eql('r1'); + expect(turns[7].direct).to.be.false; // indirect + expect(turns[7].no).to.be.true; // restricted! + expect(turns[7].only).to.be.not.ok; + }); + }); + }); }); From d20c537e46a864b008db98bdfc24f81adb6c88a0 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Wed, 11 Apr 2018 22:54:49 -0400 Subject: [PATCH 4/4] Don't match a simple from-via-to restriction by taking a longer path --- modules/osm/intersection.js | 22 +++++++++++++++------- test/spec/osm/intersection.js | 2 +- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/modules/osm/intersection.js b/modules/osm/intersection.js index 384961f53..b145c5833 100644 --- a/modules/osm/intersection.js +++ b/modules/osm/intersection.js @@ -407,21 +407,29 @@ export function osmIntersection(graph, startVertexId, maxDistance) { var matchesViaTo = false; var isAlongOnlyPath = false; - if (t.id === way.id) { // match VIA, TO - if (v.length === 1 && v[0].type === 'node') { // match VIA node - matchesViaTo = v[0].id === entity.id; - } else { // match all VIA ways + if (t.id === way.id) { // match TO + + if (v.length === 1 && v[0].type === 'node') { // match VIA node + matchesViaTo = (v[0].id === entity.id && ( + (matchesFrom && currPath.length === 2) || + (!matchesFrom && currPath.length > 2) + )); + + } else { // match all VIA ways var pathVias = []; - for (k = 2; k < currPath.length; k+=2) { // k = 1 skips FROM way - pathVias.push(currPath[k]); + for (k = 2; k < currPath.length; k +=2 ) { // k = 2 skips FROM + pathVias.push(currPath[k]); // (path goes way-node-way...) } var restrictionVias = []; for (k = 0; k < v.length; k++) { - restrictionVias.push(v[k].id); + if (v[k].type === 'way') { + restrictionVias.push(v[k].id); + } } var diff = _difference(pathVias, restrictionVias); matchesViaTo = !diff.length; } + } else if (isOnly) { for (k = 0; k < v.length; k++) { // way doesn't match TO, but is one of the via ways along the path of an "only" diff --git a/test/spec/osm/intersection.js b/test/spec/osm/intersection.js index 3b18f397f..ecb23a265 100644 --- a/test/spec/osm/intersection.js +++ b/test/spec/osm/intersection.js @@ -1456,7 +1456,7 @@ describe('iD.osmIntersection', function() { expect(turns[9].u).to.be.not.ok; }); - it('matches from-via-to strictly when alternate paths exist between from and to', function() { + it('matches from-via-to strictly when alternate paths exist between from-via-to', function() { var r1 = iD.osmRelation({ id: 'r1', tags: { type: 'restriction', restriction: 'no_straight_on' },