source: osm/applications/editors/josm/plugins/michigan_left/src/MichiganLeft/MichiganLeft.java@ 30753

Last change on this file since 30753 was 30753, checked in by donvip, 11 years ago

[josm_michigan_left] code cleanup

File size: 9.0 KB
Line 
1//License: GPL
2package MichiganLeft;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.event.ActionEvent;
7import java.awt.event.KeyEvent;
8import java.util.ArrayList;
9import java.util.Collection;
10import java.util.Enumeration;
11import java.util.Hashtable;
12import java.util.LinkedList;
13
14import javax.swing.JMenuItem;
15import javax.swing.JOptionPane;
16
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.actions.JosmAction;
19import org.openstreetmap.josm.command.AddCommand;
20import org.openstreetmap.josm.command.Command;
21import org.openstreetmap.josm.command.SequenceCommand;
22import org.openstreetmap.josm.data.osm.Node;
23import org.openstreetmap.josm.data.osm.OsmPrimitive;
24import org.openstreetmap.josm.data.osm.Relation;
25import org.openstreetmap.josm.data.osm.RelationMember;
26import org.openstreetmap.josm.data.osm.Way;
27import org.openstreetmap.josm.gui.MainMenu;
28import org.openstreetmap.josm.plugins.Plugin;
29import org.openstreetmap.josm.plugins.PluginInformation;
30import org.openstreetmap.josm.tools.Shortcut;
31
32/**
33 * Plugin for easily creating turn restrictions at "Michigan left" intersections.
34 */
35public class MichiganLeft extends Plugin {
36 JMenuItem MichiganLeft;
37
38 /**
39 * Constructs a new {@code MichiganLeft} plugin.
40 *
41 * @param info plugin info
42 */
43 public MichiganLeft(PluginInformation info) {
44 super(info);
45 MichiganLeft = MainMenu.add(Main.main.menu.dataMenu, new MichiganLeftAction());
46 }
47
48 private class MichiganLeftAction extends JosmAction {
49 private LinkedList<Command> cmds = new LinkedList<>();
50
51 public MichiganLeftAction() {
52 super(tr("Michigan Left"), "michigan_left",
53 tr("Adds no left turn for sets of 4 or 5 ways."),
54 Shortcut.registerShortcut("tools:michigan_left",
55 tr("Tool: {0}", tr("Michigan Left")), KeyEvent.VK_N, Shortcut.ALT_SHIFT), true);
56 }
57
58 @Override
59 public void actionPerformed(ActionEvent e) {
60 Collection<OsmPrimitive> mainSelection = Main.main.getCurrentDataSet().getSelected();
61
62 ArrayList<OsmPrimitive> selection = new ArrayList<>();
63
64 for (OsmPrimitive prim : mainSelection)
65 selection.add(prim);
66
67 int ways = 0;
68 for (OsmPrimitive prim : selection) {
69 if (prim instanceof Way)
70 ways++;
71 }
72
73 if ((ways != 4) && (ways != 5)) {
74 JOptionPane.showMessageDialog(Main.parent,
75 tr("Please select 4 or 5 ways to assign no left turns."));
76 return;
77 }
78
79 if (ways == 4) {
80 // Find extremities of ways
81 Hashtable<Node, Integer> extremNodes = new Hashtable<>();
82 for (OsmPrimitive prim : selection) {
83 if (prim instanceof Way) {
84 Way way = (Way) prim;
85 incrementHashtable(extremNodes, way.firstNode());
86 incrementHashtable(extremNodes, way.lastNode());
87 }
88 }
89 if (extremNodes.size() != 4) {
90 JOptionPane.showMessageDialog(Main.parent,
91 tr("Please select 4 ways that form a closed relation."));
92 return;
93 }
94
95 // order the ways
96 ArrayList<Way> orderedWays = new ArrayList<>();
97 Way currentWay = (Way) selection.iterator().next();
98 orderedWays.add(currentWay);
99 selection.remove(currentWay);
100 while (selection.size() > 0) {
101 boolean found = false;
102 Node nextNode = currentWay.lastNode();
103 for (OsmPrimitive prim : selection) {
104 Way tmpWay = (Way) prim;
105 if (tmpWay.firstNode() == nextNode) {
106 orderedWays.add(tmpWay);
107 selection.remove(prim);
108 currentWay = tmpWay;
109 found = true;
110 break;
111 }
112 }
113 if (!found) {
114 JOptionPane.showMessageDialog(Main.parent,
115 tr("Unable to order the ways. Please verify their directions"));
116 return;
117 }
118 }
119
120 // Build relations
121 for (int index = 0; index < 4; index++) {
122 Way firstWay = orderedWays.get(index);
123 Way lastWay = orderedWays.get((index + 1) % 4);
124 Node lastNode = firstWay.lastNode();
125
126 buildRelation(firstWay, lastWay, lastNode);
127 }
128 Command c = new SequenceCommand(tr("Create Michigan left turn restriction"), cmds);
129 Main.main.undoRedo.add(c);
130 cmds.clear();
131 }
132
133 if (ways == 5) {
134 // Find extremities of ways
135 Hashtable<Node, Integer> extremNodes = new Hashtable<>();
136 for (OsmPrimitive prim : selection) {
137 if (prim instanceof Way) {
138 Way way = (Way) prim;
139 incrementHashtable(extremNodes, way.firstNode());
140 incrementHashtable(extremNodes, way.lastNode());
141 }
142 }
143
144 ArrayList<Node> viaNodes = new ArrayList<>();
145 // find via nodes (they have 3 occurences in the list)
146 for (Enumeration<Node> enumKey = extremNodes.keys(); enumKey.hasMoreElements();) {
147 Node extrem = enumKey.nextElement();
148 Integer nb = extremNodes.get(extrem);
149 if (nb.intValue() == 3) {
150 viaNodes.add(extrem);
151 }
152 }
153
154 if (viaNodes.size() != 2) {
155 JOptionPane.showMessageDialog(Main.parent,
156 tr("Unable to find via nodes. Please check your selection"));
157 return;
158 }
159
160 Node viaFirst = viaNodes.get(0);
161 Node viaLast = viaNodes.get(1); // Find middle segment
162
163 Way middle = null;
164 for (OsmPrimitive prim : selection) {
165 if (prim instanceof Way) {
166 Way way = (Way) prim;
167 Node first = way.firstNode();
168 Node last = way.lastNode();
169
170 if ((first.equals(viaFirst) && last.equals(viaLast))
171 || (first.equals(viaLast) && last.equals(viaFirst)))
172 middle = way;
173 }
174 }
175
176 // Build relations
177 for (OsmPrimitive prim : selection) {
178 if (prim instanceof Way) {
179 Way way = (Way) prim;
180 if (way != middle) {
181 Node first = way.firstNode();
182 Node last = way.lastNode();
183
184 if (first == viaFirst)
185 buildRelation(middle, way, viaNodes.get(0));
186 else if (first == viaLast)
187 buildRelation(middle, way, viaNodes.get(1));
188 else if (last == viaFirst)
189 buildRelation(way, middle, viaNodes.get(0));
190 else if (last == viaLast)
191 buildRelation(way, middle, viaNodes.get(1));
192 }
193 }
194 }
195 Command c = new SequenceCommand(tr("Create Michigan left turn restriction"), cmds);
196 Main.main.undoRedo.add(c);
197 cmds.clear();
198 }
199 }
200
201 public void incrementHashtable(Hashtable<Node, Integer> hash, Node node) {
202 if (hash.containsKey(node)) {
203 Integer nb = hash.get(node);
204 hash.put(node, new Integer(nb.intValue() + 1));
205 } else {
206 hash.put(node, new Integer(1));
207 }
208 }
209
210 public void buildRelation(Way fromWay, Way toWay, Node viaNode) {
211 Relation relation = new Relation();
212
213 RelationMember from = new RelationMember("from", fromWay);
214 relation.addMember(from);
215
216 RelationMember to = new RelationMember("to", toWay);
217 relation.addMember(to);
218
219 RelationMember via = new RelationMember("via", viaNode);
220 relation.addMember(via);
221
222 relation.put("type", "restriction");
223 relation.put("restriction", "no_left_turn");
224
225 cmds.add(new AddCommand(relation));
226 }
227
228 @Override
229 protected void updateEnabledState() {
230 setEnabled(getEditLayer() != null);
231 }
232
233 @Override
234 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
235 // do nothing
236 }
237 }
238}
Note: See TracBrowser for help on using the repository browser.