source: osm/applications/editors/josm/plugins/public_transport/src/public_transport/StopImporterAction.java@ 20772

Last change on this file since 20772 was 20772, checked in by roland, 14 years ago

Public Transport Plugin: Making UndoRedo possible

File size: 14.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.Container;
7import java.awt.Frame;
8import java.awt.GridBagConstraints;
9import java.awt.GridBagLayout;
10import java.awt.event.ActionEvent;
11import java.io.File;
12import java.io.FileInputStream;
13import java.io.FileNotFoundException;
14import java.io.InputStream;
15import java.io.IOException;
16import java.text.DecimalFormat;
17import java.text.Format;
18import java.util.Collections;
19import java.util.Iterator;
20import java.util.Vector;
21import java.util.zip.GZIPInputStream;
22
23import javax.swing.DefaultListModel;
24import javax.swing.JButton;
25import javax.swing.JComboBox;
26import javax.swing.JDialog;
27import javax.swing.JFileChooser;
28import javax.swing.JLabel;
29import javax.swing.JList;
30import javax.swing.JOptionPane;
31import javax.swing.JPanel;
32import javax.swing.JScrollPane;
33import javax.swing.JTabbedPane;
34import javax.swing.JTable;
35import javax.swing.JTextField;
36import javax.swing.ListSelectionModel;
37import javax.swing.event.ListSelectionEvent;
38import javax.swing.event.ListSelectionListener;
39import javax.swing.event.TableModelEvent;
40import javax.swing.event.TableModelListener;
41import javax.swing.table.DefaultTableModel;
42
43import org.openstreetmap.josm.Main;
44import org.openstreetmap.josm.actions.JosmAction;
45import org.openstreetmap.josm.command.Command;
46import org.openstreetmap.josm.command.ChangeCommand;
47import org.openstreetmap.josm.command.DeleteCommand;
48import org.openstreetmap.josm.data.coor.LatLon;
49import org.openstreetmap.josm.data.gpx.GpxData;
50import org.openstreetmap.josm.data.gpx.GpxTrack;
51import org.openstreetmap.josm.data.gpx.GpxTrackSegment;
52import org.openstreetmap.josm.data.gpx.WayPoint;
53import org.openstreetmap.josm.data.osm.DataSet;
54import org.openstreetmap.josm.data.osm.Node;
55import org.openstreetmap.josm.data.osm.OsmPrimitive;
56import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
57import org.openstreetmap.josm.io.GpxReader;
58
59import org.xml.sax.SAXException;
60
61public class StopImporterAction extends JosmAction
62{
63 private static StopImporterDialog dialog = null;
64 private static DefaultListModel tracksListModel = null;
65 private static GpxData data = null;
66 private static TrackReference currentTrack = null;
67 private static WaypointTableModel waypointTM = null;
68
69 public StopImporterAction()
70 {
71 super(tr("Create Stops from GPX ..."), null,
72 tr("Create Stops from a GPX file"), null, true);
73 }
74
75 public WaypointTableModel getWaypointTableModel()
76 {
77 return waypointTM;
78 }
79
80 public StopImporterDialog getDialog()
81 {
82 return dialog;
83 }
84
85 public DefaultListModel getTracksListModel()
86 {
87 if (tracksListModel == null)
88 tracksListModel = new DefaultListModel();
89 return tracksListModel;
90 }
91
92 public TrackReference getCurrentTrack()
93 {
94 return currentTrack;
95 }
96
97 public void actionPerformed(ActionEvent event)
98 {
99 DataSet mainDataSet = Main.main.getCurrentDataSet();
100
101 if (dialog == null)
102 dialog = new StopImporterDialog(this);
103
104 dialog.setVisible(true);
105
106 if (tr("Create Stops from GPX ...").equals(event.getActionCommand()))
107 {
108 String curDir = Main.pref.get("lastDirectory");
109 if (curDir.equals(""))
110 {
111 curDir = ".";
112 }
113 JFileChooser fc = new JFileChooser(new File(curDir));
114 fc.setDialogTitle("Select GPX file");
115 fc.setMultiSelectionEnabled(false);
116
117 int answer = fc.showOpenDialog(Main.parent);
118 if (answer != JFileChooser.APPROVE_OPTION)
119 return;
120
121 if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir))
122 Main.pref.put("lastDirectory", fc.getCurrentDirectory().getAbsolutePath());
123
124 importData(fc.getSelectedFile());
125
126 refreshData();
127 }
128 else if ("stopImporter.settingsGPSTimeStart".equals(event.getActionCommand()))
129 {
130 if ((dialog.gpsTimeStartValid()) && (currentTrack != null))
131 {
132 currentTrack.gpsSyncTime = dialog.getGpsTimeStart();
133 currentTrack.relocateNodes();
134 }
135 }
136 else if ("stopImporter.settingsStopwatchStart".equals(event.getActionCommand()))
137 {
138 if ((dialog.stopwatchStartValid()) && (currentTrack != null))
139 {
140 currentTrack.stopwatchStart = dialog.getStopwatchStart();
141 currentTrack.relocateNodes();
142 }
143 }
144 else if ("stopImporter.settingsTimeWindow".equals(event.getActionCommand()))
145 {
146 if (currentTrack != null)
147 currentTrack.timeWindow = dialog.getTimeWindow();
148 }
149 else if ("stopImporter.settingsThreshold".equals(event.getActionCommand()))
150 {
151 if (currentTrack != null)
152 currentTrack.threshold = dialog.getThreshold();
153 }
154 else if ("stopImporter.settingsSuggestStops".equals(event.getActionCommand()))
155 {
156 currentTrack.suggestStops();
157 }
158 else if ("stopImporter.stoplistFind".equals(event.getActionCommand()))
159 findNodesInTable(dialog.getStoplistTable(), currentTrack.stoplistTM.nodes);
160 else if ("stopImporter.stoplistShow".equals(event.getActionCommand()))
161 showNodesFromTable(dialog.getStoplistTable(), currentTrack.stoplistTM.nodes);
162 else if ("stopImporter.stoplistMark".equals(event.getActionCommand()))
163 markNodesFromTable(dialog.getStoplistTable(), currentTrack.stoplistTM.nodes);
164 else if ("stopImporter.stoplistDetach".equals(event.getActionCommand()))
165 {
166 Main.main.undoRedo.add(new TrackStoplistDetachCommand(this));
167 dialog.getStoplistTable().clearSelection();
168 }
169 else if ("stopImporter.stoplistAdd".equals(event.getActionCommand()))
170 Main.main.undoRedo.add(new TrackStoplistAddCommand(this));
171 else if ("stopImporter.stoplistDelete".equals(event.getActionCommand()))
172 Main.main.undoRedo.add(new TrackStoplistDeleteCommand(this));
173 else if ("stopImporter.stoplistSort".equals(event.getActionCommand()))
174 Main.main.undoRedo.add(new TrackStoplistSortCommand(this));
175 else if ("stopImporter.waypointsFind".equals(event.getActionCommand()))
176 findNodesInTable(dialog.getWaypointsTable(), waypointTM.nodes);
177 else if ("stopImporter.waypointsShow".equals(event.getActionCommand()))
178 showNodesFromTable(dialog.getWaypointsTable(), waypointTM.nodes);
179 else if ("stopImporter.waypointsMark".equals(event.getActionCommand()))
180 markNodesFromTable(dialog.getWaypointsTable(), waypointTM.nodes);
181 else if ("stopImporter.waypointsDetach".equals(event.getActionCommand()))
182 {
183 Main.main.undoRedo.add(new WaypointsDetachCommand(this));
184 dialog.getWaypointsTable().clearSelection();
185 }
186 else if ("stopImporter.waypointsAdd".equals(event.getActionCommand()))
187 Main.main.undoRedo.add(new WaypointsEnableCommand(this));
188 else if ("stopImporter.waypointsDelete".equals(event.getActionCommand()))
189 Main.main.undoRedo.add(new WaypointsDisableCommand(this));
190 else if ("stopImporter.settingsStoptype".equals(event.getActionCommand()))
191 Main.main.undoRedo.add(new SettingsStoptypeCommand(this));
192 }
193
194 private void importData(final File file)
195 {
196 try
197 {
198 InputStream is;
199 if (file.getName().endsWith(".gpx.gz"))
200 is = new GZIPInputStream(new FileInputStream(file));
201 else
202 is = new FileInputStream(file);
203 // Workaround for SAX BOM bug
204 // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6206835
205 if (!((is.read() == 0xef) && (is.read() == 0xbb) && (is.read() == 0xbf)))
206 {
207 is.close();
208 if (file.getName().endsWith(".gpx.gz"))
209 is = new GZIPInputStream(new FileInputStream(file));
210 else
211 is = new FileInputStream(file);
212 }
213 final GpxReader r = new GpxReader(is);
214 final boolean parsedProperly = r.parse(true);
215 data = r.data;
216
217 if (!parsedProperly)
218 {
219 JOptionPane.showMessageDialog(null, tr("Error occured while parsing gpx file {0}. Only part of the file will be available", file.getName()));
220 }
221 }
222 catch (FileNotFoundException e)
223 {
224 e.printStackTrace();
225 JOptionPane.showMessageDialog(null, tr("File \"{0}\" does not exist", file.getName()));
226 }
227 catch (SAXException e)
228 {
229 e.printStackTrace();
230 JOptionPane.showMessageDialog(null, tr("Parsing file \"{0}\" failed", file.getName()));
231 }
232 catch (IOException e)
233 {
234 e.printStackTrace();
235 JOptionPane.showMessageDialog(null, tr("IOException \"{0}\" occurred", e.toString()));
236 }
237 }
238
239 private void refreshData()
240 {
241 tracksListModel.clear();
242 if (data != null)
243 {
244 Vector< TrackReference > trackRefs = new Vector< TrackReference >();
245 Iterator< GpxTrack > trackIter = data.tracks.iterator();
246 while (trackIter.hasNext())
247 {
248 GpxTrack track = trackIter.next();
249 trackRefs.add(new TrackReference(track, this));
250 }
251
252 Collections.sort(trackRefs);
253
254 Iterator< TrackReference > iter = trackRefs.iterator();
255 while (iter.hasNext())
256 tracksListModel.addElement(iter.next());
257
258 waypointTM = new WaypointTableModel(this);
259 Iterator< WayPoint > waypointIter = data.waypoints.iterator();
260 while (waypointIter.hasNext())
261 {
262 WayPoint waypoint = waypointIter.next();
263 waypointTM.addRow(waypoint);
264 }
265 dialog.getWaypointsTable().setModel(waypointTM);
266 }
267 else
268 {
269 JOptionPane.showMessageDialog
270 (null, "The GPX file contained no tracks or waypoints.", "No data found",
271 JOptionPane.ERROR_MESSAGE);
272
273 System.out.println("Public Transport: StopImporter: No data found");
274 }
275 }
276
277 public void tracksSelectionChanged(int selectedPos)
278 {
279 if (selectedPos >= 0)
280 {
281 currentTrack = ((TrackReference)tracksListModel.elementAt(selectedPos));
282 dialog.setTrackValid(true);
283
284 //Prepare Settings
285 dialog.setSettings
286 (currentTrack.gpsSyncTime, currentTrack.stopwatchStart,
287 currentTrack.timeWindow, currentTrack.threshold);
288
289 //Prepare Stoplist
290 dialog.getStoplistTable().setModel
291 (((TrackReference)tracksListModel.elementAt(selectedPos)).stoplistTM);
292 }
293 else
294 {
295 currentTrack = null;
296 dialog.setTrackValid(false);
297 }
298 }
299
300 public Node createNode(LatLon latLon, String name)
301 {
302 return createNode(latLon, dialog.getStoptype(), name);
303 }
304
305 public static Node createNode(LatLon latLon, String type, String name)
306 {
307 Node node = new Node(latLon);
308 if ("bus".equals(type))
309 node.put("highway", "bus_stop");
310 else if ("tram".equals(type))
311 node.put("railway", "tram_stop");
312 else if ("light_rail".equals(type))
313 node.put("railway", "station");
314 else if ("subway".equals(type))
315 node.put("railway", "station");
316 else if ("rail".equals(type))
317 node.put("railway", "station");
318 node.put("name", name);
319 if (Main.main.getCurrentDataSet() == null)
320 {
321 JOptionPane.showMessageDialog(null, "There exists no dataset."
322 + " Try to download data from the server or open an OSM file.",
323 "No data found", JOptionPane.ERROR_MESSAGE);
324
325 System.out.println("Public Transport: StopInserter: No data found");
326
327 return null;
328 }
329 Main.main.getCurrentDataSet().addPrimitive(node);
330 return node;
331 }
332
333 /* sets the tags of the node according to the type */
334 public static void setTagsWrtType(Node node, String type)
335 {
336 node.remove("highway");
337 node.remove("railway");
338 if ("bus".equals(type))
339 node.put("highway", "bus_stop");
340 else if ("tram".equals(type))
341 node.put("railway", "tram_stop");
342 else if ("light_rail".equals(type))
343 node.put("railway", "station");
344 else if ("subway".equals(type))
345 node.put("railway", "station");
346 else if ("rail".equals(type))
347 node.put("railway", "station");
348 }
349
350 /* returns a collection of all selected lines or
351 a collection of all lines otherwise */
352 public static Vector< Integer > getConsideredLines(JTable table)
353 {
354 int[] selectedLines = table.getSelectedRows();
355 Vector< Integer > consideredLines = new Vector< Integer >();
356 if (selectedLines.length > 0)
357 {
358 for (int i = 0; i < selectedLines.length; ++i)
359 consideredLines.add(selectedLines[i]);
360 }
361 else
362 {
363 for (int i = 0; i < table.getRowCount(); ++i)
364 consideredLines.add(new Integer(i));
365 }
366 return consideredLines;
367 }
368
369 /* marks the table items whose nodes are marked on the map */
370 public static void findNodesInTable(JTable table, Vector< Node > nodes)
371 {
372 if (Main.main.getCurrentDataSet() == null)
373 return;
374
375 table.clearSelection();
376
377 for (int i = 0; i < table.getRowCount(); ++i)
378 {
379 if ((nodes.elementAt(i) != null) &&
380 (Main.main.getCurrentDataSet().isSelected(nodes.elementAt(i))))
381 table.addRowSelectionInterval(i, i);
382 }
383 }
384
385 /* shows the nodes that correspond to the marked lines in the table.
386 If no lines are marked in the table, show all nodes from the vector */
387 public static void showNodesFromTable(JTable table, Vector< Node > nodes)
388 {
389 BoundingXYVisitor box = new BoundingXYVisitor();
390 Vector< Integer > consideredLines = getConsideredLines(table);
391 for (int i = 0; i < consideredLines.size(); ++i)
392 {
393 int j = consideredLines.elementAt(i);
394 if (nodes.elementAt(j) != null)
395 nodes.elementAt(j).visit(box);
396 }
397 if (box.getBounds() == null)
398 return;
399 box.enlargeBoundingBox();
400 Main.map.mapView.recalculateCenterScale(box);
401 }
402
403 /* marks the nodes that correspond to the marked lines in the table.
404 If no lines are marked in the table, mark all nodes from the vector */
405 public static void markNodesFromTable(JTable table, Vector< Node > nodes)
406 {
407 OsmPrimitive[] osmp = { null };
408 Main.main.getCurrentDataSet().setSelected(osmp);
409 Vector< Integer > consideredLines = getConsideredLines(table);
410 for (int i = 0; i < consideredLines.size(); ++i)
411 {
412 int j = consideredLines.elementAt(i);
413 if (nodes.elementAt(j) != null)
414 Main.main.getCurrentDataSet().addSelected(nodes.elementAt(j));
415 }
416 }
417
418 public static String timeOf(double t)
419 {
420 t -= Math.floor(t/24/60/60)*24*60*60;
421
422 int hour = (int)Math.floor(t/60/60);
423 t -= Math.floor(t/60/60)*60*60;
424 int minute = (int)Math.floor(t/60);
425 t -= Math.floor(t/60)*60;
426 double second = t;
427
428 Format format = new DecimalFormat("00");
429 Format formatS = new DecimalFormat("00.###");
430 return (format.format(hour) + ":" + format.format(minute) + ":"
431 + formatS.format(second));
432 }
433}
Note: See TracBrowser for help on using the repository browser.