source: osm/applications/editors/josm/plugins/public_transport/src/public_transport/RoutePatternAction.java@ 26533

Last change on this file since 26533 was 26533, checked in by roland, 13 years ago

Fixed a bug concerning relation role treatment in the stoplist.

File size: 72.1 KB
Line 
1package public_transport;
2
3import static org.openstreetmap.josm.tools.I18n.marktr;
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.Container;
8import java.awt.Dimension;
9import java.awt.Frame;
10import java.awt.GridBagConstraints;
11import java.awt.GridBagLayout;
12import java.awt.event.ActionEvent;
13import java.util.Collection;
14import java.util.Collections;
15import java.util.Iterator;
16import java.util.LinkedList;
17import java.util.List;
18import java.util.ListIterator;
19import java.util.Map;
20import java.util.TreeMap;
21import java.util.TreeSet;
22import java.util.Vector;
23
24import javax.swing.DefaultCellEditor;
25import javax.swing.DefaultListModel;
26import javax.swing.JButton;
27import javax.swing.JCheckBox;
28import javax.swing.JComboBox;
29import javax.swing.JDialog;
30import javax.swing.JLabel;
31import javax.swing.JList;
32import javax.swing.JOptionPane;
33import javax.swing.JPanel;
34import javax.swing.JScrollPane;
35import javax.swing.JTabbedPane;
36import javax.swing.JTable;
37import javax.swing.JTextField;
38import javax.swing.ListSelectionModel;
39import javax.swing.event.ListSelectionEvent;
40import javax.swing.event.ListSelectionListener;
41import javax.swing.event.TableModelEvent;
42import javax.swing.event.TableModelListener;
43import javax.swing.table.DefaultTableModel;
44import javax.swing.table.TableCellEditor;
45
46import org.openstreetmap.josm.Main;
47import org.openstreetmap.josm.actions.JosmAction;
48import org.openstreetmap.josm.actions.mapmode.DeleteAction;
49import org.openstreetmap.josm.data.osm.DataSet;
50import org.openstreetmap.josm.data.osm.Node;
51import org.openstreetmap.josm.data.osm.OsmPrimitive;
52import org.openstreetmap.josm.data.osm.Relation;
53import org.openstreetmap.josm.data.osm.RelationMember;
54import org.openstreetmap.josm.data.osm.Way;
55import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
56import org.openstreetmap.josm.gui.ExtendedDialog;
57import org.openstreetmap.josm.tools.GBC;
58import org.openstreetmap.josm.tools.Shortcut;
59import org.openstreetmap.josm.tools.UrlLabel;
60
61public class RoutePatternAction extends JosmAction {
62
63 public static int STOPLIST_ROLE_COLUMN = 2;
64
65 private class RoutesLSL implements ListSelectionListener {
66 RoutePatternAction root = null;
67
68 public RoutesLSL(RoutePatternAction rpa) {
69 root = rpa;
70 }
71
72 public void valueChanged(ListSelectionEvent e) {
73 root.routesSelectionChanged();
74 }
75 };
76
77 private class RouteReference implements Comparable< RouteReference > {
78 Relation route;
79
80 public RouteReference(Relation route) {
81 this.route = route;
82 }
83
84 public int compareTo(RouteReference rr) {
85 if (route.get("route") != null)
86 {
87 if (rr.route.get("route") == null)
88 return -1;
89 int result = route.get("route").compareTo(rr.route.get("route"));
90 if (result != 0)
91 return result;
92 }
93 else if (rr.route.get("route") != null)
94 return 1;
95 if (route.get("ref") != null)
96 {
97 if (rr.route.get("ref") == null)
98 return -1;
99 int result = route.get("ref").compareTo(rr.route.get("ref"));
100 if (result != 0)
101 return result;
102 }
103 else if (rr.route.get("ref") != null)
104 return 1;
105 if (route.get("to") != null)
106 {
107 if (rr.route.get("to") == null)
108 return -1;
109 int result = route.get("to").compareTo(rr.route.get("to"));
110 if (result != 0)
111 return result;
112 }
113 else if (rr.route.get("to") != null)
114 return 1;
115 if (route.get("direction") != null)
116 {
117 if (rr.route.get("direction") == null)
118 return -1;
119 int result = route.get("direction").compareTo(rr.route.get("direction"));
120 if (result != 0)
121 return result;
122 }
123 else if (rr.route.get("direction") != null)
124 return 1;
125 if (route.getId() < rr.route.getId())
126 return -1;
127 else if (route.getId() > rr.route.getId())
128 return 1;
129 return 0;
130 }
131
132 public String toString() {
133 String buf = route.get("route");
134 if ((route.get("ref") != null) && (route.get("ref") != ""))
135 {
136 if ((route.get("to") != null) && (route.get("to") != ""))
137 {
138 buf += " " + route.get("ref") + ": " + route.get("to");
139 }
140 else if ((route.get("direction") != null) && (route.get("direction") != ""))
141 {
142 buf += " " + route.get("ref") + ": " + route.get("direction");
143 }
144 else
145 {
146 buf += " " + route.get("ref");
147 }
148 }
149 buf += tr(" [ID] {0}", Long.toString(route.getId()));
150
151 return buf;
152 }
153 };
154
155 private class TagTableModel extends DefaultTableModel implements TableModelListener {
156 Relation relation = null;
157 TreeSet< String > blacklist = null;
158 boolean hasFixedKeys = true;
159
160 public TagTableModel(boolean hasFixedKeys) {
161 this.hasFixedKeys = hasFixedKeys;
162 }
163
164 public boolean isCellEditable(int row, int column) {
165 if ((column == 0) && (hasFixedKeys))
166 return false;
167 return true;
168 }
169
170 public void readRelation(Relation rel) {
171 relation = rel;
172
173 for (int i = 0; i < getRowCount(); ++i)
174 {
175 String value = rel.get((String)getValueAt(i, 0));
176 if (value == null)
177 value = "";
178 setValueAt(value, i, 1);
179 }
180 }
181
182 public void readRelation(Relation rel, TreeSet< String > blacklist) {
183 relation = rel;
184 this.blacklist = blacklist;
185
186 setRowCount(0);
187 Iterator< Map.Entry< String, String > > iter = rel.getKeys().entrySet().iterator();
188 while (iter.hasNext())
189 {
190 Map.Entry< String, String > entry = iter.next();
191 if (!blacklist.contains(entry.getKey()))
192 {
193 Vector< String > newRow = new Vector< String >();
194 newRow.add(entry.getKey());
195 newRow.add(entry.getValue());
196 addRow(newRow);
197 }
198 }
199
200 for (int i = 0; i < getRowCount(); ++i)
201 {
202 String value = rel.get((String)getValueAt(i, 0));
203 if (value == null)
204 value = "";
205 setValueAt(value, i, 1);
206 }
207 }
208
209 public void tableChanged(TableModelEvent e)
210 {
211 if (e.getType() == TableModelEvent.UPDATE)
212 {
213 relation.setModified(true);
214
215 String key = (String)getValueAt(e.getFirstRow(), 0);
216 if (key == null)
217 return;
218 if ((blacklist == null) || (!blacklist.contains(key)))
219 {
220 relation.setModified(true);
221 if ("".equals(getValueAt(e.getFirstRow(), 1)))
222 relation.remove(key);
223 else
224 relation.put(key, (String)getValueAt(e.getFirstRow(), 1));
225 }
226 else
227 {
228 if (e.getColumn() == 0)
229 setValueAt("", e.getFirstRow(), 0);
230 }
231 }
232 }
233 };
234
235 private class CustomCellEditorTable extends JTable {
236 TreeMap< Integer, TableCellEditor > col1 = null;
237 TreeMap< Integer, TableCellEditor > col2 = null;
238
239 public CustomCellEditorTable() {
240 col1 = new TreeMap< Integer, TableCellEditor >();
241 col2 = new TreeMap< Integer, TableCellEditor >();
242 }
243
244 public TableCellEditor getCellEditor(int row, int column) {
245 TableCellEditor editor = null;
246 if (column == 0)
247 editor = col1.get(new Integer(row));
248 else
249 editor = col2.get(new Integer(row));
250 if (editor == null)
251 return new DefaultCellEditor(new JTextField());
252 else
253 return editor;
254 }
255
256 public void setCellEditor(int row, int column, TableCellEditor editor) {
257 if (column == 0)
258 col1.put(new Integer(row), editor);
259 else
260 col2.put(new Integer(row), editor);
261 }
262 };
263
264 private class StoplistTableModel extends DefaultTableModel {
265
266 public Vector<Node> nodes = new Vector<Node>();
267
268 public boolean isCellEditable(int row, int column) {
269 if (column != STOPLIST_ROLE_COLUMN)
270 return false;
271 return true;
272 }
273
274 public void addRow(Object[] obj) {
275 throw new UnsupportedOperationException();
276 }
277
278 public void insertRow(int insPos, Object[] obj) {
279 throw new UnsupportedOperationException();
280 }
281
282 public void addRow(Node node, String role) {
283 insertRow(-1, node, role);
284 }
285
286 public void insertRow(int insPos, Node node, String role) {
287 String[] buf = { "", "", "" };
288 String curName = node.get("name");
289 if (curName != null)
290 {
291 buf[0] = curName;
292 }
293 else
294 {
295 buf[0] = tr("[ID] {0}", (new Long(node.getId())).toString());
296 }
297 String curRef = node.get("ref");
298 if (curRef != null)
299 {
300 buf[1] = curRef;
301 }
302 buf[STOPLIST_ROLE_COLUMN] = role;
303 if (insPos == -1)
304 {
305 nodes.addElement(node);
306 super.addRow(buf);
307 }
308 else
309 {
310 nodes.insertElementAt(node, insPos);
311 super.insertRow(insPos, buf);
312 }
313 }
314
315 public void clear()
316 {
317 nodes.clear();
318 super.setRowCount(0);
319 }
320 };
321
322 private class StoplistTableModelListener implements TableModelListener {
323 public void tableChanged(TableModelEvent e)
324 {
325 if (e.getType() == TableModelEvent.UPDATE)
326 {
327 rebuildNodes();
328 }
329 }
330 };
331
332 private class SegmentMetric {
333 public double aLat, aLon;
334 public double length;
335 public double d1, d2, o1, o2;
336
337 public SegmentMetric(double fromLat, double fromLon, double toLat, double toLon) {
338 aLat = fromLat;
339 aLon = fromLon;
340
341 //Compute length and direction
342 //length is in units of latitude degrees
343 d1 = toLat - fromLat;
344 d2 = (toLon - fromLon) * Math.cos(fromLat * Math.PI/180.0);
345 length = Math.sqrt(d1*d1 + d2*d2);
346
347 //Normalise direction
348 d1 = d1 / length;
349 d2 = d2 / length;
350
351 //Compute orthogonal direction (right hand size is positive)
352 o1 = - d2;
353 o2 = d1;
354
355 //Prepare lon direction to reduce the number of necessary multiplications
356 d2 = d2 * Math.cos(fromLat * Math.PI/180.0);
357 o2 = o2 * Math.cos(fromLat * Math.PI/180.0);
358 }
359 };
360
361 private class StopReference implements Comparable< StopReference > {
362 public int index = 0;
363 public double pos = 0;
364 public double distance = 0;
365 public String name = "";
366 public String role = "";
367 public Node node;
368
369 public StopReference(int inIndex, double inPos, double inDistance,
370 String inName, String inRole, Node inNode) {
371 index = inIndex;
372 pos = inPos;
373 distance = inDistance;
374 name = inName;
375 role = inRole;
376 node = inNode;
377 }
378
379 public int compareTo(StopReference sr) {
380 if (this.index < sr.index)
381 return -1;
382 if (this.index > sr.index)
383 return 1;
384 if (this.pos < sr.pos)
385 return -1;
386 if (this.pos > sr.pos)
387 return 1;
388 return 0;
389 }
390 };
391
392 private static JDialog jDialog = null;
393 private static JTabbedPane tabbedPane = null;
394 private static DefaultListModel relsListModel = null;
395 private static TagTableModel requiredTagsData = null;
396 private static CustomCellEditorTable requiredTagsTable = null;
397 private static TagTableModel commonTagsData = null;
398 private static CustomCellEditorTable commonTagsTable = null;
399 private static TagTableModel otherTagsData = null;
400 private static TreeSet< String > tagBlacklist = null;
401 private static CustomCellEditorTable otherTagsTable = null;
402 private static ItineraryTableModel itineraryData = null;
403 private static JTable itineraryTable = null;
404 private static StoplistTableModel stoplistData = null;
405 private static JTable stoplistTable = null;
406 private static JList relsList = null;
407 private static JCheckBox cbRight = null;
408 private static JCheckBox cbLeft = null;
409 private static JTextField tfSuggestStopsLimit = null;
410 private static Relation currentRoute = null;
411 private static Vector< RelationMember > markedWays = new Vector< RelationMember >();
412 private static Vector< RelationMember > markedNodes = new Vector< RelationMember >();
413
414 private static Relation copy = null;
415
416 public RoutePatternAction() {
417 super(tr("Route patterns ..."), null,
418 tr("Edit Route patterns for public transport"), null, false);
419 putValue("toolbar", "publictransport/routepattern");
420 Main.toolbar.register(this);
421 }
422
423 public void actionPerformed(ActionEvent event) {
424 Frame frame = JOptionPane.getFrameForComponent(Main.parent);
425 DataSet mainDataSet = Main.main.getCurrentDataSet();
426
427 if (jDialog == null)
428 {
429 jDialog = new JDialog(frame, tr("Route Patterns"), false);
430 tabbedPane = new JTabbedPane();
431 JPanel tabOverview = new JPanel();
432 tabbedPane.addTab(tr("Overview"), tabOverview);
433 JPanel tabTags = new JPanel();
434 tabbedPane.addTab(tr("Tags"), tabTags);
435 JPanel tabItinerary = new JPanel();
436 tabbedPane.addTab(tr("Itinerary"), tabItinerary);
437 JPanel tabStoplist = new JPanel();
438 tabbedPane.addTab(tr("Stops"), tabStoplist);
439 JPanel tabMeta = new JPanel();
440 tabbedPane.addTab(tr("Meta"), tabMeta);
441 tabbedPane.setEnabledAt(0, true);
442 tabbedPane.setEnabledAt(1, false);
443 tabbedPane.setEnabledAt(2, false);
444 tabbedPane.setEnabledAt(3, false);
445 tabbedPane.setEnabledAt(4, false);
446 jDialog.add(tabbedPane);
447
448 //Overview Tab
449 Container contentPane = tabOverview;
450 GridBagLayout gridbag = new GridBagLayout();
451 GridBagConstraints layoutCons = new GridBagConstraints();
452 contentPane.setLayout(gridbag);
453
454 JLabel headline = new JLabel(tr("Existing route patterns:"));
455
456 layoutCons.gridx = 0;
457 layoutCons.gridy = 0;
458 layoutCons.gridwidth = 3;
459 layoutCons.weightx = 0.0;
460 layoutCons.weighty = 0.0;
461 layoutCons.fill = GridBagConstraints.BOTH;
462 gridbag.setConstraints(headline, layoutCons);
463 contentPane.add(headline);
464
465 relsListModel = new DefaultListModel();
466 relsList = new JList(relsListModel);
467 JScrollPane rpListSP = new JScrollPane(relsList);
468 String[] data = {"1", "2", "3", "4", "5", "6"};
469 relsListModel.copyInto(data);
470 relsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
471 relsList.addListSelectionListener(new RoutesLSL(this));
472
473 layoutCons.gridx = 0;
474 layoutCons.gridy = 1;
475 layoutCons.gridwidth = 3;
476 layoutCons.weightx = 1.0;
477 layoutCons.weighty = 1.0;
478 layoutCons.fill = GridBagConstraints.BOTH;
479 gridbag.setConstraints(rpListSP, layoutCons);
480 contentPane.add(rpListSP);
481
482 JButton bRefresh = new JButton(tr("Refresh"));
483 bRefresh.setActionCommand("routePattern.refresh");
484 bRefresh.addActionListener(this);
485
486 layoutCons.gridx = 0;
487 layoutCons.gridy = 2;
488 layoutCons.gridwidth = 1;
489 layoutCons.gridheight = 2;
490 layoutCons.weightx = 1.0;
491 layoutCons.weighty = 0.0;
492 layoutCons.fill = GridBagConstraints.BOTH;
493 gridbag.setConstraints(bRefresh, layoutCons);
494 contentPane.add(bRefresh);
495
496 JButton bNew = new JButton(tr("New"));
497 bNew.setActionCommand("routePattern.overviewNew");
498 bNew.addActionListener(this);
499
500 layoutCons.gridx = 1;
501 layoutCons.gridy = 2;
502 layoutCons.gridwidth = 1;
503 layoutCons.gridheight = 1;
504 layoutCons.weightx = 1.0;
505 layoutCons.weighty = 0.0;
506 layoutCons.fill = GridBagConstraints.BOTH;
507 gridbag.setConstraints(bNew, layoutCons);
508 contentPane.add(bNew);
509
510 JButton bDelete = new JButton(tr("Delete"));
511 bDelete.setActionCommand("routePattern.overviewDelete");
512 bDelete.addActionListener(this);
513
514 layoutCons.gridx = 1;
515 layoutCons.gridy = 3;
516 layoutCons.gridwidth = 1;
517 layoutCons.gridheight = 1;
518 layoutCons.weightx = 1.0;
519 layoutCons.weighty = 0.0;
520 layoutCons.fill = GridBagConstraints.BOTH;
521 gridbag.setConstraints(bDelete, layoutCons);
522 contentPane.add(bDelete);
523
524 JButton bDuplicate = new JButton(tr("Duplicate"));
525 bDuplicate.setActionCommand("routePattern.overviewDuplicate");
526 bDuplicate.addActionListener(this);
527
528 layoutCons.gridx = 2;
529 layoutCons.gridy = 2;
530 layoutCons.gridwidth = 1;
531 layoutCons.gridheight = 1;
532 layoutCons.weightx = 1.0;
533 layoutCons.weighty = 0.0;
534 layoutCons.fill = GridBagConstraints.BOTH;
535 gridbag.setConstraints(bDuplicate, layoutCons);
536 contentPane.add(bDuplicate);
537
538 JButton bReflect = new JButton(tr("Reflect"));
539 bReflect.setActionCommand("routePattern.overviewReflect");
540 bReflect.addActionListener(this);
541
542 layoutCons.gridx = 2;
543 layoutCons.gridy = 3;
544 layoutCons.gridwidth = 1;
545 layoutCons.gridheight = 1;
546 layoutCons.weightx = 1.0;
547 layoutCons.weighty = 0.0;
548 layoutCons.fill = GridBagConstraints.BOTH;
549 gridbag.setConstraints(bReflect, layoutCons);
550 contentPane.add(bReflect);
551
552 //Tags Tab
553 /*Container*/ contentPane = tabTags;
554 /*GridBagLayout*/ gridbag = new GridBagLayout();
555 /*GridBagConstraints*/ layoutCons = new GridBagConstraints();
556 contentPane.setLayout(gridbag);
557
558 /*JLabel*/ headline = new JLabel(tr("Required tags:"));
559
560 layoutCons.gridx = 0;
561 layoutCons.gridy = 0;
562 layoutCons.weightx = 0.0;
563 layoutCons.weighty = 0.0;
564 layoutCons.fill = GridBagConstraints.BOTH;
565 gridbag.setConstraints(headline, layoutCons);
566 contentPane.add(headline);
567
568 requiredTagsTable = new CustomCellEditorTable();
569 requiredTagsData = new TagTableModel(true);
570 requiredTagsData.addColumn(tr("Key"));
571 requiredTagsData.addColumn(tr("Value"));
572 tagBlacklist = new TreeSet< String >();
573 Vector< String > rowContent = new Vector< String >();
574 /* TODO: keys and values should also be translated using TransText class */
575 rowContent.add("type");
576 tagBlacklist.add("type");
577 rowContent.add("route");
578 requiredTagsData.addRow(rowContent);
579 JComboBox comboBox = new JComboBox();
580 comboBox.addItem("route");
581 requiredTagsTable.setCellEditor(0, 1, new DefaultCellEditor(comboBox));
582 rowContent = new Vector< String >();
583 rowContent.add(0, "route");
584 tagBlacklist.add("route");
585 rowContent.add(1, "bus");
586 requiredTagsData.addRow(rowContent);
587 /*JComboBox*/ comboBox = new JComboBox();
588 comboBox.addItem("bus");
589 comboBox.addItem("trolleybus");
590 comboBox.addItem("tram");
591 comboBox.addItem("light_rail");
592 comboBox.addItem("subway");
593 comboBox.addItem("rail");
594 requiredTagsTable.setCellEditor(1, 1, new DefaultCellEditor(comboBox));
595 rowContent = new Vector< String >();
596 rowContent.add(0, "ref");
597 tagBlacklist.add("ref");
598 rowContent.add(1, "");
599 requiredTagsData.addRow(rowContent);
600 rowContent = new Vector< String >();
601 rowContent.add(0, "to");
602 tagBlacklist.add("to");
603 rowContent.add(1, "");
604 requiredTagsData.addRow(rowContent);
605 rowContent = new Vector< String >();
606 rowContent.add(0, "network");
607 tagBlacklist.add("network");
608 rowContent.add(1, "");
609 requiredTagsData.addRow(rowContent);
610 requiredTagsTable.setModel(requiredTagsData);
611 JScrollPane tableSP = new JScrollPane(requiredTagsTable);
612 requiredTagsData.addTableModelListener(requiredTagsData);
613
614 layoutCons.gridx = 0;
615 layoutCons.gridy = 1;
616 layoutCons.weightx = 1.0;
617 layoutCons.weighty = 0.25;
618 layoutCons.fill = GridBagConstraints.BOTH;
619 gridbag.setConstraints(tableSP, layoutCons);
620 Dimension preferredSize = tableSP.getPreferredSize();
621 preferredSize.setSize(tableSP.getPreferredSize().getWidth(), tableSP.getPreferredSize().getHeight()/4.0);
622 tableSP.setPreferredSize(preferredSize);
623 contentPane.add(tableSP);
624
625 headline = new JLabel(tr("Common tags:"));
626
627 layoutCons.gridx = 0;
628 layoutCons.gridy = 2;
629 layoutCons.weightx = 0.0;
630 layoutCons.weighty = 0.0;
631 layoutCons.fill = GridBagConstraints.BOTH;
632 gridbag.setConstraints(headline, layoutCons);
633 contentPane.add(headline);
634
635 commonTagsTable = new CustomCellEditorTable();
636 commonTagsData = new TagTableModel(true);
637 commonTagsData.addColumn(tr("Key"));
638 commonTagsData.addColumn(tr("Value"));
639 rowContent = new Vector< String >();
640 rowContent.add(0, "direction");
641 tagBlacklist.add("direction");
642 rowContent.add(1, "");
643 commonTagsData.addRow(rowContent);
644 rowContent = new Vector< String >();
645 rowContent.add(0, "from");
646 tagBlacklist.add("from");
647 rowContent.add(1, "");
648 commonTagsData.addRow(rowContent);
649 rowContent = new Vector< String >();
650 rowContent.add(0, "operator");
651 tagBlacklist.add("operator");
652 rowContent.add(1, "");
653 commonTagsData.addRow(rowContent);
654 rowContent = new Vector< String >();
655 rowContent.add(0, "color");
656 tagBlacklist.add("color");
657 rowContent.add(1, "");
658 commonTagsData.addRow(rowContent);
659 rowContent = new Vector< String >();
660 rowContent.add(0, "name");
661 tagBlacklist.add("name");
662 rowContent.add(1, "");
663 commonTagsData.addRow(rowContent);
664 commonTagsTable.setModel(commonTagsData);
665 /*JScrollPane*/ tableSP = new JScrollPane(commonTagsTable);
666 commonTagsData.addTableModelListener(commonTagsData);
667
668 layoutCons.gridx = 0;
669 layoutCons.gridy = 3;
670 layoutCons.weightx = 1.0;
671 layoutCons.weighty = 0.25;
672 layoutCons.fill = GridBagConstraints.BOTH;
673 gridbag.setConstraints(tableSP, layoutCons);
674 /*Dimension*/ preferredSize = tableSP.getPreferredSize();
675 preferredSize.setSize(tableSP.getPreferredSize().getWidth(), tableSP.getPreferredSize().getHeight()/4.0);
676 tableSP.setPreferredSize(preferredSize);
677 contentPane.add(tableSP);
678
679 headline = new JLabel(tr("Additional tags:"));
680
681 layoutCons.gridx = 0;
682 layoutCons.gridy = 4;
683 layoutCons.weightx = 0.0;
684 layoutCons.weighty = 0.0;
685 layoutCons.fill = GridBagConstraints.BOTH;
686 gridbag.setConstraints(headline, layoutCons);
687 contentPane.add(headline);
688
689 otherTagsTable = new CustomCellEditorTable();
690 otherTagsData = new TagTableModel(false);
691 otherTagsData.addColumn(tr("Key"));
692 otherTagsData.addColumn(tr("Value"));
693 otherTagsTable.setModel(otherTagsData);
694 /*JScrollPane*/ tableSP = new JScrollPane(otherTagsTable);
695 otherTagsData.addTableModelListener(otherTagsData);
696
697 layoutCons.gridx = 0;
698 layoutCons.gridy = 5;
699 layoutCons.weightx = 1.0;
700 layoutCons.weighty = 1.0;
701 layoutCons.fill = GridBagConstraints.BOTH;
702 gridbag.setConstraints(tableSP, layoutCons);
703 /*Dimension*/ preferredSize = tableSP.getPreferredSize();
704 preferredSize.setSize(tableSP.getPreferredSize().getWidth(), tableSP.getPreferredSize().getHeight()/2.0);
705 tableSP.setPreferredSize(preferredSize);
706 contentPane.add(tableSP);
707
708 JButton bAddTag = new JButton(tr("Add a new Tag"));
709 bAddTag.setActionCommand("routePattern.tagAddTag");
710 bAddTag.addActionListener(this);
711
712 layoutCons.gridx = 0;
713 layoutCons.gridy = 6;
714 layoutCons.gridwidth = 1;
715 layoutCons.weightx = 1.0;
716 layoutCons.weighty = 0.0;
717 layoutCons.fill = GridBagConstraints.BOTH;
718 gridbag.setConstraints(bAddTag, layoutCons);
719 contentPane.add(bAddTag);
720
721 //Itinerary Tab
722 contentPane = tabItinerary;
723 gridbag = new GridBagLayout();
724 layoutCons = new GridBagConstraints();
725 contentPane.setLayout(gridbag);
726
727 itineraryTable = new JTable();
728 itineraryData = new ItineraryTableModel();
729 itineraryData.addColumn(tr("Name/Id"));
730 itineraryData.addColumn(tr("Role"));
731 itineraryTable.setModel(itineraryData);
732 /*JScrollPane*/ tableSP = new JScrollPane(itineraryTable);
733 /*JComboBox*/ comboBox = new JComboBox();
734 comboBox.addItem("");
735 comboBox.addItem("forward");
736 comboBox.addItem("backward");
737 itineraryTable.getColumnModel().getColumn(1)
738 .setCellEditor(new DefaultCellEditor(comboBox));
739 itineraryData.addTableModelListener(itineraryData);
740
741 layoutCons.gridx = 0;
742 layoutCons.gridy = 0;
743 layoutCons.gridwidth = 4;
744 layoutCons.weightx = 1.0;
745 layoutCons.weighty = 1.0;
746 layoutCons.fill = GridBagConstraints.BOTH;
747 gridbag.setConstraints(tableSP, layoutCons);
748 contentPane.add(tableSP);
749
750 JButton bFind = new JButton(tr("Find"));
751 bFind.setActionCommand("routePattern.itineraryFind");
752 bFind.addActionListener(this);
753
754 layoutCons.gridx = 0;
755 layoutCons.gridy = 1;
756 layoutCons.gridwidth = 1;
757 layoutCons.weightx = 1.0;
758 layoutCons.weighty = 0.0;
759 layoutCons.fill = GridBagConstraints.BOTH;
760 gridbag.setConstraints(bFind, layoutCons);
761 contentPane.add(bFind);
762
763 JButton bShow = new JButton(tr("Show"));
764 bShow.setActionCommand("routePattern.itineraryShow");
765 bShow.addActionListener(this);
766
767 layoutCons.gridx = 0;
768 layoutCons.gridy = 2;
769 layoutCons.gridwidth = 1;
770 layoutCons.weightx = 1.0;
771 layoutCons.weighty = 0.0;
772 layoutCons.fill = GridBagConstraints.BOTH;
773 gridbag.setConstraints(bShow, layoutCons);
774 contentPane.add(bShow);
775
776 JButton bMark = new JButton(tr("Mark"));
777 bMark.setActionCommand("routePattern.itineraryMark");
778 bMark.addActionListener(this);
779
780 layoutCons.gridx = 1;
781 layoutCons.gridy = 1;
782 layoutCons.gridheight = 2;
783 layoutCons.gridwidth = 1;
784 layoutCons.weightx = 1.0;
785 layoutCons.weighty = 0.0;
786 layoutCons.fill = GridBagConstraints.BOTH;
787 gridbag.setConstraints(bMark, layoutCons);
788 contentPane.add(bMark);
789
790 JButton bAdd = new JButton(tr("Add"));
791 bAdd.setActionCommand("routePattern.itineraryAdd");
792 bAdd.addActionListener(this);
793
794 layoutCons.gridx = 2;
795 layoutCons.gridy = 1;
796 layoutCons.gridheight = 1;
797 layoutCons.gridwidth = 1;
798 layoutCons.weightx = 1.0;
799 layoutCons.weighty = 0.0;
800 layoutCons.fill = GridBagConstraints.BOTH;
801 gridbag.setConstraints(bAdd, layoutCons);
802 contentPane.add(bAdd);
803
804 /*JButton*/ bDelete = new JButton(tr("Delete"));
805 bDelete.setActionCommand("routePattern.itineraryDelete");
806 bDelete.addActionListener(this);
807
808 layoutCons.gridx = 2;
809 layoutCons.gridy = 2;
810 layoutCons.gridwidth = 1;
811 layoutCons.weightx = 1.0;
812 layoutCons.weighty = 0.0;
813 layoutCons.fill = GridBagConstraints.BOTH;
814 gridbag.setConstraints(bDelete, layoutCons);
815 contentPane.add(bDelete);
816
817 JButton bSort = new JButton(tr("Sort"));
818 bSort.setActionCommand("routePattern.itinerarySort");
819 bSort.addActionListener(this);
820
821 layoutCons.gridx = 3;
822 layoutCons.gridy = 1;
823 layoutCons.gridwidth = 1;
824 layoutCons.weightx = 1.0;
825 layoutCons.weighty = 0.0;
826 layoutCons.fill = GridBagConstraints.BOTH;
827 gridbag.setConstraints(bSort, layoutCons);
828 contentPane.add(bSort);
829
830 /*JButton*/ bReflect = new JButton(tr("Reflect"));
831 bReflect.setActionCommand("routePattern.itineraryReflect");
832 bReflect.addActionListener(this);
833
834 layoutCons.gridx = 3;
835 layoutCons.gridy = 2;
836 layoutCons.gridwidth = 1;
837 layoutCons.weightx = 1.0;
838 layoutCons.weighty = 0.0;
839 layoutCons.fill = GridBagConstraints.BOTH;
840 gridbag.setConstraints(bReflect, layoutCons);
841 contentPane.add(bReflect);
842
843 //Stoplist Tab
844 contentPane = tabStoplist;
845 gridbag = new GridBagLayout();
846 layoutCons = new GridBagConstraints();
847 contentPane.setLayout(gridbag);
848
849 stoplistTable = new JTable();
850 stoplistData = new StoplistTableModel();
851 stoplistData.addColumn(tr("Name/Id"));
852 stoplistData.addColumn(tr("Ref"));
853 stoplistData.addColumn(tr("Role"));
854 stoplistTable.setModel(stoplistData);
855 /*JScrollPane*/ tableSP = new JScrollPane(stoplistTable);
856 /*JComboBox*/ comboBox = new JComboBox();
857 comboBox.addItem("");
858 comboBox.addItem("forward_stop");
859 comboBox.addItem("backward_stop");
860 stoplistTable.getColumnModel().getColumn(STOPLIST_ROLE_COLUMN)
861 .setCellEditor(new DefaultCellEditor(comboBox));
862 stoplistData.addTableModelListener(new StoplistTableModelListener());
863
864 layoutCons.gridx = 0;
865 layoutCons.gridy = 0;
866 layoutCons.gridwidth = 4;
867 layoutCons.weightx = 1.0;
868 layoutCons.weighty = 1.0;
869 layoutCons.fill = GridBagConstraints.BOTH;
870 gridbag.setConstraints(tableSP, layoutCons);
871 contentPane.add(tableSP);
872
873 /*JButton*/ bFind = new JButton(tr("Find"));
874 bFind.setActionCommand("routePattern.stoplistFind");
875 bFind.addActionListener(this);
876
877 layoutCons.gridx = 0;
878 layoutCons.gridy = 1;
879 layoutCons.gridwidth = 1;
880 layoutCons.weightx = 1.0;
881 layoutCons.weighty = 0.0;
882 layoutCons.fill = GridBagConstraints.BOTH;
883 gridbag.setConstraints(bFind, layoutCons);
884 contentPane.add(bFind);
885
886 /*JButton*/ bShow = new JButton(tr("Show"));
887 bShow.setActionCommand("routePattern.stoplistShow");
888 bShow.addActionListener(this);
889
890 layoutCons.gridx = 0;
891 layoutCons.gridy = 2;
892 layoutCons.gridwidth = 1;
893 layoutCons.weightx = 1.0;
894 layoutCons.weighty = 0.0;
895 layoutCons.fill = GridBagConstraints.BOTH;
896 gridbag.setConstraints(bShow, layoutCons);
897 contentPane.add(bShow);
898
899 /*JButton*/ bMark = new JButton(tr("Mark"));
900 bMark.setActionCommand("routePattern.stoplistMark");
901 bMark.addActionListener(this);
902
903 layoutCons.gridx = 1;
904 layoutCons.gridy = 1;
905 layoutCons.gridheight = 2;
906 layoutCons.gridwidth = 1;
907 layoutCons.weightx = 1.0;
908 layoutCons.weighty = 0.0;
909 layoutCons.fill = GridBagConstraints.BOTH;
910 gridbag.setConstraints(bMark, layoutCons);
911 contentPane.add(bMark);
912
913 /*JButton*/ bAdd = new JButton(tr("Add"));
914 bAdd.setActionCommand("routePattern.stoplistAdd");
915 bAdd.addActionListener(this);
916
917 layoutCons.gridx = 2;
918 layoutCons.gridy = 1;
919 layoutCons.gridheight = 1;
920 layoutCons.gridwidth = 1;
921 layoutCons.weightx = 1.0;
922 layoutCons.weighty = 0.0;
923 layoutCons.fill = GridBagConstraints.BOTH;
924 gridbag.setConstraints(bAdd, layoutCons);
925 contentPane.add(bAdd);
926
927 /*JButton*/ bDelete = new JButton(tr("Delete"));
928 bDelete.setActionCommand("routePattern.stoplistDelete");
929 bDelete.addActionListener(this);
930
931 layoutCons.gridx = 2;
932 layoutCons.gridy = 2;
933 layoutCons.gridwidth = 1;
934 layoutCons.weightx = 1.0;
935 layoutCons.weighty = 0.0;
936 layoutCons.fill = GridBagConstraints.BOTH;
937 gridbag.setConstraints(bDelete, layoutCons);
938 contentPane.add(bDelete);
939
940 /*JButton*/ bSort = new JButton(tr("Sort"));
941 bSort.setActionCommand("routePattern.stoplistSort");
942 bSort.addActionListener(this);
943
944 layoutCons.gridx = 3;
945 layoutCons.gridy = 1;
946 layoutCons.gridwidth = 1;
947 layoutCons.weightx = 1.0;
948 layoutCons.weighty = 0.0;
949 layoutCons.fill = GridBagConstraints.BOTH;
950 gridbag.setConstraints(bSort, layoutCons);
951 contentPane.add(bSort);
952
953 /*JButton*/ bReflect = new JButton(tr("Reflect"));
954 bReflect.setActionCommand("routePattern.stoplistReflect");
955 bReflect.addActionListener(this);
956
957 layoutCons.gridx = 3;
958 layoutCons.gridy = 2;
959 layoutCons.gridwidth = 1;
960 layoutCons.weightx = 1.0;
961 layoutCons.weighty = 0.0;
962 layoutCons.fill = GridBagConstraints.BOTH;
963 gridbag.setConstraints(bReflect, layoutCons);
964 contentPane.add(bReflect);
965
966 //Meta Tab
967 contentPane = tabMeta;
968 gridbag = new GridBagLayout();
969 layoutCons = new GridBagConstraints();
970 contentPane.setLayout(gridbag);
971
972 JLabel rightleft = new JLabel(tr("Stops are possible on the"));
973
974 layoutCons.gridx = 0;
975 layoutCons.gridy = 1;
976 layoutCons.gridwidth = 2;
977 layoutCons.weightx = 0.0;
978 layoutCons.weighty = 0.0;
979 layoutCons.fill = GridBagConstraints.BOTH;
980 gridbag.setConstraints(rightleft, layoutCons);
981 contentPane.add(rightleft);
982
983 cbRight = new JCheckBox(tr("right hand side"), true);
984
985 layoutCons.gridx = 0;
986 layoutCons.gridy = 2;
987 layoutCons.gridwidth = 2;
988 layoutCons.weightx = 0.0;
989 layoutCons.weighty = 0.0;
990 layoutCons.fill = GridBagConstraints.BOTH;
991 gridbag.setConstraints(cbRight, layoutCons);
992 contentPane.add(cbRight);
993
994 cbLeft = new JCheckBox(tr("left hand side"), false);
995
996 layoutCons.gridx = 0;
997 layoutCons.gridy = 3;
998 layoutCons.gridwidth = 2;
999 layoutCons.weightx = 0.0;
1000 layoutCons.weighty = 0.0;
1001 layoutCons.fill = GridBagConstraints.BOTH;
1002 gridbag.setConstraints(cbLeft, layoutCons);
1003 contentPane.add(cbLeft);
1004
1005 JLabel maxdist = new JLabel(tr("Maximum distance from route"));
1006
1007 layoutCons.gridx = 0;
1008 layoutCons.gridy = 4;
1009 layoutCons.gridwidth = 2;
1010 layoutCons.weightx = 0.0;
1011 layoutCons.weighty = 0.0;
1012 layoutCons.fill = GridBagConstraints.BOTH;
1013 gridbag.setConstraints(maxdist, layoutCons);
1014 contentPane.add(maxdist);
1015
1016 tfSuggestStopsLimit = new JTextField("20", 4);
1017
1018 layoutCons.gridx = 0;
1019 layoutCons.gridy = 5;
1020 layoutCons.gridwidth = 1;
1021 layoutCons.weightx = 0.0;
1022 layoutCons.weighty = 0.0;
1023 layoutCons.fill = GridBagConstraints.BOTH;
1024 gridbag.setConstraints(tfSuggestStopsLimit, layoutCons);
1025 contentPane.add(tfSuggestStopsLimit);
1026
1027 JLabel meters = new JLabel(tr("meters"));
1028
1029 layoutCons.gridx = 1;
1030 layoutCons.gridy = 5;
1031 layoutCons.gridwidth = 1;
1032 layoutCons.weightx = 0.0;
1033 layoutCons.weighty = 0.0;
1034 layoutCons.fill = GridBagConstraints.BOTH;
1035 gridbag.setConstraints(meters, layoutCons);
1036 contentPane.add(meters);
1037
1038 JButton bSuggestStops = new JButton(tr("Suggest Stops"));
1039 bSuggestStops.setActionCommand("routePattern.metaSuggestStops");
1040 bSuggestStops.addActionListener(this);
1041
1042 layoutCons.gridx = 0;
1043 layoutCons.gridy = 6;
1044 layoutCons.gridwidth = 3;
1045 layoutCons.weightx = 1.0;
1046 layoutCons.weighty = 0.0;
1047 layoutCons.fill = GridBagConstraints.BOTH;
1048 gridbag.setConstraints(bSuggestStops, layoutCons);
1049 contentPane.add(bSuggestStops);
1050
1051 jDialog.pack();
1052 }
1053
1054 if ("routePattern.refresh".equals(event.getActionCommand()))
1055 {
1056 refreshData();
1057 }
1058 else if ("routePattern.overviewNew".equals(event.getActionCommand()))
1059 {
1060 currentRoute = new Relation();
1061 currentRoute.put("type", "route");
1062 currentRoute.put("route", "bus");
1063 mainDataSet.addPrimitive(currentRoute);
1064
1065 refreshData();
1066
1067 for (int i = 0; i < relsListModel.size(); ++i)
1068 {
1069 if (currentRoute == ((RouteReference)relsListModel.elementAt(i)).route)
1070 relsList.setSelectedIndex(i);
1071 }
1072 }
1073 else if ("routePattern.overviewDuplicate".equals(event.getActionCommand()))
1074 {
1075 currentRoute = new Relation(currentRoute, true);
1076 currentRoute.put("type", "route");
1077 currentRoute.put("route", "bus");
1078 mainDataSet.addPrimitive(currentRoute);
1079
1080 refreshData();
1081
1082 for (int i = 0; i < relsListModel.size(); ++i)
1083 {
1084 if (currentRoute == ((RouteReference)relsListModel.elementAt(i)).route)
1085 relsList.setSelectedIndex(i);
1086 }
1087 }
1088 else if ("routePattern.overviewReflect".equals(event.getActionCommand()))
1089 {
1090 currentRoute.setModified(true);
1091 String tag_from = currentRoute.get("from");
1092 String tag_to = currentRoute.get("to");
1093 currentRoute.put("from", tag_to);
1094 currentRoute.put("to", tag_from);
1095
1096 Vector< RelationMember > itemsToReflect = new Vector< RelationMember >();
1097 Vector< RelationMember > otherItems = new Vector< RelationMember >();
1098 int insPos = itineraryTable.getSelectedRow();
1099
1100 for (int i = 0; i < currentRoute.getMembersCount(); ++i)
1101 {
1102 RelationMember item = currentRoute.getMember(i);
1103
1104 if (item.isWay())
1105 {
1106 String role = item.getRole();
1107 if ("backward".equals(role))
1108 role = "forward";
1109 else if ("forward".equals(role))
1110 role = "backward";
1111 else
1112 role = "backward";
1113
1114 itemsToReflect.add(new RelationMember(role, item.getWay()));
1115 }
1116 else if (item.isNode())
1117 itemsToReflect.add(item);
1118 else
1119 otherItems.add(item);
1120 }
1121
1122 currentRoute.setMembers(null);
1123 for (int i = itemsToReflect.size()-1; i >= 0; --i)
1124 currentRoute.addMember(itemsToReflect.elementAt(i));
1125 for (int i = 0; i < otherItems.size(); ++i)
1126 currentRoute.addMember(otherItems.elementAt(i));
1127
1128 refreshData();
1129
1130 for (int i = 0; i < relsListModel.size(); ++i)
1131 {
1132 if (currentRoute == ((RouteReference)relsListModel.elementAt(i)).route)
1133 relsList.setSelectedIndex(i);
1134 }
1135 }
1136 else if ("routePattern.overviewDelete".equals(event.getActionCommand()))
1137 {
1138 DeleteAction.deleteRelation(Main.main.getEditLayer(), currentRoute);
1139
1140 currentRoute = null;
1141 tabbedPane.setEnabledAt(1, false);
1142 tabbedPane.setEnabledAt(2, false);
1143 tabbedPane.setEnabledAt(3, false);
1144 tabbedPane.setEnabledAt(4, false);
1145
1146 refreshData();
1147 }
1148 else if ("routePattern.tagAddTag".equals(event.getActionCommand()))
1149 {
1150 Vector< String > rowContent = new Vector< String >();
1151 rowContent.add("");
1152 rowContent.add("");
1153 otherTagsData.addRow(rowContent);
1154 }
1155 else if ("routePattern.itineraryFind".equals(event.getActionCommand()))
1156 {
1157 if (mainDataSet == null)
1158 return;
1159
1160 itineraryTable.clearSelection();
1161
1162 for (int i = 0; i < itineraryData.getRowCount(); ++i)
1163 {
1164 if ((itineraryData.ways.elementAt(i) != null) &&
1165 (mainDataSet.isSelected(itineraryData.ways.elementAt(i))))
1166 itineraryTable.addRowSelectionInterval(i, i);
1167 }
1168 }
1169 else if ("routePattern.itineraryShow".equals(event.getActionCommand()))
1170 {
1171 BoundingXYVisitor box = new BoundingXYVisitor();
1172 if (itineraryTable.getSelectedRowCount() > 0)
1173 {
1174 for (int i = 0; i < itineraryData.getRowCount(); ++i)
1175 {
1176 if ((itineraryTable.isRowSelected(i)) && (itineraryData.ways.elementAt(i) != null))
1177 {
1178 itineraryData.ways.elementAt(i).visit(box);
1179 }
1180 }
1181 }
1182 else
1183 {
1184 for (int i = 0; i < itineraryData.getRowCount(); ++i)
1185 {
1186 if (itineraryData.ways.elementAt(i) != null)
1187 {
1188 itineraryData.ways.elementAt(i).visit(box);
1189 }
1190 }
1191 }
1192 if (box.getBounds() == null)
1193 return;
1194 box.enlargeBoundingBox();
1195 Main.map.mapView.recalculateCenterScale(box);
1196 }
1197 else if ("routePattern.itineraryMark".equals(event.getActionCommand()))
1198 {
1199 OsmPrimitive[] osmp = { null };
1200 Main.main.getCurrentDataSet().setSelected(osmp);
1201 markedWays.clear();
1202 if (itineraryTable.getSelectedRowCount() > 0)
1203 {
1204 for (int i = 0; i < itineraryData.getRowCount(); ++i)
1205 {
1206 if ((itineraryTable.isRowSelected(i)) && (itineraryData.ways.elementAt(i) != null))
1207 {
1208 mainDataSet.addSelected(itineraryData.ways.elementAt(i));
1209
1210 RelationMember markedWay = new RelationMember
1211 ((String)(itineraryData.getValueAt(i, 1)), itineraryData.ways.elementAt(i));
1212 markedWays.addElement(markedWay);
1213 }
1214 }
1215 }
1216 else
1217 {
1218 for (int i = 0; i < itineraryData.getRowCount(); ++i)
1219 {
1220 if (itineraryData.ways.elementAt(i) != null)
1221 {
1222 mainDataSet.addSelected(itineraryData.ways.elementAt(i));
1223
1224 RelationMember markedWay = new RelationMember
1225 ((String)(itineraryData.getValueAt(i, 1)), itineraryData.ways.elementAt(i));
1226 markedWays.addElement(markedWay);
1227 }
1228 }
1229 }
1230 }
1231 else if ("routePattern.itineraryAdd".equals(event.getActionCommand()))
1232 {
1233 int insPos = itineraryTable.getSelectedRow();
1234 Iterator<RelationMember> relIter = markedWays.iterator();
1235 TreeSet<Way> addedWays = new TreeSet<Way>();
1236 if (mainDataSet == null)
1237 return;
1238
1239 while (relIter.hasNext())
1240 {
1241 RelationMember curMember = relIter.next();
1242 if ((curMember.isWay()) && (mainDataSet.isSelected(curMember.getWay())))
1243 {
1244 itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
1245 if (insPos >= 0)
1246 ++insPos;
1247
1248 addedWays.add(curMember.getWay());
1249 }
1250 }
1251
1252 Collection<Way> selectedWays = mainDataSet.getSelectedWays();
1253 Iterator<Way> wayIter = selectedWays.iterator();
1254
1255 while (wayIter.hasNext())
1256 {
1257 Way curMember = wayIter.next();
1258 if (!(addedWays.contains(curMember)))
1259 {
1260 itineraryData.insertRow(insPos, curMember, "");
1261 if (insPos >= 0)
1262 ++insPos;
1263 }
1264 }
1265
1266 if ((insPos > 0) && (insPos < itineraryData.getRowCount()))
1267 {
1268 while ((insPos < itineraryData.getRowCount())
1269 && (itineraryData.ways.elementAt(insPos) == null))
1270 ++insPos;
1271 itineraryTable.removeRowSelectionInterval(0, itineraryData.getRowCount()-1);
1272 if (insPos < itineraryData.getRowCount())
1273 itineraryTable.addRowSelectionInterval(insPos, insPos);
1274 }
1275
1276 itineraryData.cleanupGaps();
1277 rebuildWays();
1278 }
1279 else if ("routePattern.itineraryDelete".equals(event.getActionCommand()))
1280 {
1281 for (int i = itineraryData.getRowCount()-1; i >=0; --i)
1282 {
1283 if ((itineraryTable.isRowSelected(i)) && (itineraryData.ways.elementAt(i) != null))
1284 {
1285 itineraryData.ways.removeElementAt(i);
1286 itineraryData.removeRow(i);
1287 }
1288 }
1289
1290 itineraryData.cleanupGaps();
1291 rebuildWays();
1292 }
1293 else if ("routePattern.itinerarySort".equals(event.getActionCommand()))
1294 {
1295 TreeSet<Way> usedWays = new TreeSet<Way>();
1296 TreeMap<Node, LinkedList<RelationMember> > frontNodes =
1297 new TreeMap<Node, LinkedList<RelationMember> >();
1298 TreeMap<Node, LinkedList<RelationMember> > backNodes =
1299 new TreeMap<Node, LinkedList<RelationMember> >();
1300 Vector< LinkedList<RelationMember> > loops =
1301 new Vector< LinkedList<RelationMember> >();
1302 int insPos = itineraryTable.getSelectedRow();
1303
1304 if (itineraryTable.getSelectedRowCount() > 0)
1305 {
1306 for (int i = itineraryData.getRowCount()-1; i >=0; --i)
1307 {
1308 if ((itineraryTable.isRowSelected(i)) && (itineraryData.ways.elementAt(i) != null))
1309 {
1310 if (!(usedWays.contains(itineraryData.ways.elementAt(i))))
1311 {
1312 addWayToSortingData
1313 (itineraryData.ways.elementAt(i), frontNodes, backNodes, loops);
1314 usedWays.add(itineraryData.ways.elementAt(i));
1315 }
1316
1317 itineraryData.ways.removeElementAt(i);
1318 itineraryData.removeRow(i);
1319 }
1320 }
1321 }
1322 else
1323 {
1324 for (int i = itineraryData.getRowCount()-1; i >=0; --i)
1325 {
1326 if (itineraryData.ways.elementAt(i) != null)
1327 {
1328 if (!(usedWays.contains(itineraryData.ways.elementAt(i))))
1329 {
1330 addWayToSortingData
1331 (itineraryData.ways.elementAt(i), frontNodes, backNodes, loops);
1332 usedWays.add(itineraryData.ways.elementAt(i));
1333 }
1334 }
1335 }
1336
1337 itineraryData.clear();
1338 }
1339
1340 Iterator< Map.Entry< Node, LinkedList<RelationMember> > > entryIter
1341 = frontNodes.entrySet().iterator();
1342 while (entryIter.hasNext())
1343 {
1344 Iterator<RelationMember> relIter = entryIter.next().getValue().iterator();
1345 while (relIter.hasNext())
1346 {
1347 RelationMember curMember = relIter.next();
1348 itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
1349 if (insPos >= 0)
1350 ++insPos;
1351 }
1352 }
1353
1354 Iterator< LinkedList<RelationMember> > listIter = loops.iterator();
1355 while (listIter.hasNext())
1356 {
1357 Iterator<RelationMember> relIter = listIter.next().iterator();
1358 while (relIter.hasNext())
1359 {
1360 RelationMember curMember = relIter.next();
1361 itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
1362 if (insPos >= 0)
1363 ++insPos;
1364 }
1365 }
1366
1367 itineraryData.cleanupGaps();
1368 rebuildWays();
1369 }
1370 else if ("routePattern.itineraryReflect".equals(event.getActionCommand()))
1371 {
1372 Vector<RelationMember> itemsToReflect = new Vector<RelationMember>();
1373 int insPos = itineraryTable.getSelectedRow();
1374
1375 if (itineraryTable.getSelectedRowCount() > 0)
1376 {
1377 for (int i = itineraryData.getRowCount()-1; i >=0; --i)
1378 {
1379 if ((itineraryTable.isRowSelected(i)) && (itineraryData.ways.elementAt(i) != null))
1380 {
1381 String role = (String)(itineraryData.getValueAt(i, 1));
1382 if ("backward".equals(role))
1383 role = "forward";
1384 else if ("forward".equals(role))
1385 role = "backward";
1386 else
1387 role = "backward";
1388 RelationMember markedWay = new RelationMember
1389 (role, itineraryData.ways.elementAt(i));
1390 itemsToReflect.addElement(markedWay);
1391
1392 itineraryData.ways.removeElementAt(i);
1393 itineraryData.removeRow(i);
1394 }
1395 }
1396 }
1397 else
1398 {
1399 for (int i = itineraryData.getRowCount()-1; i >=0; --i)
1400 {
1401 if (itineraryData.ways.elementAt(i) != null)
1402 {
1403 String role = (String)(itineraryData.getValueAt(i, 1));
1404 if ("backward".equals(role))
1405 role = "forward";
1406 else if ("forward".equals(role))
1407 role = "backward";
1408 else
1409 role = "backward";
1410 RelationMember markedWay = new RelationMember
1411 (role, itineraryData.ways.elementAt(i));
1412 itemsToReflect.addElement(markedWay);
1413 }
1414 }
1415
1416 itineraryData.clear();
1417 }
1418
1419 int startPos = insPos;
1420 Iterator<RelationMember> relIter = itemsToReflect.iterator();
1421 while (relIter.hasNext())
1422 {
1423 RelationMember curMember = relIter.next();
1424 if (curMember.isWay())
1425 {
1426 itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
1427 if (insPos >= 0)
1428 ++insPos;
1429 }
1430 }
1431 if (insPos >= 0)
1432 itineraryTable.addRowSelectionInterval(startPos, insPos-1);
1433
1434 itineraryData.cleanupGaps();
1435 rebuildWays();
1436 }
1437 else if ("routePattern.stoplistFind".equals(event.getActionCommand()))
1438 {
1439 if (mainDataSet == null)
1440 return;
1441
1442 stoplistTable.clearSelection();
1443
1444 for (int i = 0; i < stoplistData.getRowCount(); ++i)
1445 {
1446 if ((stoplistData.nodes.elementAt(i) != null) &&
1447 (mainDataSet.isSelected(stoplistData.nodes.elementAt(i))))
1448 stoplistTable.addRowSelectionInterval(i, i);
1449 }
1450 }
1451 else if ("routePattern.stoplistShow".equals(event.getActionCommand()))
1452 {
1453 BoundingXYVisitor box = new BoundingXYVisitor();
1454 if (stoplistTable.getSelectedRowCount() > 0)
1455 {
1456 for (int i = 0; i < stoplistData.getRowCount(); ++i)
1457 {
1458 if (stoplistTable.isRowSelected(i))
1459 {
1460 stoplistData.nodes.elementAt(i).visit(box);
1461 }
1462 }
1463 }
1464 else
1465 {
1466 for (int i = 0; i < stoplistData.getRowCount(); ++i)
1467 {
1468 stoplistData.nodes.elementAt(i).visit(box);
1469 }
1470 }
1471 if (box.getBounds() == null)
1472 return;
1473 box.enlargeBoundingBox();
1474 Main.map.mapView.recalculateCenterScale(box);
1475 }
1476 else if ("routePattern.stoplistMark".equals(event.getActionCommand()))
1477 {
1478 OsmPrimitive[] osmp = { null };
1479 Main.main.getCurrentDataSet().setSelected(osmp);
1480 markedNodes.clear();
1481 if (stoplistTable.getSelectedRowCount() > 0)
1482 {
1483 for (int i = 0; i < stoplistData.getRowCount(); ++i)
1484 {
1485 if (stoplistTable.isRowSelected(i))
1486 {
1487 mainDataSet.addSelected(stoplistData.nodes.elementAt(i));
1488
1489 RelationMember markedNode = new RelationMember
1490 ((String)(stoplistData.getValueAt(i, 1)), stoplistData.nodes.elementAt(i));
1491 markedNodes.addElement(markedNode);
1492 }
1493 }
1494 }
1495 else
1496 {
1497 for (int i = 0; i < stoplistData.getRowCount(); ++i)
1498 {
1499 mainDataSet.addSelected(stoplistData.nodes.elementAt(i));
1500
1501 RelationMember markedNode = new RelationMember
1502 ((String)(stoplistData.getValueAt(i, 1)), stoplistData.nodes.elementAt(i));
1503 markedNodes.addElement(markedNode);
1504 }
1505 }
1506 }
1507 else if ("routePattern.stoplistAdd".equals(event.getActionCommand()))
1508 {
1509 int insPos = stoplistTable.getSelectedRow();
1510 Iterator<RelationMember> relIter = markedNodes.iterator();
1511 TreeSet<Node> addedNodes = new TreeSet<Node>();
1512 if (mainDataSet == null)
1513 return;
1514
1515 while (relIter.hasNext())
1516 {
1517 RelationMember curMember = relIter.next();
1518 if ((curMember.isNode()) && (mainDataSet.isSelected(curMember.getNode())))
1519 {
1520 stoplistData.insertRow(insPos, curMember.getNode(), curMember.getRole());
1521 if (insPos >= 0)
1522 ++insPos;
1523
1524 addedNodes.add(curMember.getNode());
1525 }
1526 }
1527
1528 Collection<Node> selectedNodes = mainDataSet.getSelectedNodes();
1529 Iterator<Node> nodeIter = selectedNodes.iterator();
1530
1531 while (nodeIter.hasNext())
1532 {
1533 Node curMember = nodeIter.next();
1534 if (!(addedNodes.contains(curMember)))
1535 {
1536 stoplistData.insertRow(insPos, curMember, "");
1537 if (insPos >= 0)
1538 ++insPos;
1539 }
1540 }
1541
1542 if ((insPos > 0) && (insPos < stoplistData.getRowCount()))
1543 {
1544 while ((insPos < stoplistData.getRowCount())
1545 && (stoplistData.nodes.elementAt(insPos) == null))
1546 ++insPos;
1547 stoplistTable.removeRowSelectionInterval(0, stoplistData.getRowCount()-1);
1548 if (insPos < stoplistData.getRowCount())
1549 stoplistTable.addRowSelectionInterval(insPos, insPos);
1550 }
1551
1552 rebuildNodes();
1553 }
1554 else if ("routePattern.stoplistDelete".equals(event.getActionCommand()))
1555 {
1556 for (int i = stoplistData.getRowCount()-1; i >=0; --i)
1557 {
1558 if (stoplistTable.isRowSelected(i))
1559 {
1560 stoplistData.nodes.removeElementAt(i);
1561 stoplistData.removeRow(i);
1562 }
1563 }
1564
1565 rebuildNodes();
1566 }
1567 else if ("routePattern.stoplistSort".equals(event.getActionCommand()))
1568 {
1569 // Prepare Segments: The segments of all usable ways are arranged in a linear
1570 // list such that a coor can directly be checked concerning position and offset
1571 Vector<SegmentMetric> segmentMetrics = new Vector<SegmentMetric>();
1572 for (int i = 0; i < itineraryData.getRowCount(); ++i)
1573 {
1574 if (itineraryData.ways.elementAt(i) != null)
1575 {
1576 Way way = itineraryData.ways.elementAt(i);
1577 if (!(way.isIncomplete()))
1578 {
1579 if ("backward".equals((String)(itineraryData.getValueAt(i, 1))))
1580 {
1581 for (int j = way.getNodesCount()-2; j >= 0; --j)
1582 {
1583 SegmentMetric sm = new SegmentMetric
1584 (way.getNode(j+1).getCoor().lat(), way.getNode(j+1).getCoor().lon(),
1585 way.getNode(j).getCoor().lat(), way.getNode(j).getCoor().lon());
1586 segmentMetrics.add(sm);
1587 }
1588 }
1589 else
1590 {
1591 for (int j = 0; j < way.getNodesCount()-1; ++j)
1592 {
1593 SegmentMetric sm = new SegmentMetric
1594 (way.getNode(j).getCoor().lat(), way.getNode(j).getCoor().lon(),
1595 way.getNode(j+1).getCoor().lat(), way.getNode(j+1).getCoor().lon());
1596 segmentMetrics.add(sm);
1597 }
1598 }
1599 }
1600 }
1601 else
1602 {
1603 segmentMetrics.add(null);
1604 }
1605 }
1606
1607 Vector< StopReference > srm = new Vector< StopReference >();
1608 int insPos = stoplistTable.getSelectedRow();
1609 if (stoplistTable.getSelectedRowCount() > 0)
1610 {
1611 // Determine for each member its position on the itinerary: position means here the
1612 // point on the itinerary that has minimal distance to the coor
1613 for (int i = stoplistData.getRowCount()-1; i >= 0; --i)
1614 {
1615 if (stoplistTable.isRowSelected(i))
1616 {
1617 StopReference sr = detectMinDistance
1618 (stoplistData.nodes.elementAt(i), segmentMetrics,
1619 cbRight.isSelected(), cbLeft.isSelected());
1620 if (sr != null)
1621 {
1622 if (sr.distance <
1623 Double.parseDouble(tfSuggestStopsLimit.getText()) * 9.0 / 1000000.0 )
1624 {
1625 sr.role = (String)stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN);
1626 srm.addElement(sr);
1627 }
1628 else
1629 {
1630 sr.role = (String)stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN);
1631 sr.index = segmentMetrics.size()*2;
1632 sr.pos = 0;
1633 srm.addElement(sr);
1634 }
1635
1636 stoplistData.nodes.removeElementAt(i);
1637 stoplistData.removeRow(i);
1638 }
1639
1640 }
1641 }
1642 }
1643 else
1644 {
1645 // Determine for each member its position on the itinerary: position means here the
1646 // point on the itinerary that has minimal distance to the coor
1647 for (int i = stoplistData.getRowCount()-1; i >= 0; --i)
1648 {
1649 StopReference sr = detectMinDistance
1650 (stoplistData.nodes.elementAt(i), segmentMetrics,
1651 cbRight.isSelected(), cbLeft.isSelected());
1652 if (sr != null)
1653 {
1654 if (sr.distance <
1655 Double.parseDouble(tfSuggestStopsLimit.getText()) * 9.0 / 1000000.0 )
1656 {
1657 sr.role = (String)stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN);
1658 srm.addElement(sr);
1659 }
1660 else
1661 {
1662 sr.role = (String)stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN);
1663 sr.index = segmentMetrics.size()*2;
1664 sr.pos = 0;
1665 srm.addElement(sr);
1666 }
1667 }
1668 }
1669
1670 stoplistData.clear();
1671 }
1672
1673 Collections.sort(srm);
1674
1675 for (int i = 0; i < srm.size(); ++i)
1676 {
1677 stoplistData.insertRow(insPos, srm.elementAt(i).node, srm.elementAt(i).role);
1678 if (insPos >= 0)
1679 ++insPos;
1680 }
1681
1682 rebuildNodes();
1683 }
1684 else if ("routePattern.stoplistReflect".equals(event.getActionCommand()))
1685 {
1686 Vector<RelationMember> itemsToReflect = new Vector<RelationMember>();
1687 int insPos = stoplistTable.getSelectedRow();
1688
1689 if (stoplistTable.getSelectedRowCount() > 0)
1690 {
1691 for (int i = stoplistData.getRowCount()-1; i >=0; --i)
1692 {
1693 if (stoplistTable.isRowSelected(i))
1694 {
1695 String role = (String)(stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN));
1696 RelationMember markedNode = new RelationMember
1697 (role, stoplistData.nodes.elementAt(i));
1698 itemsToReflect.addElement(markedNode);
1699
1700 stoplistData.nodes.removeElementAt(i);
1701 stoplistData.removeRow(i);
1702 }
1703 }
1704 }
1705 else
1706 {
1707 for (int i = stoplistData.getRowCount()-1; i >=0; --i)
1708 {
1709 String role = (String)(stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN));
1710 RelationMember markedNode = new RelationMember
1711 (role, stoplistData.nodes.elementAt(i));
1712 itemsToReflect.addElement(markedNode);
1713 }
1714
1715 stoplistData.clear();
1716 }
1717
1718 int startPos = insPos;
1719 Iterator<RelationMember> relIter = itemsToReflect.iterator();
1720 while (relIter.hasNext())
1721 {
1722 RelationMember curMember = relIter.next();
1723 if (curMember.isNode())
1724 {
1725 stoplistData.insertRow(insPos, curMember.getNode(), curMember.getRole());
1726 if (insPos >= 0)
1727 ++insPos;
1728 }
1729 }
1730 if (insPos >= 0)
1731 stoplistTable.addRowSelectionInterval(startPos, insPos-1);
1732
1733 rebuildNodes();
1734 }
1735 else if ("routePattern.metaSuggestStops".equals(event.getActionCommand()))
1736 {
1737 // Prepare Segments: The segments of all usable ways are arranged in a linear
1738 // list such that a coor can directly be checked concerning position and offset
1739 Vector<SegmentMetric> segmentMetrics = new Vector<SegmentMetric>();
1740 for (int i = 0; i < itineraryData.getRowCount(); ++i)
1741 {
1742 if (itineraryData.ways.elementAt(i) != null)
1743 {
1744 Way way = itineraryData.ways.elementAt(i);
1745 if (!(way.isIncomplete()))
1746 {
1747 if ("backward".equals((String)(itineraryData.getValueAt(i, 1))))
1748 {
1749 for (int j = way.getNodesCount()-2; j >= 0; --j)
1750 {
1751 SegmentMetric sm = new SegmentMetric
1752 (way.getNode(j+1).getCoor().lat(), way.getNode(j+1).getCoor().lon(),
1753 way.getNode(j).getCoor().lat(), way.getNode(j).getCoor().lon());
1754 segmentMetrics.add(sm);
1755 }
1756 }
1757 else
1758 {
1759 for (int j = 0; j < way.getNodesCount()-1; ++j)
1760 {
1761 SegmentMetric sm = new SegmentMetric
1762 (way.getNode(j).getCoor().lat(), way.getNode(j).getCoor().lon(),
1763 way.getNode(j+1).getCoor().lat(), way.getNode(j+1).getCoor().lon());
1764 segmentMetrics.add(sm);
1765 }
1766 }
1767 }
1768 }
1769 else
1770 {
1771 segmentMetrics.add(null);
1772 }
1773 }
1774
1775 Vector< StopReference > srm = new Vector< StopReference >();
1776 // Determine for each member its position on the itinerary: position means here the
1777 // point on the itinerary that has minimal distance to the coor
1778 mainDataSet = Main.main.getCurrentDataSet();
1779 if (mainDataSet != null)
1780 {
1781 String stopKey = "";
1782 String stopValue = "";
1783 if ("bus".equals(currentRoute.get("route")))
1784 {
1785 stopKey = "highway";
1786 stopValue = "bus_stop";
1787 }
1788 else if ("trolleybus".equals(currentRoute.get("route")))
1789 {
1790 stopKey = "highway";
1791 stopValue = "bus_stop";
1792 }
1793 else if ("tram".equals(currentRoute.get("route")))
1794 {
1795 stopKey = "railway";
1796 stopValue = "tram_stop";
1797 }
1798 else if ("light_rail".equals(currentRoute.get("route")))
1799 {
1800 stopKey = "railway";
1801 stopValue = "station";
1802 }
1803 else if ("subway".equals(currentRoute.get("route")))
1804 {
1805 stopKey = "railway";
1806 stopValue = "station";
1807 }
1808 else if ("rail".equals(currentRoute.get("route")))
1809 {
1810 stopKey = "railway";
1811 stopValue = "station";
1812 }
1813
1814 Collection< Node > nodeCollection = mainDataSet.getNodes();
1815 Iterator< Node > nodeIter = nodeCollection.iterator();
1816 while (nodeIter.hasNext())
1817 {
1818 Node currentNode = nodeIter.next();
1819 if (!currentNode.isUsable())
1820 continue;
1821 if (stopValue.equals(currentNode.get(stopKey)))
1822 {
1823 StopReference sr = detectMinDistance
1824 (currentNode, segmentMetrics,
1825 cbRight.isSelected(), cbLeft.isSelected());
1826 if ((sr != null) && (sr.distance <
1827 Double.parseDouble(tfSuggestStopsLimit.getText()) * 9.0 / 1000000.0 ))
1828 srm.addElement(sr);
1829 }
1830 }
1831 }
1832 else
1833 {
1834 JOptionPane.showMessageDialog(null, tr("There exists no dataset."
1835 + " Try to download data from the server or open an OSM file."),
1836 tr("No data found"), JOptionPane.ERROR_MESSAGE);
1837 }
1838
1839 /*for (int i = 0; i < stoplistData.getRowCount(); ++i)
1840 {
1841 }*/
1842
1843 Collections.sort(srm);
1844
1845 stoplistData.clear();
1846 for (int i = 0; i < srm.size(); ++i)
1847 {
1848 stoplistData.addRow(srm.elementAt(i).node, srm.elementAt(i).role);
1849 }
1850
1851 rebuildNodes();
1852 }
1853 else
1854 {
1855 refreshData();
1856
1857 jDialog.setLocationRelativeTo(frame);
1858 jDialog.setVisible(true);
1859 }
1860 }
1861
1862 private void refreshData() {
1863 Relation copy = currentRoute;
1864 relsListModel.clear();
1865 currentRoute = copy;
1866
1867 DataSet mainDataSet = Main.main.getCurrentDataSet();
1868 if (mainDataSet != null)
1869 {
1870 Vector< RouteReference > relRefs = new Vector< RouteReference >();
1871 Collection< Relation > relCollection = mainDataSet.getRelations();
1872 Iterator< Relation > relIter = relCollection.iterator();
1873
1874 while (relIter.hasNext())
1875 {
1876 Relation currentRel = relIter.next();
1877 if (!currentRel.isDeleted())
1878 {
1879 String routeVal = currentRel.get("route");
1880 if ("bus".equals(routeVal))
1881 relRefs.add(new RouteReference(currentRel));
1882 else if ("trolleybus".equals(routeVal))
1883 relRefs.add(new RouteReference(currentRel));
1884 else if ("tram".equals(routeVal))
1885 relRefs.add(new RouteReference(currentRel));
1886 else if ("light_rail".equals(routeVal))
1887 relRefs.add(new RouteReference(currentRel));
1888 else if ("subway".equals(routeVal))
1889 relRefs.add(new RouteReference(currentRel));
1890 else if ("rail".equals(routeVal))
1891 relRefs.add(new RouteReference(currentRel));
1892 }
1893 }
1894
1895 Collections.sort(relRefs);
1896
1897 Iterator< RouteReference > iter = relRefs.iterator();
1898 while (iter.hasNext())
1899 relsListModel.addElement(iter.next());
1900 }
1901 else
1902 {
1903 JOptionPane.showMessageDialog(null, tr("There exists no dataset."
1904 + " Try to download data from the server or open an OSM file."),
1905 tr("No data found"), JOptionPane.ERROR_MESSAGE);
1906 }
1907 }
1908
1909 //Rebuild ways in the relation currentRoute
1910 public static void rebuildWays() {
1911 currentRoute.setModified(true);
1912 List< RelationMember > members = currentRoute.getMembers();
1913 ListIterator< RelationMember > iter = members.listIterator();
1914 while (iter.hasNext())
1915 {
1916 if (iter.next().isWay())
1917 iter.remove();
1918 }
1919 for (int i = 0; i < itineraryData.getRowCount(); ++i)
1920 {
1921 if (itineraryData.ways.elementAt(i) != null)
1922 {
1923 RelationMember member = new RelationMember
1924 ((String)(itineraryData.getValueAt(i, 1)),
1925 itineraryData.ways.elementAt(i));
1926 members.add(member);
1927 }
1928 }
1929 currentRoute.setMembers(members);
1930 }
1931
1932 //Rebuild nodes in the relation currentRoute
1933 private void rebuildNodes() {
1934 currentRoute.setModified(true);
1935 for (int i = currentRoute.getMembersCount()-1; i >=0; --i)
1936 {
1937 if (currentRoute.getMember(i).isNode())
1938 {
1939 currentRoute.removeMember(i);
1940 }
1941 }
1942 for (int i = 0; i < stoplistData.getRowCount(); ++i)
1943 {
1944 RelationMember member = new RelationMember
1945 ((String)(stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN)),
1946 stoplistData.nodes.elementAt(i));
1947 currentRoute.addMember(member);
1948 }
1949 }
1950
1951 private void addWayToSortingData
1952 (Way way, TreeMap<Node, LinkedList<RelationMember> > frontNodes,
1953 TreeMap<Node, LinkedList<RelationMember> > backNodes,
1954 Vector< LinkedList<RelationMember> > loops)
1955 {
1956 if (way.getNodesCount() < 1)
1957 return;
1958
1959 Node firstNode = way.getNode(0);
1960 Node lastNode = way.getNode(way.getNodesCount() - 1);
1961
1962 if (frontNodes.get(firstNode) != null)
1963 {
1964 LinkedList<RelationMember> list = frontNodes.get(firstNode);
1965 list.addFirst(new RelationMember("backward", way));
1966 frontNodes.remove(firstNode);
1967
1968 Node lastListNode = null;
1969 if ("backward".equals(list.getLast().getRole()))
1970 lastListNode = list.getLast().getWay().getNode(0);
1971 else
1972 lastListNode = list.getLast().getWay().getNode
1973 (list.getLast().getWay().getNodesCount() - 1);
1974 if (lastNode.equals(lastListNode))
1975 {
1976 backNodes.remove(lastListNode);
1977 loops.add(list);
1978 }
1979 else if (frontNodes.get(lastNode) != null)
1980 {
1981 backNodes.remove(lastListNode);
1982 LinkedList<RelationMember> listToAppend = frontNodes.get(lastNode);
1983 Iterator<RelationMember> memberIter = list.iterator();
1984 while (memberIter.hasNext())
1985 {
1986 RelationMember member = memberIter.next();
1987 if ("backward".equals(member.getRole()))
1988 listToAppend.addFirst(new RelationMember("forward", member.getWay()));
1989 else
1990 listToAppend.addFirst(new RelationMember("backward", member.getWay()));
1991 }
1992 frontNodes.remove(lastNode);
1993 frontNodes.put(lastListNode, listToAppend);
1994 }
1995 else if (backNodes.get(lastNode) != null)
1996 {
1997 backNodes.remove(lastListNode);
1998 LinkedList<RelationMember> listToAppend = backNodes.get(lastNode);
1999 Iterator<RelationMember> memberIter = list.iterator();
2000 while (memberIter.hasNext())
2001 {
2002 RelationMember member = memberIter.next();
2003 listToAppend.addLast(member);
2004 }
2005 backNodes.remove(lastNode);
2006 backNodes.put(lastListNode, listToAppend);
2007 }
2008 else
2009 frontNodes.put(lastNode, list);
2010 }
2011 else if (backNodes.get(firstNode) != null)
2012 {
2013 LinkedList<RelationMember> list = backNodes.get(firstNode);
2014 list.addLast(new RelationMember("forward", way));
2015 backNodes.remove(firstNode);
2016
2017 Node firstListNode = null;
2018 if ("backward".equals(list.getFirst().getRole()))
2019 firstListNode = list.getFirst().getWay().getNode
2020 (list.getFirst().getWay().getNodesCount() - 1);
2021 else
2022 firstListNode = list.getFirst().getWay().getNode(0);
2023 if (lastNode.equals(firstListNode))
2024 {
2025 frontNodes.remove(firstListNode);
2026 loops.add(list);
2027 }
2028 else if (frontNodes.get(lastNode) != null)
2029 {
2030 frontNodes.remove(firstListNode);
2031 LinkedList<RelationMember> listToAppend = frontNodes.get(lastNode);
2032 ListIterator<RelationMember> memberIter = list.listIterator(list.size());
2033 while (memberIter.hasPrevious())
2034 {
2035 RelationMember member = memberIter.previous();
2036 listToAppend.addFirst(member);
2037 }
2038 frontNodes.remove(lastNode);
2039 frontNodes.put(firstListNode, listToAppend);
2040 }
2041 else if (backNodes.get(lastNode) != null)
2042 {
2043 frontNodes.remove(firstListNode);
2044 LinkedList<RelationMember> listToAppend = backNodes.get(lastNode);
2045 ListIterator<RelationMember> memberIter = list.listIterator(list.size());
2046 while (memberIter.hasPrevious())
2047 {
2048 RelationMember member = memberIter.previous();
2049 if ("backward".equals(member.getRole()))
2050 listToAppend.addLast(new RelationMember("forward", member.getWay()));
2051 else
2052 listToAppend.addLast(new RelationMember("backward", member.getWay()));
2053 }
2054 backNodes.remove(lastNode);
2055 backNodes.put(firstListNode, listToAppend);
2056 }
2057 else
2058 backNodes.put(lastNode, list);
2059 }
2060 else if (frontNodes.get(lastNode) != null)
2061 {
2062 LinkedList<RelationMember> list = frontNodes.get(lastNode);
2063 list.addFirst(new RelationMember("forward", way));
2064 frontNodes.remove(lastNode);
2065 frontNodes.put(firstNode, list);
2066 }
2067 else if (backNodes.get(lastNode) != null)
2068 {
2069 LinkedList<RelationMember> list = backNodes.get(lastNode);
2070 list.addLast(new RelationMember("backward", way));
2071 backNodes.remove(lastNode);
2072 backNodes.put(firstNode, list);
2073 }
2074 else
2075 {
2076 LinkedList<RelationMember> newList = new LinkedList<RelationMember>();
2077 newList.add(new RelationMember("forward", way));
2078 frontNodes.put(firstNode, newList);
2079 backNodes.put(lastNode, newList);
2080 }
2081 }
2082
2083 private void routesSelectionChanged() {
2084 int selectedPos = relsList.getAnchorSelectionIndex();
2085 if (relsList.isSelectedIndex(selectedPos))
2086 {
2087 currentRoute = ((RouteReference)relsListModel.elementAt(selectedPos)).route;
2088 tabbedPane.setEnabledAt(1, true);
2089 tabbedPane.setEnabledAt(2, true);
2090 tabbedPane.setEnabledAt(3, true);
2091 tabbedPane.setEnabledAt(4, true);
2092
2093 //Prepare Tags
2094 requiredTagsData.readRelation(currentRoute);
2095 commonTagsData.readRelation(currentRoute);
2096 otherTagsData.readRelation(currentRoute, tagBlacklist);
2097
2098 //Prepare Itinerary
2099 itineraryData.clear();
2100 List<RelationMember> relMembers = currentRoute.getMembers();
2101 Iterator<RelationMember> relIter = relMembers.iterator();
2102 fillItineraryTable(relIter, 0, -1);
2103
2104 //Prepare Stoplist
2105 stoplistData.clear();
2106 /*List<RelationMember>*/ relMembers = currentRoute.getMembers();
2107 /*Iterator<RelationMember>*/ relIter = relMembers.iterator();
2108 fillStoplistTable(relIter, -1);
2109 }
2110 else
2111 {
2112 currentRoute = null;
2113 tabbedPane.setEnabledAt(1, false);
2114 tabbedPane.setEnabledAt(2, false);
2115 tabbedPane.setEnabledAt(3, false);
2116 tabbedPane.setEnabledAt(4, false);
2117 }
2118 }
2119
2120 private void fillItineraryTable
2121 (Iterator<RelationMember> relIter, long lastNodeId, int insPos) {
2122 while (relIter.hasNext())
2123 {
2124 RelationMember curMember = relIter.next();
2125 if (curMember.isWay())
2126 {
2127 itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
2128 if (insPos >= 0)
2129 ++insPos;
2130 }
2131 }
2132 itineraryData.cleanupGaps();
2133 }
2134
2135 private void fillStoplistTable
2136 (Iterator<RelationMember> relIter, int insPos) {
2137 while (relIter.hasNext())
2138 {
2139 RelationMember curMember = relIter.next();
2140 if (curMember.isNode())
2141 {
2142 stoplistData.insertRow(insPos, curMember.getNode(), curMember.getRole());
2143 if (insPos >= 0)
2144 ++insPos;
2145 }
2146 }
2147 }
2148
2149 private StopReference detectMinDistance
2150 (Node node, Vector< SegmentMetric > segmentMetrics,
2151 boolean rhsPossible, boolean lhsPossible) {
2152 int minIndex = -1;
2153 double position = -1.0;
2154 double distance = 180.0;
2155 double lat = node.getCoor().lat();
2156 double lon = node.getCoor().lon();
2157
2158 int curIndex = -2;
2159 double angleLat = 100.0;
2160 double angleLon = 200.0;
2161 Iterator<SegmentMetric> iter = segmentMetrics.iterator();
2162 while (iter.hasNext())
2163 {
2164 curIndex += 2;
2165 SegmentMetric sm = iter.next();
2166
2167 if (sm == null)
2168 {
2169 angleLat = 100.0;
2170 angleLon = 200.0;
2171
2172 continue;
2173 }
2174
2175 double curPosition = (lat - sm.aLat)*sm.d1 + (lon - sm.aLon)*sm.d2;
2176
2177 if (curPosition < 0)
2178 {
2179 if (angleLat <= 90.0)
2180 {
2181 double lastSegAngle = Math.atan2(angleLat - sm.aLat, angleLon - sm.aLon);
2182 double segAngle = Math.atan2(sm.d1, -sm.o1);
2183 double vertexAngle = Math.atan2(lat - sm.aLat, lon - sm.aLon);
2184
2185 boolean vertexOnSeg = (vertexAngle == segAngle) ||
2186 (vertexAngle == lastSegAngle);
2187 boolean vertexOnTheLeft = (!vertexOnSeg) &&
2188 (((lastSegAngle > vertexAngle) && (vertexAngle > segAngle))
2189 || ((vertexAngle > segAngle) && (segAngle > lastSegAngle))
2190 || ((segAngle > lastSegAngle) && (lastSegAngle > vertexAngle)));
2191
2192 double currentDistance = Math.sqrt((lat - sm.aLat)*(lat - sm.aLat)
2193 + (lon - sm.aLon)*(lon - sm.aLon)
2194 *Math.cos(sm.aLat * Math.PI/180.0)*Math.cos(sm.aLat * Math.PI/180.0));
2195 curPosition = vertexAngle - segAngle;
2196 if (vertexOnTheLeft)
2197 curPosition = -curPosition;
2198 if (curPosition < 0)
2199 curPosition += 2*Math.PI;
2200 if ((Math.abs(currentDistance) < distance)
2201 && (((!vertexOnTheLeft) && (rhsPossible))
2202 || ((vertexOnTheLeft) && (lhsPossible))
2203 || (vertexOnSeg)))
2204 {
2205 distance = Math.abs(currentDistance);
2206 minIndex = curIndex-1;
2207 position = curPosition;
2208 }
2209 }
2210 angleLat = 100.0;
2211 angleLon = 200.0;
2212 }
2213 else if (curPosition > sm.length)
2214 {
2215 angleLat = sm.aLat;
2216 angleLon = sm.aLon;
2217 }
2218 else
2219 {
2220 double currentDistance = (lat - sm.aLat)*sm.o1 + (lon - sm.aLon)*sm.o2;
2221 if ((Math.abs(currentDistance) < distance)
2222 && (((currentDistance >= 0) && (rhsPossible))
2223 || ((currentDistance <= 0) && (lhsPossible))))
2224 {
2225 distance = Math.abs(currentDistance);
2226 minIndex = curIndex;
2227 position = curPosition;
2228 }
2229
2230 angleLat = 100.0;
2231 angleLon = 200.0;
2232 }
2233 }
2234
2235 if (minIndex == -1)
2236 return new StopReference(segmentMetrics.size()*2, 0, 180.0, node.get("name"),
2237 "", node);
2238
2239 return new StopReference(minIndex, position, distance, node.get("name"),
2240 "", node);
2241 }
2242}
Note: See TracBrowser for help on using the repository browser.