source: josm/trunk/src/org/openstreetmap/josm/actions/UnJoinNodeWayAction.java@ 6272

Last change on this file since 6272 was 6253, checked in by stoecker, 11 years ago

fix #5133 - add command to remove nodes from ways - patch by Giuseppe Bilotta

File size: 5.5 KB
Line 
1//License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6import static org.openstreetmap.josm.tools.I18n.trn;
7
8import java.awt.event.ActionEvent;
9import java.awt.event.KeyEvent;
10import java.util.ArrayList;
11import java.util.Collection;
12import java.util.Collections;
13import java.util.Iterator;
14import java.util.List;
15
16import javax.swing.JOptionPane;
17
18import org.openstreetmap.josm.Main;
19import org.openstreetmap.josm.command.RemoveNodesCommand;
20import org.openstreetmap.josm.command.Command;
21import org.openstreetmap.josm.data.osm.Node;
22import org.openstreetmap.josm.data.osm.OsmPrimitive;
23import org.openstreetmap.josm.data.osm.Way;
24import org.openstreetmap.josm.tools.Shortcut;
25
26public class UnJoinNodeWayAction extends JosmAction {
27 public UnJoinNodeWayAction() {
28 super(tr("Disconnect Node from Way"), "unjoinnodeway",
29 tr("Disconnect nodes from a way they currently belong to"),
30 Shortcut.registerShortcut("tools:unjoinnodeway",
31 tr("Tool: {0}", tr("Disconnect Node from Way")), KeyEvent.VK_J, Shortcut.ALT), true);
32 putValue("help", ht("/Action/UnJoinNodeWay"));
33 }
34
35 @Override
36 public void actionPerformed(ActionEvent e) {
37
38 Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
39
40 List<Node> selectedNodes = OsmPrimitive.getFilteredList(selection, Node.class);
41 List<Way> selectedWays = OsmPrimitive.getFilteredList(selection, Way.class);
42 List<Way> applicableWays = getApplicableWays(selectedWays, selectedNodes);
43
44 if (applicableWays == null) {
45 JOptionPane.showMessageDialog(
46 Main.parent,
47 tr("Select at least one node to be disconnected."),
48 tr("Warning"),
49 JOptionPane.WARNING_MESSAGE);
50 return;
51 } else if (applicableWays.isEmpty()) {
52 JOptionPane.showMessageDialog(Main.parent,
53 trn("Selected node cannot be disconnected from anything.",
54 "Selected nodes cannot be disconnected from anything.",
55 selectedNodes.size()),
56 tr("Warning"),
57 JOptionPane.WARNING_MESSAGE);
58 return;
59 } else if (applicableWays.size() > 1) {
60 JOptionPane.showMessageDialog(Main.parent,
61 trn("There is more than one way using the node you selected. Please select the way also.",
62 "There is more than one way using the nodes you selected. Please select the way also.",
63 selectedNodes.size()),
64 tr("Warning"),
65 JOptionPane.WARNING_MESSAGE);
66 return;
67 } else if (applicableWays.get(0).getRealNodesCount() < selectedNodes.size() + 2) {
68 // there is only one affected way, but removing the selected nodes would only leave it
69 // with less than 2 nodes
70 JOptionPane.showMessageDialog(Main.parent,
71 trn("The affected way would disappear after disconnecting the selected node.",
72 "The affected way would disappear after disconnecting the selected nodes.",
73 selectedNodes.size()),
74 tr("Warning"),
75 JOptionPane.WARNING_MESSAGE);
76 return;
77 }
78
79
80 // Finally, applicableWays contains only one perfect way
81 Way selectedWay = applicableWays.get(0);
82
83 // I'm sure there's a better way to handle this
84 Main.main.undoRedo.add(new RemoveNodesCommand(selectedWay, selectedNodes));
85 Main.map.repaint();
86 }
87
88 // Find ways to which the disconnect can be applied. This is the list of ways with more
89 // than two nodes which pass through all the given nodes, intersected with the selected ways (if any)
90 private List<Way> getApplicableWays(List<Way> selectedWays, List<Node> selectedNodes) {
91 if (selectedNodes.isEmpty())
92 return null;
93
94 // List of ways shared by all nodes
95 List<Way> result = new ArrayList<Way>(OsmPrimitive.getFilteredList(selectedNodes.get(0).getReferrers(), Way.class));
96 for (int i=1; i<selectedNodes.size(); i++) {
97 List<OsmPrimitive> ref = selectedNodes.get(i).getReferrers();
98 for (Iterator<Way> it = result.iterator(); it.hasNext(); ) {
99 if (!ref.contains(it.next())) {
100 it.remove();
101 }
102 }
103 }
104
105 // Remove broken ways
106 for (Iterator<Way> it = result.iterator(); it.hasNext(); ) {
107 if (it.next().getNodesCount() <= 2) {
108 it.remove();
109 }
110 }
111
112 if (selectedWays.isEmpty())
113 return result;
114 else {
115 // Return only selected ways
116 for (Iterator<Way> it = result.iterator(); it.hasNext(); ) {
117 if (!selectedWays.contains(it.next())) {
118 it.remove();
119 }
120 }
121 return result;
122 }
123 }
124
125 @Override
126 protected void updateEnabledState() {
127 if (getCurrentDataSet() == null) {
128 setEnabled(false);
129 } else {
130 updateEnabledState(getCurrentDataSet().getSelected());
131 }
132 }
133
134 @Override
135 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
136 setEnabled(selection != null && !selection.isEmpty());
137 }
138}
Note: See TracBrowser for help on using the repository browser.