From d7639acb22fba53006d2a8686d2394dd7179a84f Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 6 Feb 2013 13:29:43 -0800 Subject: [PATCH] Set up iD.actions.Join to be more flexible --- js/id/actions/join.js | 16 +++++++++++++++- js/id/operations/merge.js | 7 ++----- test/spec/actions/join.js | 22 +++++++++++----------- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/js/id/actions/join.js b/js/id/actions/join.js index a4fd913d8..7bba4783c 100644 --- a/js/id/actions/join.js +++ b/js/id/actions/join.js @@ -6,7 +6,15 @@ // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeWaysAction.as // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/CombineWayAction.java // -iD.actions.Join = function(idA, idB) { +iD.actions.Join = function(ids) { + var idA = ids[0], + idB = ids[1]; + + function groupEntitiesByGeometry(graph) { + var entities = ids.map(function(id) { return graph.entity(id); }); + return _.extend({line: []}, _.groupBy(entities, function(entity) { return entity.geometry(graph); })); + } + var action = function(graph) { var a = graph.entity(idA), b = graph.entity(idB), @@ -48,8 +56,14 @@ iD.actions.Join = function(idA, idB) { }; action.enabled = function(graph) { + var geometries = groupEntitiesByGeometry(graph); + + if (ids.length !== 2 || ids.length !== geometries['line'].length) + return false; + var a = graph.entity(idA), b = graph.entity(idB); + return a.first() === b.first() || a.first() === b.last() || a.last() === b.first() || diff --git a/js/id/operations/merge.js b/js/id/operations/merge.js index d02222368..b2073db52 100644 --- a/js/id/operations/merge.js +++ b/js/id/operations/merge.js @@ -1,5 +1,5 @@ iD.operations.Merge = function(selection, context) { - var action = iD.actions.Join(selection[0], selection[1]); + var action = iD.actions.Join(selection); var operation = function() { var annotation = t('operations.merge.annotation', {n: selection.length}), @@ -8,10 +8,7 @@ iD.operations.Merge = function(selection, context) { }; operation.available = function() { - return selection.length === 2 && - _.all(selection, function (id) { - return context.geometry(id) === 'line'; - }); + return selection.length > 1; }; operation.enabled = function() { diff --git a/test/spec/actions/join.js b/test/spec/actions/join.js index 88b4d5acc..11a95bc2d 100644 --- a/test/spec/actions/join.js +++ b/test/spec/actions/join.js @@ -10,7 +10,7 @@ describe("iD.actions.Join", function () { '=': iD.Way({id: '=', nodes: ['b', 'c']}) }); - expect(iD.actions.Join('-', '=').enabled(graph)).to.be.true; + expect(iD.actions.Join(['-', '=']).enabled(graph)).to.be.true; }); it("returns true for ways that share a start/end node", function () { @@ -23,7 +23,7 @@ describe("iD.actions.Join", function () { '=': iD.Way({id: '=', nodes: ['c', 'b']}) }); - expect(iD.actions.Join('-', '=').enabled(graph)).to.be.true; + expect(iD.actions.Join(['-', '=']).enabled(graph)).to.be.true; }); it("returns true for ways that share a start/start node", function () { @@ -36,7 +36,7 @@ describe("iD.actions.Join", function () { '=': iD.Way({id: '=', nodes: ['b', 'c']}) }); - expect(iD.actions.Join('-', '=').enabled(graph)).to.be.true; + expect(iD.actions.Join(['-', '=']).enabled(graph)).to.be.true; }); it("returns true for ways that share an end/end node", function () { @@ -49,7 +49,7 @@ describe("iD.actions.Join", function () { '=': iD.Way({id: '=', nodes: ['c', 'b']}) }); - expect(iD.actions.Join('-', '=').enabled(graph)).to.be.true; + expect(iD.actions.Join(['-', '=']).enabled(graph)).to.be.true; }); it("returns false for ways that don't share the necessary nodes", function () { @@ -65,7 +65,7 @@ describe("iD.actions.Join", function () { '=': iD.Way({id: '=', nodes: ['b', 'd']}) }); - expect(iD.actions.Join('-', '=').enabled(graph)).to.be.false; + expect(iD.actions.Join(['-', '=']).enabled(graph)).to.be.false; }); }); @@ -80,7 +80,7 @@ describe("iD.actions.Join", function () { '=': iD.Way({id: '=', nodes: ['b', 'c']}) }); - graph = iD.actions.Join('-', '=')(graph); + graph = iD.actions.Join(['-', '='])(graph); expect(graph.entity('-').nodes).to.eql(['a', 'b', 'c']); expect(graph.entity('=')).to.be.undefined; @@ -97,7 +97,7 @@ describe("iD.actions.Join", function () { '=': iD.Way({id: '=', nodes: ['c', 'b']}) }); - graph = iD.actions.Join('-', '=')(graph); + graph = iD.actions.Join(['-', '='])(graph); expect(graph.entity('-').nodes).to.eql(['c', 'b', 'a']); expect(graph.entity('=')).to.be.undefined; @@ -115,7 +115,7 @@ describe("iD.actions.Join", function () { '=': iD.Way({id: '=', nodes: ['b', 'c']}) }); - graph = iD.actions.Join('-', '=')(graph); + graph = iD.actions.Join(['-', '='])(graph); expect(graph.entity('-').nodes).to.eql(['c', 'b', 'a']); expect(graph.entity('=')).to.be.undefined; @@ -133,7 +133,7 @@ describe("iD.actions.Join", function () { '=': iD.Way({id: '=', nodes: ['c', 'b']}) }); - graph = iD.actions.Join('-', '=')(graph); + graph = iD.actions.Join(['-', '='])(graph); expect(graph.entity('-').nodes).to.eql(['a', 'b', 'c']); expect(graph.entity('=')).to.be.undefined; @@ -148,7 +148,7 @@ describe("iD.actions.Join", function () { '=': iD.Way({id: '=', nodes: ['b', 'c'], tags: {a: 'a', b: '=', d: 'd'}}) }); - graph = iD.actions.Join('-', '=')(graph); + graph = iD.actions.Join(['-', '='])(graph); expect(graph.entity('-').tags).to.eql({a: 'a', b: '-; =', c: 'c', d: 'd'}); }); @@ -164,7 +164,7 @@ describe("iD.actions.Join", function () { 'r2': iD.Relation({id: 'r2', members: [{id: '=', role: 'r2', type: 'way'}, {id: '-', role: 'r2', type: 'way'}]}) }); - graph = iD.actions.Join('-', '=')(graph); + graph = iD.actions.Join(['-', '='])(graph); expect(graph.entity('r1').members).to.eql([{id: '-', role: 'r1', type: 'way'}]); expect(graph.entity('r2').members).to.eql([{id: '-', role: 'r2', type: 'way'}]);