diff --git a/index.html b/index.html index 9de339471..51ddec95d 100644 --- a/index.html +++ b/index.html @@ -54,6 +54,7 @@ + diff --git a/js/id/actions/move_way.js b/js/id/actions/move_way.js new file mode 100644 index 000000000..0ef14e4f3 --- /dev/null +++ b/js/id/actions/move_way.js @@ -0,0 +1,14 @@ +iD.actions.MoveWay = function(wayId, dxdy, projection) { + return function(graph) { + var way = graph.entity(wayId); + + _.uniq(way.nodes).forEach(function(id) { + var node = graph.entity(id), + start = projection(node.loc), + end = projection.invert([start[0] + dxdy[0], start[1] + dxdy[1]]); + graph = iD.actions.MoveNode(id, end)(graph); + }); + + return graph; + }; +}; diff --git a/js/id/modes/select.js b/js/id/modes/select.js index e5f208992..c0553ac61 100644 --- a/js/id/modes/select.js +++ b/js/id/modes/select.js @@ -22,15 +22,7 @@ iD.modes.Select = function (entity) { mode.history.perform(iD.actions.Noop()); } - _.uniq(_.pluck(entity.nodes, 'id')) - .forEach(function(id) { - var node = mode.history.graph().entity(id), - start = mode.map.projection(node.loc), - end = mode.map.projection.invert([ - start[0] + d3.event.dx, - start[1] + d3.event.dy]); - mode.history.replace(iD.actions.Move(id, end)); - }); + mode.history.replace(iD.actions.MoveWay(entity.id, [d3.event.dx, d3.event.dy], mode.map.projection)); }) .on('dragend', function () { if (!dragging) return; diff --git a/test/index.html b/test/index.html index f66c872d4..c583acee9 100644 --- a/test/index.html +++ b/test/index.html @@ -55,6 +55,7 @@ + @@ -95,6 +96,7 @@ + diff --git a/test/index_packaged.html b/test/index_packaged.html index 1c197a5b7..2fdd8ab0f 100644 --- a/test/index_packaged.html +++ b/test/index_packaged.html @@ -32,6 +32,7 @@ + diff --git a/test/spec/actions/move_way.js b/test/spec/actions/move_way.js new file mode 100644 index 000000000..71c703e7f --- /dev/null +++ b/test/spec/actions/move_way.js @@ -0,0 +1,21 @@ +describe("iD.actions.MoveWay", function () { + it("moves all nodes in a way by the given amount", function () { + var node1 = iD.Node({loc: [0, 0]}), + node2 = iD.Node({loc: [5, 10]}), + way = iD.Way({nodes: [node1.id, node2.id]}), + dxdy = [2, 3], + projection = d3.geo.mercator(), + graph = iD.actions.MoveWay(way.id, dxdy, projection)(iD.Graph([node1, node2, way])); + expect(graph.entity(node1.id).loc).to.eql([1.4400000000000002, -2.1594885414215783]); + expect(graph.entity(node2.id).loc).to.eql([6.440000000000008, 7.866329874099955]); + }); + + it("moves repeated nodes only once", function () { + var node = iD.Node({loc: [0, 0]}), + way = iD.Way({nodes: [node.id, node.id]}), + dxdy = [2, 3], + projection = d3.geo.mercator(), + graph = iD.actions.MoveWay(way.id, dxdy, projection)(iD.Graph([node, way])); + expect(graph.entity(node.id).loc).to.eql([1.4400000000000002, -2.1594885414215783]); + }); +});