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

Last change on this file since 35583 was 35583, checked in by Klumbumbus, 4 years ago

see #19851 - Fix shortcut names

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