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

Last change on this file since 18083 was 18083, checked in by nakor, 15 years ago

Now works when two separated ways cross

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