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

Last change on this file since 32536 was 32536, checked in by donvip, 10 years ago

checkstyle

File size: 9.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
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 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.getLayerManager().getEditDataSet().getSelected();
61
62 ArrayList<OsmPrimitive> selection = new ArrayList<>();
63
64 for (OsmPrimitive prim : mainSelection) {
65 selection.add(prim);
66 }
67
68 int ways = 0;
69 for (OsmPrimitive prim : selection) {
70 if (prim instanceof Way)
71 ways++;
72 }
73
74 if ((ways != 4) && (ways != 5)) {
75 JOptionPane.showMessageDialog(Main.parent,
76 tr("Please select 4 or 5 ways to assign no left turns."));
77 return;
78 }
79
80 if (ways == 4) {
81 // Find extremities of ways
82 Hashtable<Node, Integer> extremNodes = new Hashtable<>();
83 for (OsmPrimitive prim : selection) {
84 if (prim instanceof Way) {
85 Way way = (Way) prim;
86 incrementHashtable(extremNodes, way.firstNode());
87 incrementHashtable(extremNodes, way.lastNode());
88 }
89 }
90 if (extremNodes.size() != 4) {
91 JOptionPane.showMessageDialog(Main.parent,
92 tr("Please select 4 ways that form a closed relation."));
93 return;
94 }
95
96 // order the ways
97 ArrayList<Way> orderedWays = new ArrayList<>();
98 Way currentWay = (Way) selection.iterator().next();
99 orderedWays.add(currentWay);
100 selection.remove(currentWay);
101 while (selection.size() > 0) {
102 boolean found = false;
103 Node nextNode = currentWay.lastNode();
104 for (OsmPrimitive prim : selection) {
105 Way tmpWay = (Way) prim;
106 if (tmpWay.firstNode() == nextNode) {
107 orderedWays.add(tmpWay);
108 selection.remove(prim);
109 currentWay = tmpWay;
110 found = true;
111 break;
112 }
113 }
114 if (!found) {
115 JOptionPane.showMessageDialog(Main.parent,
116 tr("Unable to order the ways. Please verify their directions"));
117 return;
118 }
119 }
120
121 // Build relations
122 for (int index = 0; index < 4; index++) {
123 Way firstWay = orderedWays.get(index);
124 Way lastWay = orderedWays.get((index + 1) % 4);
125 Node lastNode = firstWay.lastNode();
126
127 buildRelation(firstWay, lastWay, lastNode);
128 }
129 Command c = new SequenceCommand(tr("Create Michigan left turn restriction"), cmds);
130 Main.main.undoRedo.add(c);
131 cmds.clear();
132 }
133
134 if (ways == 5) {
135 // Find extremities of ways
136 Hashtable<Node, Integer> extremNodes = new Hashtable<>();
137 for (OsmPrimitive prim : selection) {
138 if (prim instanceof Way) {
139 Way way = (Way) prim;
140 incrementHashtable(extremNodes, way.firstNode());
141 incrementHashtable(extremNodes, way.lastNode());
142 }
143 }
144
145 ArrayList<Node> viaNodes = new ArrayList<>();
146 // find via nodes (they have 3 occurences in the list)
147 for (Enumeration<Node> enumKey = extremNodes.keys(); enumKey.hasMoreElements();) {
148 Node extrem = enumKey.nextElement();
149 Integer nb = extremNodes.get(extrem);
150 if (nb.intValue() == 3) {
151 viaNodes.add(extrem);
152 }
153 }
154
155 if (viaNodes.size() != 2) {
156 JOptionPane.showMessageDialog(Main.parent,
157 tr("Unable to find via nodes. Please check your selection"));
158 return;
159 }
160
161 Node viaFirst = viaNodes.get(0);
162 Node viaLast = viaNodes.get(1); // Find middle segment
163
164 Way middle = null;
165 for (OsmPrimitive prim : selection) {
166 if (prim instanceof Way) {
167 Way way = (Way) prim;
168 Node first = way.firstNode();
169 Node last = way.lastNode();
170
171 if ((first.equals(viaFirst) && last.equals(viaLast))
172 || (first.equals(viaLast) && last.equals(viaFirst)))
173 middle = way;
174 }
175 }
176
177 // Build relations
178 for (OsmPrimitive prim : selection) {
179 if (prim instanceof Way) {
180 Way way = (Way) prim;
181 if (way != middle) {
182 Node first = way.firstNode();
183 Node last = way.lastNode();
184
185 if (first == viaFirst)
186 buildRelation(middle, way, viaNodes.get(0));
187 else if (first == viaLast)
188 buildRelation(middle, way, viaNodes.get(1));
189 else if (last == viaFirst)
190 buildRelation(way, middle, viaNodes.get(0));
191 else if (last == viaLast)
192 buildRelation(way, middle, viaNodes.get(1));
193 }
194 }
195 }
196 Command c = new SequenceCommand(tr("Create Michigan left turn restriction"), cmds);
197 Main.main.undoRedo.add(c);
198 cmds.clear();
199 }
200 }
201
202 public void incrementHashtable(Hashtable<Node, Integer> hash, Node node) {
203 if (hash.containsKey(node)) {
204 Integer nb = hash.get(node);
205 hash.put(node, new Integer(nb.intValue() + 1));
206 } else {
207 hash.put(node, new Integer(1));
208 }
209 }
210
211 public void buildRelation(Way fromWay, Way toWay, Node viaNode) {
212 Relation relation = new Relation();
213
214 RelationMember from = new RelationMember("from", fromWay);
215 relation.addMember(from);
216
217 RelationMember to = new RelationMember("to", toWay);
218 relation.addMember(to);
219
220 RelationMember via = new RelationMember("via", viaNode);
221 relation.addMember(via);
222
223 relation.put("type", "restriction");
224 relation.put("restriction", "no_left_turn");
225
226 cmds.add(new AddCommand(relation));
227 }
228
229 @Override
230 protected void updateEnabledState() {
231 setEnabled(getLayerManager().getEditLayer() != null);
232 }
233
234 @Override
235 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
236 // do nothing
237 }
238 }
239}
Note: See TracBrowser for help on using the repository browser.