source: subversion/applications/editors/josm/plugins/michigan_left/src/MichiganLeft/MichiganLeft.java

Last change on this file was 34531, checked in by donvip, 8 months ago

update to JOSM 14153

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("Tool: {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.