source: osm/applications/editors/josm/plugins/utilsplugin/src/UtilsPlugin/MergeNodesAction.java@ 5076

Last change on this file since 5076 was 5076, checked in by gabriel, 18 years ago

utilsplugin: Port to API 0.5.

File size: 3.4 KB
Line 
1package UtilsPlugin;
2
3import static org.openstreetmap.josm.tools.I18n.tr;
4
5import java.util.ArrayList;
6import java.util.LinkedList;
7import java.util.Collection;
8import java.util.Collections;
9
10import java.awt.event.ActionEvent;
11
12import org.openstreetmap.josm.Main;
13import org.openstreetmap.josm.data.osm.OsmPrimitive;
14import org.openstreetmap.josm.data.osm.Node;
15import org.openstreetmap.josm.data.osm.Way;
16import org.openstreetmap.josm.data.osm.visitor.CollectBackReferencesVisitor;
17import org.openstreetmap.josm.data.coor.EastNorth;
18import org.openstreetmap.josm.gui.MapFrame;
19import org.openstreetmap.josm.plugins.Plugin;
20import org.openstreetmap.josm.actions.JosmAction;
21import org.openstreetmap.josm.command.Command;
22import org.openstreetmap.josm.command.AddCommand;
23import org.openstreetmap.josm.command.DeleteCommand;
24import org.openstreetmap.josm.command.ChangeCommand;
25import org.openstreetmap.josm.command.SequenceCommand;
26
27import javax.swing.AbstractAction;
28import javax.swing.JOptionPane;
29
30class MergeNodesAction extends JosmAction {
31 public MergeNodesAction() {
32 super(tr("Merge nodes"), "mergenodes",
33 tr("Merge nodes"), 0, 0, true);
34 }
35
36 public void actionPerformed(ActionEvent e) {
37 Collection<OsmPrimitive> sel = Main.ds.getSelected();
38 Collection<Node> nodes = new ArrayList<Node>();
39
40 for (OsmPrimitive osm : sel)
41 if (osm instanceof Node)
42 nodes.add((Node)osm);
43 if (nodes.size() < 2) {
44 JOptionPane.showMessageDialog(Main.parent,
45 tr("Must select at least two nodes."));
46 return;
47 }
48
49 // Find the node with the lowest ID.
50 // We're gonna keep our 3-digit node ids.
51 Node target = null;
52 for (Node n : nodes) {
53 if (target == null || target.id == 0 || n.id < target.id) {
54 target = n;
55 }
56 }
57
58 Collection<Command> cmds = new LinkedList<Command>();
59
60 Node newTarget = new Node(target);
61 cmds.add(new ChangeCommand(target, newTarget));
62
63 // Don't place the merged node on one of the former nodes.
64 // Place it right there in the middle.
65 double x = 0, y = 0;
66 for (Node n : nodes) {
67 x += n.eastNorth.east();
68 y += n.eastNorth.north();
69 }
70 newTarget.eastNorth = new EastNorth(
71 x / nodes.size(), y / nodes.size());
72
73 nodes.remove(target);
74
75 cmds.add(new DeleteCommand(nodes));
76
77 for (Way w : Main.ds.ways) {
78 if (w.deleted || w.incomplete) continue;
79
80 boolean affected = false;
81 for (Node n : nodes) {
82 if (w.nodes.contains(n)) {
83 affected = true;
84 break;
85 }
86 }
87 if (!affected) continue;
88
89 // Replace the old nodes with the merged ones
90 Way wnew = new Way(w);
91 for (int i = 0; i < wnew.nodes.size(); i++) {
92 if (nodes.contains(wnew.nodes.get(i))) {
93 wnew.nodes.set(i, newTarget);
94 }
95 }
96
97 // Remove duplicates
98 Node lastN = null;
99 for (int i = wnew.nodes.size() - 1; i >= 0; i--) {
100 if (lastN == wnew.nodes.get(i)) {
101 wnew.nodes.remove(i);
102 if (i < wnew.nodes.size()) i++;
103 }
104 }
105
106 if (wnew.nodes.size() < 2) {
107 CollectBackReferencesVisitor backRefV =
108 new CollectBackReferencesVisitor(Main.ds, false);
109 backRefV.visit(w);
110 if (!backRefV.data.isEmpty()) {
111 JOptionPane.showMessageDialog(Main.parent,
112 tr("Cannot merge nodes: " +
113 "Would have to delete way that is still used."));
114 return;
115 }
116
117 cmds.add(new DeleteCommand(Collections.singleton(w)));
118 } else {
119 cmds.add(new ChangeCommand(w, wnew));
120 }
121 }
122
123 Main.main.undoRedo.add(new SequenceCommand(tr("Merge Nodes"), cmds));
124 Main.map.repaint();
125 }
126}
Note: See TracBrowser for help on using the repository browser.