mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-15 05:30:35 +02:00
Fix moving multiple entities which share nodes
While here, implement moving multipolygons too.
This commit is contained in:
+2
-2
@@ -81,7 +81,7 @@
|
||||
<script src="js/id/actions/delete_way.js"></script>
|
||||
<script src='js/id/actions/disconnect.js'></script>
|
||||
<script src='js/id/actions/move_node.js'></script>
|
||||
<script src='js/id/actions/move_way.js'></script>
|
||||
<script src='js/id/actions/move.js'></script>
|
||||
<script src='js/id/actions/circularize.js'></script>
|
||||
<script src='js/id/actions/noop.js'></script>
|
||||
<script src='js/id/actions/reverse.js'></script>
|
||||
@@ -103,7 +103,7 @@
|
||||
<script src='js/id/modes/browse.js'></script>
|
||||
<script src='js/id/modes/draw_area.js'></script>
|
||||
<script src='js/id/modes/draw_line.js'></script>
|
||||
<script src='js/id/modes/move_way.js'></script>
|
||||
<script src='js/id/modes/move.js'></script>
|
||||
<script src='js/id/modes/select.js'></script>
|
||||
|
||||
<script src='js/id/operations.js'></script>
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@
|
||||
<script src='js/id/actions/join.js'></script>
|
||||
<script src='js/id/actions/merge.js'></script>
|
||||
<script src='js/id/actions/move_node.js'></script>
|
||||
<script src='js/id/actions/move_way.js'></script>
|
||||
<script src='js/id/actions/move.js'></script>
|
||||
<script src='js/id/actions/circularize.js'></script>
|
||||
<script src='js/id/actions/orthogonalize.js'></script>
|
||||
<script src='js/id/actions/noop.js'></script>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
|
||||
// https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
|
||||
iD.actions.Move = function(ids, delta, projection) {
|
||||
function addNodes(ids, nodes, graph) {
|
||||
ids.forEach(function(id) {
|
||||
var entity = graph.entity(id);
|
||||
if (entity.type === 'node') {
|
||||
nodes.push(id);
|
||||
} else if (entity.type === 'way') {
|
||||
nodes.push.apply(nodes, entity.nodes);
|
||||
} else {
|
||||
addNodes(_.pluck(entity.members, 'id'), nodes, graph);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return function(graph) {
|
||||
var nodes = [];
|
||||
|
||||
addNodes(ids, nodes, graph);
|
||||
|
||||
_.uniq(nodes).forEach(function(id) {
|
||||
var node = graph.entity(id),
|
||||
start = projection(node.loc),
|
||||
end = projection.invert([start[0] + delta[0], start[1] + delta[1]]);
|
||||
graph = graph.replace(node.move(end));
|
||||
});
|
||||
|
||||
return graph;
|
||||
};
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
iD.actions.MoveWay = function(wayId, delta, projection) {
|
||||
return function(graph) {
|
||||
return graph.update(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] + delta[0], start[1] + delta[1]]);
|
||||
graph = graph.replace(node.move(end));
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
+6
-17
@@ -4,14 +4,13 @@ iD.modes.Move = function(context, entityIDs) {
|
||||
button: 'browse'
|
||||
};
|
||||
|
||||
var keybinding = d3.keybinding('move'),
|
||||
entities = entityIDs.map(context.entity);
|
||||
var keybinding = d3.keybinding('move');
|
||||
|
||||
mode.enter = function() {
|
||||
var origin,
|
||||
nudgeInterval,
|
||||
annotation = entities.length === 1 ?
|
||||
t('operations.move.annotation.' + context.geometry(entities[0].id)) :
|
||||
annotation = entityIDs.length === 1 ?
|
||||
t('operations.move.annotation.' + context.geometry(entityIDs[0])) :
|
||||
t('operations.move.annotation.multiple');
|
||||
|
||||
context.perform(
|
||||
@@ -57,19 +56,9 @@ iD.modes.Move = function(context, entityIDs) {
|
||||
|
||||
origin = context.map().mouseCoordinates();
|
||||
|
||||
entities.forEach(function(entity) {
|
||||
if (entity.type === 'way') {
|
||||
context.replace(
|
||||
iD.actions.MoveWay(entity.id, delta, context.projection));
|
||||
} else if (entity.type === 'node') {
|
||||
var start = context.projection(context.entity(entity.id).loc),
|
||||
end = [start[0] + delta[0], start[1] + delta[1]],
|
||||
loc = context.projection.invert(end);
|
||||
context.replace(iD.actions.MoveNode(entity.id, loc));
|
||||
}
|
||||
});
|
||||
|
||||
context.replace(iD.actions.Noop(), annotation);
|
||||
context.replace(
|
||||
iD.actions.Move(entityIDs, delta, context.projection),
|
||||
annotation);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
|
||||
@@ -6,7 +6,7 @@ iD.operations.Move = function(selection, context) {
|
||||
|
||||
operation.available = function() {
|
||||
return selection.length > 1 ||
|
||||
context.entity(selection[0]).type === 'way';
|
||||
context.entity(selection[0]).type !== 'node';
|
||||
};
|
||||
|
||||
operation.enabled = function() {
|
||||
|
||||
+2
-2
@@ -96,7 +96,7 @@
|
||||
<script src='../js/id/actions/join.js'></script>
|
||||
<script src='../js/id/actions/merge.js'></script>
|
||||
<script src='../js/id/actions/move_node.js'></script>
|
||||
<script src='../js/id/actions/move_way.js'></script>
|
||||
<script src='../js/id/actions/move.js'></script>
|
||||
<script src='../js/id/actions/noop.js'></script>
|
||||
<script src='../js/id/actions/reverse.js'></script>
|
||||
<script src='../js/id/actions/split.js'></script>
|
||||
@@ -177,7 +177,7 @@
|
||||
<script src="spec/actions/join.js"></script>
|
||||
<script src='spec/actions/merge.js'></script>
|
||||
<script src="spec/actions/move_node.js"></script>
|
||||
<script src="spec/actions/move_way.js"></script>
|
||||
<script src="spec/actions/move.js"></script>
|
||||
<script src="spec/actions/noop.js"></script>
|
||||
<script src="spec/actions/reverse.js"></script>
|
||||
<script src="spec/actions/split.js"></script>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
<script src="spec/actions/join.js"></script>
|
||||
<script src='spec/actions/merge.js'></script>
|
||||
<script src="spec/actions/move_node.js"></script>
|
||||
<script src="spec/actions/move_way.js"></script>
|
||||
<script src="spec/actions/move.js"></script>
|
||||
<script src="spec/actions/noop.js"></script>
|
||||
<script src="spec/actions/reverse.js"></script>
|
||||
<script src="spec/actions/split.js"></script>
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
describe("iD.actions.Move", 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]}),
|
||||
delta = [2, 3],
|
||||
projection = d3.geo.mercator(),
|
||||
graph = iD.actions.Move([way.id], delta, projection)(iD.Graph([node1, node2, way])),
|
||||
loc1 = graph.entity(node1.id).loc,
|
||||
loc2 = graph.entity(node2.id).loc;
|
||||
expect(loc1[0]).to.be.closeTo( 1.440, 0.001);
|
||||
expect(loc1[1]).to.be.closeTo(-2.159, 0.001);
|
||||
expect(loc2[0]).to.be.closeTo( 6.440, 0.001);
|
||||
expect(loc2[1]).to.be.closeTo( 7.866, 0.001);
|
||||
});
|
||||
|
||||
it("moves repeated nodes only once", function() {
|
||||
var node = iD.Node({loc: [0, 0]}),
|
||||
way = iD.Way({nodes: [node.id, node.id]}),
|
||||
delta = [2, 3],
|
||||
projection = d3.geo.mercator(),
|
||||
graph = iD.actions.Move([way.id], delta, projection)(iD.Graph([node, way])),
|
||||
loc = graph.entity(node.id).loc;
|
||||
expect(loc[0]).to.be.closeTo( 1.440, 0.001);
|
||||
expect(loc[1]).to.be.closeTo(-2.159, 0.001);
|
||||
});
|
||||
|
||||
it("moves multiple ways", function() {
|
||||
var node = iD.Node({loc: [0, 0]}),
|
||||
way1 = iD.Way({nodes: [node.id]}),
|
||||
way2 = iD.Way({nodes: [node.id]}),
|
||||
delta = [2, 3],
|
||||
projection = d3.geo.mercator(),
|
||||
graph = iD.actions.Move([way1.id, way2.id], delta, projection)(iD.Graph([node, way1, way2])),
|
||||
loc = graph.entity(node.id).loc;
|
||||
expect(loc[0]).to.be.closeTo( 1.440, 0.001);
|
||||
expect(loc[1]).to.be.closeTo(-2.159, 0.001);
|
||||
});
|
||||
|
||||
it("moves leaf nodes of a relation", function() {
|
||||
var node = iD.Node({loc: [0, 0]}),
|
||||
way = iD.Way({nodes: [node.id]}),
|
||||
relation = iD.Relation({members: [{id: way.id}]}),
|
||||
delta = [2, 3],
|
||||
projection = d3.geo.mercator(),
|
||||
graph = iD.actions.Move([relation.id], delta, projection)(iD.Graph([node, way, relation])),
|
||||
loc = graph.entity(node.id).loc;
|
||||
expect(loc[0]).to.be.closeTo( 1.440, 0.001);
|
||||
expect(loc[1]).to.be.closeTo(-2.159, 0.001);
|
||||
});
|
||||
});
|
||||
@@ -1,27 +0,0 @@
|
||||
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]}),
|
||||
delta = [2, 3],
|
||||
projection = d3.geo.mercator(),
|
||||
graph = iD.actions.MoveWay(way.id, delta, projection)(iD.Graph([node1, node2, way])),
|
||||
loc1 = graph.entity(node1.id).loc,
|
||||
loc2 = graph.entity(node2.id).loc;
|
||||
expect(loc1[0]).to.be.closeTo( 1.440, 0.001);
|
||||
expect(loc1[1]).to.be.closeTo(-2.159, 0.001);
|
||||
expect(loc2[0]).to.be.closeTo( 6.440, 0.001);
|
||||
expect(loc2[1]).to.be.closeTo( 7.866, 0.001);
|
||||
});
|
||||
|
||||
it("moves repeated nodes only once", function() {
|
||||
var node = iD.Node({loc: [0, 0]}),
|
||||
way = iD.Way({nodes: [node.id, node.id]}),
|
||||
delta = [2, 3],
|
||||
projection = d3.geo.mercator(),
|
||||
graph = iD.actions.MoveWay(way.id, delta, projection)(iD.Graph([node, way])),
|
||||
loc = graph.entity(node.id).loc;
|
||||
expect(loc[0]).to.be.closeTo( 1.440, 0.001);
|
||||
expect(loc[1]).to.be.closeTo(-2.159, 0.001);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user