diff --git a/js/id/geo/intersection.js b/js/id/geo/intersection.js index 1451b1dd2..dab5b2fb2 100644 --- a/js/id/geo/intersection.js +++ b/js/id/geo/intersection.js @@ -19,8 +19,8 @@ iD.geo.Intersection = function(graph, vertexId) { highways.push(way); } else { var idx = _.indexOf(way.nodes, vertex.id, 1), - wayA = iD.Way({id: way.id + '.a', tags: way.tags, nodes: way.nodes.slice(0, idx + 1)}), - wayB = iD.Way({id: way.id + '.b', tags: way.tags, nodes: way.nodes.slice(idx)}); + wayA = iD.Way({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, idx + 1)}), + wayB = iD.Way({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(idx)}); graph = graph.replace(wayA); graph = graph.replace(wayB); @@ -64,45 +64,58 @@ iD.geo.Intersection = function(graph, vertexId) { return iD.geo.Turn(turn); } - var from = {node: way.nodes[way.first() === vertex.id ? 1 : way.nodes.length - 2], way: way.id}, - via = {node: vertex.id}, + var via = {node: vertex.id}, + ways = [], turns = []; - highways.forEach(function(parent) { - if (parent === way) - return; + if (way.affix(vertexId)) { + ways = [way]; + } else { + ways = [graph.entity(way.id + '-a'), graph.entity(way.id + '-b')]; + } - var index = parent.nodes.indexOf(vertex.id); + ways.forEach(function(way) { + var from = { + node: way.nodes[way.first() === vertex.id ? 1 : way.nodes.length - 2], + way: way.id.split(/-(a|b)/)[0] + }; - // backward - if (parent.first() !== vertex.id && parent.tags.oneway !== 'yes') { + highways.forEach(function(parent) { + if (parent === way) + return; + + var index = parent.nodes.indexOf(vertex.id); + + // backward + if (parent.first() !== vertex.id && parent.tags.oneway !== 'yes') { + turns.push(withRestriction({ + from: from, + via: via, + to: {node: parent.nodes[index - 1], way: parent.id.split(/-(a|b)/)[0]} + })); + } + + // forward + if (parent.last() !== vertex.id && parent.tags.oneway !== '-1') { + turns.push(withRestriction({ + from: from, + via: via, + to: {node: parent.nodes[index + 1], way: parent.id.split(/-(a|b)/)[0]} + })); + } + }); + + // U-turn + if (way.tags.oneway !== 'yes' && way.tags.oneway !== '-1') { turns.push(withRestriction({ from: from, via: via, - to: {node: parent.nodes[index - 1], way: parent.id.split('.')[0]} - })); - } - - // forward - if (parent.last() !== vertex.id && parent.tags.oneway !== '-1') { - turns.push(withRestriction({ - from: from, - via: via, - to: {node: parent.nodes[index + 1], way: parent.id.split('.')[0]} + to: from, + u: true })); } }); - // U-turn - if (way.tags.oneway !== 'yes' && way.tags.oneway !== '-1') { - turns.push(withRestriction({ - from: from, - via: via, - to: from, - u: true - })); - } - return turns; }; diff --git a/test/spec/geo/intersection.js b/test/spec/geo/intersection.js index fc7dbcd46..bcef423b5 100644 --- a/test/spec/geo/intersection.js +++ b/test/spec/geo/intersection.js @@ -49,7 +49,7 @@ describe("iD.geo.Intersection", function() { iD.Node({id: 'w'}), iD.Way({id: '=', nodes: ['u', '*', 'w'], tags: {highway: 'residential'}}) ]); - expect(_.pluck(iD.geo.Intersection(graph, '*').highways, 'id')).to.eql(['=.a', '=.b']); + expect(_.pluck(iD.geo.Intersection(graph, '*').highways, 'id')).to.eql(['=-a', '=-b']); }); }); @@ -92,7 +92,58 @@ describe("iD.geo.Intersection", function() { }); }); - it("permits turns onto a way in both directions", function() { + it("permits turns fom a way in both directions", function() { + // w + // | + // u===* + // | + // x + var graph = iD.Graph([ + iD.Node({id: 'u'}), + iD.Node({id: '*'}), + iD.Node({id: 'w'}), + iD.Node({id: 'x'}), + iD.Way({id: '=', nodes: ['u', '*'], tags: {highway: 'residential'}}), + iD.Way({id: '-', nodes: ['w', '*', 'x'], tags: {highway: 'residential'}}) + ]), + turns = iD.geo.Intersection(graph, '*').turns('-'); + + expect(turns.length).to.eql(6); + expect(turns[0]).to.eql({ + from: {node: 'w', way: '-'}, + via: {node: '*'}, + to: {node: 'u', way: '='} + }); + expect(turns[1]).to.eql({ + from: {node: 'w', way: '-'}, + via: {node: '*'}, + to: {node: 'x', way: '-'} + }); + expect(turns[2]).to.eql({ + from: {node: 'w', way: '-'}, + via: {node: '*'}, + to: {node: 'w', way: '-'}, + u: true + }); + expect(turns[3]).to.eql({ + from: {node: 'x', way: '-'}, + via: {node: '*'}, + to: {node: 'u', way: '='} + }); + expect(turns[4]).to.eql({ + from: {node: 'x', way: '-'}, + via: {node: '*'}, + to: {node: 'w', way: '-'} + }); + expect(turns[5]).to.eql({ + from: {node: 'x', way: '-'}, + via: {node: '*'}, + to: {node: 'x', way: '-'}, + u: true + }); + }); + + it("permits turns to a way in both directions", function() { // w // | // u===*