source: josm/trunk/src/org/openstreetmap/josm/command/MoveCommand.java@ 6538

Last change on this file since 6538 was 6380, checked in by Don-vip, 10 years ago

update license/copyright information

  • Property svn:eol-style set to native
File size: 6.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.command;
3
4import static org.openstreetmap.josm.tools.I18n.trn;
5
6import java.util.Collection;
7import java.util.Collections;
8import java.util.Iterator;
9import java.util.LinkedList;
10import java.util.List;
11
12import javax.swing.Icon;
13
14import org.openstreetmap.josm.data.coor.EastNorth;
15import org.openstreetmap.josm.data.coor.LatLon;
16import org.openstreetmap.josm.data.osm.Node;
17import org.openstreetmap.josm.data.osm.OsmPrimitive;
18import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor;
19import org.openstreetmap.josm.data.projection.Projections;
20import org.openstreetmap.josm.tools.ImageProvider;
21
22/**
23 * MoveCommand moves a set of OsmPrimitives along the map. It can be moved again
24 * to collect several MoveCommands into one command.
25 *
26 * @author imi
27 */
28public class MoveCommand extends Command {
29 /**
30 * The objects that should be moved.
31 */
32 private Collection<Node> nodes = new LinkedList<Node>();
33 /**
34 * Starting position, base command point, current (mouse-drag) position = startEN + (x,y) =
35 */
36 private EastNorth startEN;
37
38 /**
39 * x difference movement. Coordinates are in northern/eastern
40 */
41 private double x;
42 /**
43 * y difference movement. Coordinates are in northern/eastern
44 */
45 private double y;
46
47 private double backupX;
48 private double backupY;
49
50 /**
51 * List of all old states of the objects.
52 */
53 private List<OldNodeState> oldState = new LinkedList<OldNodeState>();
54
55 public MoveCommand(OsmPrimitive osm, double x, double y) {
56 this(Collections.singleton(osm), x, y);
57 }
58
59 public MoveCommand(Node node, LatLon position) {
60 this(Collections.singleton((OsmPrimitive) node), node.getEastNorth().sub(Projections.project(position)));
61 }
62
63 public MoveCommand(Collection<OsmPrimitive> objects, EastNorth offset) {
64 this(objects, offset.getX(), offset.getY());
65 }
66
67 /**
68 * Create a MoveCommand and assign the initial object set and movement vector.
69 */
70 public MoveCommand(Collection<OsmPrimitive> objects, double x, double y) {
71 super();
72 startEN = null;
73 saveCheckpoint(); // (0,0) displacement will be saved
74 this.x = x;
75 this.y = y;
76 this.nodes = AllNodesVisitor.getAllNodes(objects);
77 for (Node n : this.nodes) {
78 oldState.add(new OldNodeState(n));
79 }
80 }
81
82 public MoveCommand(Collection<OsmPrimitive> objects, EastNorth start, EastNorth end) {
83 this(objects, end.getX()-start.getX(), end.getY()-start.getY());
84 startEN = start;
85 }
86
87 public MoveCommand(OsmPrimitive p, EastNorth start, EastNorth end) {
88 this(Collections.singleton(p), end.getX()-start.getX(), end.getY()-start.getY());
89 startEN = start;
90 }
91
92 /**
93 * Move the same set of objects again by the specified vector. The vectors
94 * are added together and so the resulting will be moved to the previous
95 * vector plus this one.
96 *
97 * The move is immediately executed and any undo will undo both vectors to
98 * the original position the objects had before first moving.
99 */
100 public void moveAgain(double x, double y) {
101 for (Node n : nodes) {
102 n.setEastNorth(n.getEastNorth().add(x, y));
103 }
104 this.x += x;
105 this.y += y;
106 }
107
108 public void moveAgainTo(double x, double y) {
109 moveAgain(x - this.x, y - this.y);
110 }
111
112 /**
113 * Change the displacement vector to have endpoint @param currentEN
114 * starting point is startEN
115 */
116 public void applyVectorTo(EastNorth currentEN) {
117 if (startEN == null)
118 return;
119 x = currentEN.getX() - startEN.getX();
120 y = currentEN.getY() - startEN.getY();
121 updateCoordinates();
122 }
123
124 /**
125 * Changes base point of movement
126 * @param newDraggedStartPoint - new starting point after movement (where user clicks to start new drag)
127 */
128 public void changeStartPoint(EastNorth newDraggedStartPoint) {
129 startEN = new EastNorth(newDraggedStartPoint.getX()-x, newDraggedStartPoint.getY()-y);
130 }
131
132 /**
133 * Save curent displacement to restore in case of some problems
134 */
135 public void saveCheckpoint() {
136 backupX = x;
137 backupY = y;
138 }
139
140 /**
141 * Restore old displacement in case of some problems
142 */
143 public void resetToCheckpoint() {
144 x = backupX;
145 y = backupY;
146 updateCoordinates();
147 }
148
149 private void updateCoordinates() {
150 Iterator<OldNodeState> it = oldState.iterator();
151 for (Node n : nodes) {
152 OldNodeState os = it.next();
153 if (os.eastNorth != null) {
154 n.setEastNorth(os.eastNorth.add(x, y));
155 }
156 }
157 }
158
159 @Override public boolean executeCommand() {
160 for (Node n : nodes) {
161 // in case #3892 happens again
162 if (n == null)
163 throw new AssertionError("null detected in node list");
164 EastNorth en = n.getEastNorth();
165 if (en != null) {
166 n.setEastNorth(en.add(x, y));
167 n.setModified(true);
168 }
169 }
170 return true;
171 }
172
173 @Override public void undoCommand() {
174 Iterator<OldNodeState> it = oldState.iterator();
175 for (Node n : nodes) {
176 OldNodeState os = it.next();
177 n.setCoor(os.latlon);
178 n.setModified(os.modified);
179 }
180 }
181
182 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
183 for (OsmPrimitive osm : nodes) {
184 modified.add(osm);
185 }
186 }
187
188 @Override
189 public String getDescriptionText() {
190 return trn("Move {0} node", "Move {0} nodes", nodes.size(), nodes.size());
191 }
192
193 @Override
194 public Icon getDescriptionIcon() {
195 return ImageProvider.get("data", "node");
196 }
197
198 @Override
199 public Collection<Node> getParticipatingPrimitives() {
200 return nodes;
201 }
202}
Note: See TracBrowser for help on using the repository browser.