diff --git a/js/id/actions/split_way.js b/js/id/actions/split_way.js index de399df80..d716880cf 100644 --- a/js/id/actions/split_way.js +++ b/js/id/actions/split_way.js @@ -8,14 +8,21 @@ // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/SplitWayAction.as // iD.actions.SplitWay = function(nodeId, newWayId) { - return function(graph) { + function candidateWays(graph) { var node = graph.entity(nodeId), parents = graph.parentWays(node); - // splitting ways at intersections TODO - if (parents.length !== 1) return graph; + return parents.filter(function (parent) { + return parent.first() !== nodeId && + parent.last() !== nodeId; + }) + } - var way = parents[0], + var action = function(graph) { + if (!action.permitted(graph)) + return graph; + + var way = candidateWays(graph)[0], idx = _.indexOf(way.nodes, nodeId); // Create a 'b' way that contains all of the tags in the second @@ -58,4 +65,10 @@ iD.actions.SplitWay = function(nodeId, newWayId) { return graph; }; + + action.permitted = function(graph) { + return candidateWays(graph).length === 1; + }; + + return action; }; diff --git a/test/spec/actions/split_way.js b/test/spec/actions/split_way.js index e83d5ee1a..09bacb82a 100644 --- a/test/spec/actions/split_way.js +++ b/test/spec/actions/split_way.js @@ -1,4 +1,37 @@ describe("iD.actions.SplitWay", function () { + describe("#permitted", function () { + it("returns true for a non-end node of a single way", function () { + var graph = iD.Graph({ + 'a': iD.Node({id: 'a'}), + 'b': iD.Node({id: 'b'}), + 'c': iD.Node({id: 'c'}), + '-': iD.Way({id: '-', nodes: ['a', 'b', 'c']}) + }); + + expect(iD.actions.SplitWay('b').permitted(graph)).to.be.true; + }); + + it("returns false for the first node of a single way", function () { + var graph = iD.Graph({ + 'a': iD.Node({id: 'a'}), + 'b': iD.Node({id: 'b'}), + '-': iD.Way({id: '-', nodes: ['a', 'b']}) + }); + + expect(iD.actions.SplitWay('a').permitted(graph)).to.be.false; + }); + + it("returns false for the last node of a single way", function () { + var graph = iD.Graph({ + 'a': iD.Node({id: 'a'}), + 'b': iD.Node({id: 'b'}), + '-': iD.Way({id: '-', nodes: ['a', 'b']}) + }); + + expect(iD.actions.SplitWay('b').permitted(graph)).to.be.false; + }); + }); + it("creates a new way with the appropriate nodes", function () { // Situation: // a ---- b ---- c @@ -37,6 +70,35 @@ describe("iD.actions.SplitWay", function () { expect(graph.entity('=').tags).to.equal(tags); }); + it("splits a way at a T-junction", function () { + // Situation: + // a ---- b ---- c + // | + // d + // + // Split at b. + // + // Expected result: + // a ---- b ==== c + // | + // d + // + var graph = iD.Graph({ + 'a': iD.Node({id: 'a'}), + 'b': iD.Node({id: 'b'}), + 'c': iD.Node({id: 'c'}), + 'd': iD.Node({id: 'd'}), + '-': iD.Way({id: '-', nodes: ['a', 'b', 'c']}), + '|': iD.Way({id: '|', nodes: ['d', 'b']}) + }); + + graph = iD.actions.SplitWay('b', '=')(graph); + + expect(graph.entity('-').nodes).to.eql(['a', 'b']); + expect(graph.entity('=').nodes).to.eql(['b', 'c']); + expect(graph.entity('|').nodes).to.eql(['d', 'b']); + }); + it("adds the new way to parent relations (no connections)", function () { // Situation: // a ---- b ---- c