Source code: org/dinopolis/gpstool/GPSMap.java
1 /***********************************************************************
2 * @(#)$RCSfile: GPSMap.java,v $ $Revision: 1.44 $$Date: 2003/11/18 09:59:48 $
3 *
4 * Copyright (c) 2002 IICM, Graz University of Technology
5 * Inffeldgasse 16c, A-8010 Graz, Austria.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License (LGPL)
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the
19 * Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 ***********************************************************************/
22
23 package org.dinopolis.gpstool;
24
25 //import org.dinopolis.gpstool.alarm.AlarmConditionManager;
26 //import org.dinopolis.gpstool.gui.MapKeyHandler;
27 //import org.dinopolis.gpstool.gui.layer.TrackLayer;
28 import com.bbn.openmap.LatLonPoint;
29 import com.bbn.openmap.Layer;
30 import com.bbn.openmap.MapBean;
31 import com.bbn.openmap.proj.Projection;
32 import java.awt.BorderLayout;
33 import java.awt.Color;
34 import java.awt.Dimension;
35 import java.awt.Graphics2D;
36 import java.awt.Point;
37 import java.awt.event.ActionEvent;
38 import java.awt.event.ActionListener;
39 import java.awt.event.WindowAdapter;
40 import java.awt.event.WindowEvent;
41 import java.awt.image.BufferedImage;
42 import java.beans.PropertyChangeEvent;
43 import java.beans.PropertyChangeListener;
44 import java.beans.PropertyChangeSupport;
45 import java.io.BufferedReader;
46 import java.io.File;
47 import java.io.FileNotFoundException;
48 import java.io.FileOutputStream;
49 import java.io.FileReader;
50 import java.io.IOException;
51 import java.io.UnsupportedEncodingException;
52 import java.net.URL;
53 import java.net.URLDecoder;
54 import java.util.Hashtable;
55 import java.util.Iterator;
56 import java.util.List;
57 import java.util.Locale;
58 import java.util.MissingResourceException;
59 import java.util.NoSuchElementException;
60 import java.util.Properties;
61 import java.util.StringTokenizer;
62 import java.util.TreeSet;
63 import java.util.Vector;
64 import javax.swing.AbstractAction;
65 import javax.swing.Action;
66 import javax.swing.JCheckBoxMenuItem;
67 import javax.swing.JFileChooser;
68 import javax.swing.JFrame;
69 import javax.swing.JMenu;
70 import javax.swing.JMenuBar;
71 import javax.swing.JMenuItem;
72 import javax.swing.JOptionPane;
73 import javax.swing.JPopupMenu;
74 import org.apache.log4j.LogManager;
75 import org.apache.log4j.Logger;
76 import org.apache.log4j.PropertyConfigurator;
77 import org.dinopolis.gpstool.gpsinput.GPSDataProcessor;
78 import org.dinopolis.gpstool.gpsinput.GPSDevice;
79 import org.dinopolis.gpstool.gpsinput.GPSException;
80 import org.dinopolis.gpstool.gpsinput.GPSFileDevice;
81 import org.dinopolis.gpstool.gpsinput.GPSNetworkGpsdDevice;
82 import org.dinopolis.gpstool.gpsinput.GPSPosition;
83 import org.dinopolis.gpstool.gpsinput.GPSRawDataFileLogger;
84 import org.dinopolis.gpstool.gpsinput.GPSSerialDevice;
85 import org.dinopolis.gpstool.gpsinput.GPSSimulationDataProcessor;
86 import org.dinopolis.gpstool.gpsinput.garmin.GPSGarminDataProcessor;
87 import org.dinopolis.gpstool.gpsinput.nmea.GPSNmeaDataProcessor;
88 import org.dinopolis.gpstool.gui.LatLongInputDialog;
89 import org.dinopolis.gpstool.gui.MouseMode;
90 import org.dinopolis.gpstool.gui.MouseModeManager;
91 import org.dinopolis.gpstool.gui.StatusBar;
92 import org.dinopolis.gpstool.gui.layer.GraticuleLayer;
93 import org.dinopolis.gpstool.gui.layer.LocationLayer;
94 import org.dinopolis.gpstool.gui.layer.MultiMapLayer;
95 import org.dinopolis.gpstool.gui.layer.PositionLayer;
96 import org.dinopolis.gpstool.gui.layer.ScaleLayer;
97 import org.dinopolis.gpstool.gui.layer.ShapeLayer;
98 import org.dinopolis.gpstool.plugin.GuiPlugin;
99 import org.dinopolis.gpstool.plugin.MouseModePlugin;
100 import org.dinopolis.gpstool.plugin.WriteImagePlugin;
101 import org.dinopolis.gpstool.projection.FlatProjection;
102 import org.dinopolis.gpstool.util.ExtensionFileFilter;
103 import org.dinopolis.gpstool.util.FileUtil;
104 import org.dinopolis.gpstool.util.GeoMath;
105 import org.dinopolis.gpstool.util.UnitHelper;
106 import org.dinopolis.util.Debug;
107 import org.dinopolis.util.ResourceManager;
108 import org.dinopolis.util.Resources;
109 import org.dinopolis.util.commandarguments.CommandArgumentException;
110 import org.dinopolis.util.commandarguments.CommandArguments;
111 import org.dinopolis.util.gui.ActionStore;
112 import org.dinopolis.util.gui.MenuFactory;
113 import org.dinopolis.util.gui.ResourceEditorFrame;
114 import org.dinopolis.util.gui.SelectedButtonActionSynchronizer;
115 import org.dinopolis.util.gui.SplashScreen;
116 import org.dinopolis.util.servicediscovery.RepositoryClassLoader;
117 import org.dinopolis.util.servicediscovery.ServiceDiscovery;
118
119 //----------------------------------------------------------------------
120 /**
121 * This is an application that shows maps, tracks, gps position,
122 * etc. It heavily depends on its resources, as all default values are
123 * stored there. The information is organized and painted in layers.
124 *
125 * @author Christof Dallermassl
126 * @version $Revision: 1.44 $
127 */
128
129 public class GPSMap
130 implements PropertyChangeListener, GPSMapKeyConstants,
131 MapNavigationHook, StatusHook, Positionable
132 {
133
134 public final static String GPSMAP_VERSION = "0.4.15-pre9";
135 private final static String GPSMAP_CVS_VERSION = "$Revision: 1.44 $";
136
137 public final static String STD_PLUGINS_DIR_NAME = "plugins";
138
139 protected HookManager hook_manager_;
140
141 /** the layer to display the maps */
142 protected MultiMapLayer map_layer_;
143 protected PositionLayer position_layer_;
144 // protected TrackLayer track_layer_;
145 protected ShapeLayer shape_layer_;
146 protected LocationLayer location_layer_;
147 protected ScaleLayer scale_layer_;
148 protected GraticuleLayer graticule_layer_;
149
150 protected MapBean map_bean_;
151
152 protected JMenuBar menu_bar_;
153
154 protected JFrame main_frame_;
155
156 // protected MapKeyHandler map_key_handler_;
157 protected MapManager map_manager_;
158 protected TrackManagerImpl track_manager_;
159
160 protected StatusBar status_bar_;
161 protected Tachometer tacho_meter_;
162
163 protected static UnitHelper unit_helper_;
164
165 // protected MouseDelegator mouse_delegator_;
166 protected MouseModeManager mouse_mode_manager_;
167
168 protected Vector gui_plugins_ = new Vector();
169
170 /** the default center point */
171 protected LatLonPoint current_gps_position_ = new LatLonPoint(47.06005f,15.47314f);
172
173 protected LatLonPoint current_map_position_ = current_gps_position_;
174
175 /** destination for gps track */
176 protected LatLonPoint destination_position_;
177
178
179 protected PropertyChangeSupport property_change_support_;
180
181 /** the resource bundle (configuration) */
182 protected Resources resources_;
183
184 /** the log entry popup menu */;
185 private JPopupMenu map_entry_menu_;
186
187 /** the Resource editor */
188 private ResourceEditorFrame resource_editor_;
189
190 /** GPS processor */
191 private GPSDataProcessor gps_data_processor_;
192
193 /** the identifier used in the action store */
194 public final static String ACTION_STORE_ID = "GPSMap";
195
196 /** the name of the resource file */
197 private final static String RESOURCE_BOUNDLE_NAME = "GPSMap";
198
199 /** the name of the directory containing the resources */
200 public final static String USER_RESOURCE_DIR_NAME = ".gpsmap";
201
202 /** the action store */
203 private ActionStore action_store_;
204
205 /** the log4j logger */
206 public static Logger logger_;
207
208 protected boolean simulation_mode_ = false;
209
210 /** print warning to restart GPSMap if gps properties were changed */
211 protected boolean print_gps_device_properties_warning_ = false;
212
213 /** the service discoverer (for plugin functionality) */
214 public static ServiceDiscovery service_discovery_;
215 public static RepositoryClassLoader repository_class_loader_;
216
217 // -- action constants //
218
219 /** the name of the quit action */
220 public final static String ACTION_QUIT = "quit";
221
222 /** the name of the edit properties action */
223 public final static String ACTION_EDIT_RESOURCES = "edit_resources";
224
225 // the name of mouse mode properties action
226 public final static String ACTION_MOUSE_NAVIGATION_MODE = "mouse_navigation_mode";
227 public final static String ACTION_MOUSE_POSITION_MODE = "mouse_position_mode";
228 public final static String ACTION_MOUSE_DISTANCE_MODE = "mouse_distance_mode";
229
230 // map actions:
231 public final static String ACTION_ZOOM_IN = "zoom_in";
232 public final static String ACTION_ZOOM_OUT = "zoom_out";
233 public final static String ACTION_CENTER_MAP = "center_map";
234
235 // gps mode actions
236 public final static String ACTION_FOLLOW_ME_MODE = "followme_mode";
237 public final static String ACTION_SIMULATION_MODE = "simulation_mode";
238
239 // import actions
240 public final static String ACTION_IMPORT_GPSDRIVE = "import_gpsdrive";
241
242 // track actions
243 public final static String ACTION_DISPLAY_TRACK_MODE = "display_track_mode";
244 public final static String ACTION_SAVE_TRACK_MODE = "save_track_mode";
245 public final static String ACTION_CLEAR_TRACK = "clear_track";
246 public final static String ACTION_LOAD_TRACK = "load_track";
247
248 // layer actions
249 public final static String ACTION_TRACK_LAYER_ACTIVATE = "track_layer_activate";
250 public final static String ACTION_POSITION_LAYER_ACTIVATE = "position_layer_activate";
251 public final static String ACTION_MAP_LAYER_ACTIVATE = "map_layer_activate";
252 public final static String ACTION_SHAPE_LAYER_ACTIVATE = "shape_layer_activate";
253 public final static String ACTION_LOCATION_LAYER_ACTIVATE = "location_layer_activate";
254 public final static String ACTION_GRATICULE_LAYER_ACTIVATE = "graticule_layer_activate";
255 public final static String ACTION_TEST_LAYER_ACTIVATE = "test_layer_activate";
256 public final static String ACTION_SCALE_LAYER_ACTIVATE = "scale_layer_activate";
257
258 // location marker actions
259 public final static String ACTION_LOAD_LOCATION_MARKER = "load_location_marker";
260 public final static String ACTION_EXPORT_LOCATION_MARKER = "export_location_marker";
261 public final static String ACTION_IMPORT_LOCATION_MARKER = "import_location_marker";
262 public final static String ACTION_SHOW_MARKER_NAMES = "show_marker_names";
263 public final static String ACTION_SET_MARKER_GPS_POS = "set_marker_gps_pos";
264 public final static String ACTION_SELECT_MARKER_CATEGORIES = "select_marker_categories";
265 public final static String ACTION_DATABASE_MANAGER = "database_manager";
266 public final static String ACTION_LEVEL_OF_DETAIL_INCREASE = "level_of_detail_increase";
267 public final static String ACTION_LEVEL_OF_DETAIL_DECREASE = "level_of_detail_decrease";
268 public final static String ACTION_SEARCH_MARKER = "search_marker";
269
270 // save as... actions
271 public final static String ACTION_SAVE_AS_IMAGE_PLUGIN = "save_as_image_plugin";
272
273 // other actions
274 public final static String ACTION_RESET_TACHOMETER = "reset_tachometer";
275 public final static String ACTION_SET_SCALE = "set_scale";
276 public final static String ACTION_DOWNLOAD_MAP_POSITION = "download_map_position";
277 public final static String ACTION_DOWNLOAD_MAP_AREA = "download_map_area";
278 public final static String ACTION_LOAD_SHAPE = "load_shape";
279 // public final static String ACTION_VIEW_GPS_DATA = "view_gps_data";
280 public final static String ACTION_PRINT_MAP = "print_map";
281
282 // pan actions:
283 public final static String ACTION_PAN_WEST = "pan_west";
284 public final static String ACTION_PAN_EAST = "pan_east";
285 public final static String ACTION_PAN_NORTH = "pan_north";
286 public final static String ACTION_PAN_SOUTH = "pan_south";
287 public final static String ACTION_PAN_QUICK_WEST = "pan_quick_west";
288 public final static String ACTION_PAN_QUICK_EAST = "pan_quick_east";
289 public final static String ACTION_PAN_QUICK_NORTH = "pan_quick_north";
290 public final static String ACTION_PAN_QUICK_SOUTH = "pan_quick_south";
291
292 // scale action
293 public final static String ACTION_SCALE_1000 = "set_scale_1000";
294 public final static String ACTION_SCALE_2000 = "set_scale_2000";
295 public final static String ACTION_SCALE_5000 = "set_scale_5000";
296 public final static String ACTION_SCALE_10000 = "set_scale_10000";
297 public final static String ACTION_SCALE_25000 = "set_scale_25000";
298 public final static String ACTION_SCALE_50000 = "set_scale_50000";
299 public final static String ACTION_SCALE_100000 = "set_scale_100000";
300 public final static String ACTION_SCALE_200000 = "set_scale_200000";
301 public final static String ACTION_SCALE_500000 = "set_scale_500000";
302 public final static String ACTION_SCALE_1000000 = "set_scale_1000000";
303 public final static String ACTION_SCALE_2000000 = "set_scale_2000000";
304 public final static String ACTION_SCALE_5000000 = "set_scale_5000000";
305
306 // test action
307 public final static String ACTION_TESTACTION = "testaction";
308
309 // the keys for gps property change events
310
311 /** the key for the current location from the gps device. The
312 * value is a {@link com.bbn.openmap.LatLonPoint} object. */
313 public final static String PROPERTY_KEY_GPS_LOCATION = GPSDataProcessor.LOCATION;
314 /** the key for the heading from the gps device. Usually, you want to use
315 * <code>PROPERTY_KEY_CURRENT_HEADING</code> instead! The value
316 * is a Float object. */
317 public final static String PROPERTY_KEY_GPS_HEADING = GPSDataProcessor.HEADING;
318 /** the key for the heading either from the gps device or
319 * calculated from the last and the current location. This
320 * property is always triggered, even if the gps device does not
321 * send heading-information. The value is a Float object. */
322 public final static String PROPERTY_KEY_CURRENT_HEADING = "current.heading";
323 /** the key for the speed from the gps device. Usually, you want
324 * to use <code>PROPERTY_KEY_CURRENT_SPEED</code> instead! The
325 * value is a Float object and the speed is in kilometers per
326 * hour. */
327 public final static String PROPERTY_KEY_GPS_SPEED = GPSDataProcessor.SPEED;
328 /** the key for the speed either from the gps device or
329 * calculated from the last and the current location. This
330 * property is always triggered, even if the gps device does not
331 * send speed-information. The value is a Float object and the
332 * speed is in kilometers per hour. */
333 public final static String PROPERTY_KEY_CURRENT_SPEED = "current.speed";
334 /** the key for the altitude from the gps device. The
335 * value is a Float object and the altitude is given in meters. */
336 public final static String PROPERTY_KEY_GPS_ALTITUDE = GPSDataProcessor.ALTITUDE;
337 /** the key for the info of the gps satellites from the gps device. The
338 * value is an array of {@link org.dinopolis.gpstool.gpsinput.SatelliteInfo} objects. */
339 public final static String PROPERTY_KEY_GPS_SATELLITE_INFO = GPSDataProcessor.SATELLITE_INFO;
340 /** the key for the info of the gps position error. The
341 * value an {@link org.dinopolis.gpstool.gpsinput.GPSPositionError} object. */
342 public final static String PROPERTY_KEY_GPS_POS_ERROR = GPSDataProcessor.EPE;
343 public final static String PROPERTY_KEY_ROUTE_DESTINATION = "route.destination";
344 public final static String PROPERTY_KEY_ROUTE_DESTINATION_DISTANCE = "route.destination.distance";
345 public final static String PROPERTY_KEY_TOTAL_DISTANCE = "total.distance";
346
347
348 public final static float KM2MILES = 0.62137119f;
349 public final static float KM2NAUTIC = 0.54f;
350 public final static float METER2FEET = 3.280839895f;
351
352
353 //----------------------------------------------------------------------
354 // The GPSMap class
355 //----------------------------------------------------------------------
356
357 static
358 {
359 String log_file = "log4j.properties"; // searched in classpath (auxiliary directory!)
360 URL log_url = org.dinopolis.gpstool.GPSMap.class.getResource("/" + log_file);
361 // System.out.println("Log4j configuration url: "+log_url);
362 if(log_url != null)
363 {
364 if(log_url.getProtocol().equals("file"))
365 {
366 // use absolute path of file, so watching works:
367 PropertyConfigurator.configureAndWatch(log_url.getFile(),5000);
368 }
369 else
370 {
371 // use url (properties file may be inside jar file):
372 PropertyConfigurator.configure(log_url);
373 }
374 logger_ = Logger.getLogger("org.dinopolis.gpstool.GPSMap");
375 }
376 else
377 System.err.println("WARNING: Could not find log4j configuration file: '"
378 +log_file+"' - logging disabled.");
379 }
380
381
382
383 //----------------------------------------------------------------------
384 /**
385 * Empty Constructor
386 */
387 public GPSMap()
388 {
389 this(new String[]{});
390 }
391
392
393 //----------------------------------------------------------------------
394 /**
395 * Constructor using the command line arguments to override the resources.
396 *
397 * @param args command line argument (see printHelp for details)
398 */
399 public GPSMap(String[] args)
400 {
401
402 System.out.println("GPSylon V"+GPSMAP_VERSION);
403 System.out.println("by Christof Dallermassl (christof@dallermassl.at)");
404 System.out.println("latest version at: http://gpsmap.sourceforge.net");
405 System.out.println("using");
406 System.out.println("Java Version: "+System.getProperty("java.vm.vendor")+" "
407 +System.getProperty("java.vm.version"));
408
409 property_change_support_ = new PropertyChangeSupport(this);
410
411 // create helper class for unit converstion and formatting:
412 unit_helper_ = new UnitHelper();
413
414 // setup the GUI
415 loadResources();
416 int splash_progress = 0;
417 int splash_max_progress = resources_.getInt(KEY_SPLASH_MAX_PROGRESS,splash_progress);
418 SplashScreen splash_screen = new SplashScreen(resources_.getIcon(KEY_SPLASH_IMAGE),-1,
419 0,splash_max_progress);
420
421 setLocale();
422 initFilenames();
423 splash_screen.setStatus("Processing command line arguments",splash_progress+=5);
424 processCommandLineArguments(args);
425 print_gps_device_properties_warning_ = true;
426
427 // initialize for plugins:
428 splash_screen.setStatus("Initialize plugin architecture",splash_progress+=5);
429 initializePluginArchitecture();
430
431 /** the Actions */
432 Action[] actions_ = { new QuitAction(),
433 new EditResourcesAction(),
434 new ZoomInAction(),
435 new ZoomOutAction(),
436 new PanAction(ACTION_PAN_WEST,-0.2f,0f),
437 new PanAction(ACTION_PAN_EAST,0.2f,0f),
438 new PanAction(ACTION_PAN_NORTH,0f,-0.2f),
439 new PanAction(ACTION_PAN_SOUTH,0f,0.2f),
440 new PanAction(ACTION_PAN_QUICK_WEST,-0.8f,0f),
441 new PanAction(ACTION_PAN_QUICK_EAST,0.8f,0f),
442 new PanAction(ACTION_PAN_QUICK_NORTH,0f,-0.8f),
443 new PanAction(ACTION_PAN_QUICK_SOUTH,0f,0.8f),
444 new ScaleAction(ACTION_SCALE_1000,1000f),
445 new ScaleAction(ACTION_SCALE_2000,2000f),
446 new ScaleAction(ACTION_SCALE_5000,5000f),
447 new ScaleAction(ACTION_SCALE_10000,10000f),
448 new ScaleAction(ACTION_SCALE_25000,25000f),
449 new ScaleAction(ACTION_SCALE_50000,50000f),
450 new ScaleAction(ACTION_SCALE_100000,100000f),
451 new ScaleAction(ACTION_SCALE_200000,200000f),
452 new ScaleAction(ACTION_SCALE_500000,500000f),
453 new ScaleAction(ACTION_SCALE_1000000,1000000f),
454 new ScaleAction(ACTION_SCALE_2000000,2000000f),
455 new ScaleAction(ACTION_SCALE_5000000,5000000f),
456 new ResetTachometerAction(),
457 new SimulationModeAction(),
458 new SetScaleAction(),
459 new CenterMapAction(),
460 new SaveAsImagePluginAction(),
461 new PrintMapAction(),
462 // new TestAction(),
463 new ImportGpsDriveAction()
464 };
465
466
467 action_store_ = ActionStore.getStore(ACTION_STORE_ID);
468 action_store_.addActions(actions_);
469
470 // Create a Swing frame. The OpenMapFrame knows how to use
471 // the MapHandler to locate and place certain objects.
472 // main_frame_ = new OpenMapFrame("GPS Map");
473 main_frame_ = new JFrame("GPSylon V"+GPSMAP_VERSION);
474 // Size the frame appropriately
475 main_frame_.setSize(640, 480);
476
477 main_frame_.addWindowListener(new WindowAdapter()
478 {
479 public void windowClosing(WindowEvent e)
480 {
481 // TODO QuitAction!!!! FIXXME????
482 try
483 {
484 if(gps_data_processor_ != null)
485 gps_data_processor_.close();
486 }
487 catch(GPSException gpse)
488 {
489 System.err.println("WARNING: could not close connection to gps device: "
490 +gpse.getMessage());
491 }
492
493 System.exit(0);
494 }
495 }
496 );
497
498 checkLockFiles(resources_.getStringArray(KEY_LOCKFILES));
499
500 // create hook_manager
501 hook_manager_ = new HookManager();
502
503 splash_screen.setStatus("Connecting to gps device",splash_progress+=5);
504 connectGPSDevice();
505
506 updateResources(null);
507 updateWindowLocation();
508
509
510 // Create a MapBean
511 splash_screen.setStatus("Create map component",splash_progress+=5);
512 map_bean_ = new MapBean();
513 map_bean_.setBackgroundColor(new Color(0,0,0));
514 map_bean_.setDoubleBuffered(true);
515
516 map_manager_ = new MapManager();
517 map_manager_.initialize(resources_,main_frame_);
518
519 track_manager_ = new TrackManagerImpl();
520
521 // create MouseModeManager
522 mouse_mode_manager_ = new MouseModeManager();
523
524 // initialize data for plugins (PluginSupport):
525 splash_screen.setStatus("Initialize modules for plugins",splash_progress+=5);
526 hook_manager_.setMapManagerHook(map_manager_);
527 hook_manager_.setMapNavigationHook(this);
528 hook_manager_.setStatusHook(this);
529 hook_manager_.setMainFrame(main_frame_);
530 hook_manager_.setMapComponent(map_bean_);
531 hook_manager_.setPropertyChangeSupport(property_change_support_);
532 hook_manager_.setResources(resources_);
533 hook_manager_.setTrackManager(track_manager_);
534 hook_manager_.setServiceDiscovery(service_discovery_);
535 hook_manager_.setUnitHelper(unit_helper_);
536 hook_manager_.setMouseModeManager(mouse_mode_manager_);
537
538 track_manager_.initialize(hook_manager_);
539
540
541 // Set the default gps position
542 double latitude = resources_.getDouble(KEY_CURRENT_GPS_POSITION_LATITUDE);
543 double longitude = resources_.getDouble(KEY_CURRENT_GPS_POSITION_LONGITUDE);
544 current_gps_position_ = new LatLonPoint(latitude,longitude);
545 property_change_support_.firePropertyChange(PROPERTY_KEY_GPS_LOCATION,null,current_gps_position_);
546
547 // Set the default map position
548 latitude = resources_.getDouble(KEY_CURRENT_MAP_POSITION_LATITUDE);
549 longitude = resources_.getDouble(KEY_CURRENT_MAP_POSITION_LONGITUDE);
550 current_map_position_ = new LatLonPoint(latitude,longitude);
551
552 // set projection (including position and scale)
553 splash_screen.setStatus("Set default projection",splash_progress+=5);
554 Projection projection = new FlatProjection(current_map_position_,
555 (float)resources_.getDouble(KEY_MAP_SCALE),0,0);
556 map_bean_.setProjection(projection);
557
558 main_frame_.getContentPane().add(map_bean_,BorderLayout.CENTER);
559
560 splash_screen.setStatus("Create status bar",splash_progress+=5);
561 status_bar_ = new StatusBar(hook_manager_);
562 main_frame_.getContentPane().add(status_bar_,BorderLayout.SOUTH);
563
564
565 System.out.println("Plugins in the following locations are used:");
566 List plugin_dirs = repository_class_loader_.getRepositories();
567 Iterator dir_iterator = plugin_dirs.iterator();
568 if(!dir_iterator.hasNext())
569 System.out.println("no directories given");
570 else
571 {
572 while(dir_iterator.hasNext())
573 {
574 System.out.println(dir_iterator.next());
575 }
576 }
577
578
579 // instantiate, initialize and add plugins (gui and mousemodes)
580 splash_screen.setStatus("Initialize plugins",splash_progress+=5);
581 initializePlugins();
582
583 splash_screen.setStatus("Add graticule layer",splash_progress+=5);
584 graticule_layer_ = new GraticuleLayer();
585 graticule_layer_.initialize(resources_);
586 map_bean_.add(graticule_layer_);
587
588 splash_screen.setStatus("Add scale layer",splash_progress+=5);
589 scale_layer_ = new ScaleLayer();
590 scale_layer_.initializePlugin(hook_manager_);
591 map_bean_.add(scale_layer_);
592
593 splash_screen.setStatus("Add shape layer",splash_progress+=5);
594 shape_layer_ = new ShapeLayer(resources_);
595 map_bean_.add(shape_layer_);
596
597 // track_layer_ = new TrackLayer();
598 // track_layer_.initialize(hook_manager_);
599 // map_bean_.add(track_layer_);
600
601 splash_screen.setStatus("Add position layer",splash_progress+=5);
602 position_layer_ = new PositionLayer(resources_);
603 map_bean_.add(position_layer_);
604 map_bean_.addMouseListener(position_layer_);
605 map_bean_.addMouseMotionListener(position_layer_);
606
607 position_layer_.setNewCurrentPosition(current_gps_position_);
608
609 // the map key handler must directly follow the position
610 // layer, otherwise no key events are received!
611 // map_key_handler_ = new MapKeyHandler(this);
612 // position_layer_.addKeyListener(map_key_handler_);
613
614 splash_screen.setStatus("Add location layer",splash_progress+=5);
615 location_layer_ = new LocationLayer();
616 location_layer_.initialize(resources_,this,this,main_frame_);
617 map_bean_.add(location_layer_);
618 map_bean_.addMouseListener(location_layer_);
619
620 splash_screen.setStatus("Add map layer",splash_progress+=5);
621 map_layer_ = new MultiMapLayer();
622 map_layer_.initializePlugin(hook_manager_);
623 map_bean_.add(map_layer_);
624
625
626 tacho_meter_ = new Tachometer();
627
628 // connect some modules by the use of their eventhandler:
629 addPropertyChangeListener(PROPERTY_KEY_GPS_LOCATION, position_layer_);
630 addPropertyChangeListener(PROPERTY_KEY_CURRENT_HEADING, position_layer_);
631 resources_.addPropertyChangeListener(KEY_POSITION_USE_ICON,position_layer_);
632 // resources_.addPropertyChangeListener(KEY_POSITION_FOLLOW_ME_RELATIVE_BORDER,position_layer_);
633 resources_.addPropertyChangeListener(KEY_POSITION_FOLLOW_ME_PITCH,position_layer_);
634
635 // addPropertyChangeListener(PROPERTY_KEY_GPS_LOCATION, track_layer_);
636 // addPropertyChangeListener(PROPERTY_KEY_GPS_SPEED, track_layer_);
637 // addPropertyChangeListener(PROPERTY_KEY_GPS_ALTITUDE, track_layer_);
638 // addPropertyChangeListener(PROPERTY_KEY_CURRENT_SPEED, track_layer_);
639
640 addPropertyChangeListener(PROPERTY_KEY_GPS_LOCATION, status_bar_);
641 addPropertyChangeListener(PROPERTY_KEY_CURRENT_HEADING, status_bar_);
642 // resources_.addPropertyChangeListener(KEY_ANGLE_FORMAT_LATLON, status_bar_);
643 // resources_.addPropertyChangeListener(KEY_ANGLE_FORMAT_HEADING, status_bar_);
644 // addPropertyChangeListener(PROPERTY_KEY_GPS_SPEED, status_bar_);
645 addPropertyChangeListener(PROPERTY_KEY_CURRENT_SPEED, status_bar_);
646 addPropertyChangeListener(PROPERTY_KEY_TOTAL_DISTANCE, status_bar_);
647 addPropertyChangeListener(PROPERTY_KEY_ROUTE_DESTINATION_DISTANCE, status_bar_);
648 addPropertyChangeListener(PROPERTY_KEY_GPS_SATELLITE_INFO, status_bar_);
649 addPropertyChangeListener(PROPERTY_KEY_GPS_POS_ERROR, status_bar_);
650
651 addPropertyChangeListener(PROPERTY_KEY_GPS_LOCATION, tacho_meter_);
652 addPropertyChangeListener(PROPERTY_KEY_GPS_SPEED, tacho_meter_);
653 resources_.addPropertyChangeListener(KEY_TACHOMETER_REFRESH_TIME, tacho_meter_);
654
655 resources_.addPropertyChangeListener(KEY_UNIT_DISTANCE, scale_layer_);
656 resources_.addPropertyChangeListener(KEY_GRATICULE_DRAW_TEXT,graticule_layer_);
657
658 resources_.addPropertyChangeListener(KEY_LOCATION_MARKER_TEXT_COLOR,location_layer_);
659 resources_.addPropertyChangeListener(KEY_LOCATION_MARKER_TEXT_BACKGROUND_COLOR,location_layer_);
660 resources_.addPropertyChangeListener(KEY_LOCATION_MARKER_TEXT_FONT_SIZE,location_layer_);
661 resources_.addPropertyChangeListener(KEY_LOCATION_MARKER_SHOW_NAMES,location_layer_);
662
663 position_layer_.addPropertyChangeListener(this);
664 position_layer_.setMapNavigationHook(this);
665
666 // add the status bar as StatusLayerListener for all layers:
667 map_layer_.addLayerStatusListener(status_bar_);
668 // track_layer_.addLayerStatusListener(status_bar_);
669 shape_layer_.addLayerStatusListener(status_bar_);
670 graticule_layer_.addLayerStatusListener(status_bar_);
671 location_layer_.addLayerStatusListener(status_bar_);
672
673 // map_layer_.addMaps(map_manager_.getMapInfos());
674
675 // create popup menu
676 // map_popup_menu_ = createPopupMenu();
677
678 // add menu bar at the end (maybe some modules add actions to it!)
679 menu_bar_ = MenuFactory.createMenuBar(resources_, action_store_);
680
681 addMouseModesToMenu();
682 addGuiPluginsToMenu();
683
684 // disable the menus "mouse modes" and "plugins" if they are not used:
685 disableMenuIfEmpty(resources_.getString(KEY_MENU_PLUGIN_LABEL));
686 disableMenuIfEmpty(resources_.getString(KEY_MENU_MOUSE_MODE_LABEL));
687 mouse_mode_manager_.activateMouseMode(resources_.getString(KEY_MOUSE_MODE_DEFAULT_MODE));
688
689 main_frame_.setJMenuBar(menu_bar_);
690
691 // map_bean_.add(graticule_layer_);
692 // map_bean_.add(test_layer_);
693 // map_bean_.add(scale_layer_);
694 // map_bean_.add(location_layer_);
695 // map_bean_.add(shape_layer_);
696 // // map_bean_.add(track_layer_);
697 // // map_bean_.add(position_layer_);
698 // // map_bean_.add(map_layer_);
699
700 // start all plugins:
701 Iterator iterator = gui_plugins_.iterator();
702 GuiPlugin plugin;
703 while(iterator.hasNext())
704 {
705 plugin = (GuiPlugin)iterator.next();
706 try
707 {
708 splash_screen.setStatus("Start Plugin "+plugin.getPluginName(),splash_progress+=5);
709 plugin.startPlugin();
710 }
711 catch(Exception e)
712 {
713 logger_.error("ERROR: plugin '"+plugin.getPluginName()+" threw an exception on startup: ");
714 e.printStackTrace();
715 }
716 }
717
718
719 main_frame_.setVisible(true);
720 // main_frame_.getContentPane().requestFocus();
721 // main_frame_.getContentPane().addKeyListener(new GPSMapKeyListener());
722
723 // if(Debug.DEBUG)
724 // Debug.println("splash","final splash progress reached: "+splash_progress);
725 resources_.setInt(KEY_SPLASH_MAX_PROGRESS,splash_progress);
726 splash_screen.setStatus("Finished");
727 splash_screen.close();
728 }
729
730
731 //----------------------------------------------------------------------
732 /**
733 * Loads the resource file, or exits on a MissingResourceException.
734 */
735
736 void loadResources()
737 {
738 try
739 {
740 resources_ =
741 ResourceManager.getResources(GPSMap.class,
742 RESOURCE_BOUNDLE_NAME,
743 USER_RESOURCE_DIR_NAME,
744 Locale.getDefault());
745 resources_.addPropertyChangeListener(this);
746 }
747 catch (MissingResourceException mre)
748 {
749 // if (Debug.DEBUG)
750 // Debug.println("GPSMap", mre.toString()+'\n'+
751 // Debug.getStackTrace(mre));
752 logger_.debug(mre.toString()+'\n'+
753 Debug.getStackTrace(mre));
754 logger_.fatal("resource file '"+RESOURCE_BOUNDLE_NAME+".properties' not found");
755 logger_.fatal("please make sure that this file is within the classpath !");
756 // System.err.println("resource file '"+RESOURCE_BOUNDLE_NAME+".properties' not found");
757 // System.err.println("please make sure that this file is within the classpath !");
758 System.exit(1);
759 }
760 }
761
762 //----------------------------------------------------------------------
763 /**
764 * Sets the locales given in the resource file, if any.
765 */
766
767 void setLocale()
768 {
769 String language = resources_.getString("locale.language", null);
770 String country = resources_.getString("locale.country", null);
771 if ((language != null) && (country != null))
772 Locale.setDefault(new Locale(language, country));
773 }
774
775 //----------------------------------------------------------------------
776 /**
777 * Initializes the file- and directorynames, if they are unset.
778 */
779
780 void initFilenames()
781 {
782 String main_dir = resources_.getString(KEY_FILE_MAINDIR,null);
783 if((main_dir == null) || (main_dir.length() == 0))
784 {
785 // maindir:
786 String maindir = System.getProperty("user.home")+ File.separator + USER_RESOURCE_DIR_NAME;
787 // System.out.println("maindir: "+maindir);
788 resources_.setString(KEY_FILE_MAINDIR,maindir);
789 // System.out.println("maindir from resources: "+resources_.getString(KEY_FILE_MAINDIR));
790 }
791 }
792
793
794
795
796 //----------------------------------------------------------------------
797 /**
798 * Looks for a menu or a menu item with the given name in the given
799 * menu bar.
800 *
801 * @param menu_bar the menu bar to search.
802 * @param name the name to search for.
803 * @return the menu/menuitem or <ocde>null</code> if no menu was found.
804 */
805 protected JMenuItem findMenuItem(JMenuBar menu_bar, String name)
806 {
807 int menu_index = 0;
808 JMenuItem menu_item;
809 while(menu_index < menu_bar.getMenuCount())
810 {
811 menu_item = menu_bar.getMenu(menu_index);
812 if(menu_item.getText().equals(name))
813 {
814 return(menu_item);
815 }
816 menu_index++;
817 }
818 // nothing found:
819 return(null);
820 }
821
822 //----------------------------------------------------------------------
823 /**
824 * Looks for a menu or a menu item with the given name in the given menu.
825 *
826 * @param menu the menu to search.
827 * @param name the name to search for.
828 * @return the menu/menuitem or <ocde>null</code> if no menu was found.
829 */
830 protected JMenuItem findMenuItem(JMenu menu, String name)
831 {
832 int menu_index = 0;
833 JMenuItem menu_item;
834 while(menu_index < menu.getItemCount())
835 {
836 menu_item = menu.getItem(menu_index);
837 if(menu_item.getText().equals(name))
838 {
839 return(menu_item);
840 }
841 menu_index++;
842 }
843 // nothing found:
844 return(null);
845 }
846
847 //----------------------------------------------------------------------
848 /**
849 * Disables the menu with the given name in the menu bar if it does
850 * not contain any menu items.
851 *
852 * @param main_menu_name the name of the menu
853 */
854 protected void disableMenuIfEmpty(String main_menu_name)
855 {
856 JMenu menu = (JMenu)findMenuItem(menu_bar_,main_menu_name);
857 if ((menu != null) && (menu.getItemCount() == 0))
858 menu.setEnabled(false);
859 }
860
861
862 //----------------------------------------------------------------------
863 /**
864 * Adds the mouse modes of the MouseModeManager to the menu bar (Menu
865 * Mouse Mode).
866 *
867 */
868 protected void addMouseModesToMenu()
869 {
870 // find the menu that should contain the mouse modes (control/mouse mode):
871
872 JMenu mouse_mode_menu = (JMenu)findMenuItem(menu_bar_,
873 resources_.getString(KEY_MENU_MOUSE_MODE_LABEL));
874 if(mouse_mode_menu != null)
875 {
876 JMenuItem[] mouse_mode_items = mouse_mode_manager_.getMenuItems();
877 for(int item_count = 0; item_count < mouse_mode_items.length; item_count++)
878 {
879 // System.out.println("Adding Mouse Mode "+mouse_mode_items[item_count] +" to menu.");
880 mouse_mode_menu.add(mouse_mode_items[item_count]);
881 }
882 }
883 else
884 {
885 logger_.error("ERROR: Could not find 'Mouse Mode' menu, no mouse modes added to menu!");
886 }
887 }
888
889 //----------------------------------------------------------------------
890 /**
891 * Adds the sub menu of plugins to the menu bar (Menu Plugin).
892 *
893 * @param plugin_sub_menu the sub menu of the plugin to add to the Plugin Menu.
894 */
895 protected void addToPluginsMenu(JMenuItem plugin_sub_menu)
896 {
897 // find the menu that should contain the plugin:
898
899 JMenu plugin_menu = (JMenu)findMenuItem(menu_bar_,
900 resources_.getString(KEY_MENU_PLUGIN_LABEL));
901 if(plugin_menu != null)
902 {
903 plugin_menu.add(plugin_sub_menu);
904 }
905 else
906 {
907 logger_.error("ERROR: Could not find 'Plugins' menu, no plugin menus added to menu!");
908 }
909 }
910
911 //----------------------------------------------------------------------
912 /**
913 * Adds the layers of the plugins to the "layers" menu (to switch them
914 * on/off).
915 * @param action the action to switch them on/off.
916 */
917 protected void addOnOffActionToLayersMenu(GuiPluginOnOffAction action)
918 {
919 JMenu layer_menu = (JMenu)findMenuItem(menu_bar_,
920 resources_.getString(KEY_MENU_LAYERS_LABEL));
921 if(layer_menu != null)
922 {
923 JCheckBoxMenuItem menu_item = new JCheckBoxMenuItem(action);
924 // keep the state of the menu and the action in sync
925 SelectedButtonActionSynchronizer syncer =
926 new SelectedButtonActionSynchronizer(menu_item,action);
927 layer_menu.add(menu_item);
928 boolean active = action.getPlugin().isActive();
929 menu_item.setSelected(active);
930 }
931 else
932 {
933 logger_.warn("WARNING: could not find 'layers' menu, do not add on/off action");
934 }
935 }
936 //----------------------------------------------------------------------
937 /**
938 * Processes the command line arguments and sets resource values if
939 * needed.
940 *
941 * @param arguments The command line arguments
942 */
943
944 protected void processCommandLineArguments(String[] arguments)
945 {
946 String[] valid_args =
947 new String[] {"device*","d*","help","h","speed#","s#","gpsfile*","f*",
948 "nmealogfile*","l*","gpsdhost*","g*","gpsdport#","p#",
949 "file","gpsd","serial","nmea","garmin"};
950
951 CommandArguments args = null;
952 try
953 {
954 args = new CommandArguments(arguments,valid_args);
955 }
956 catch(CommandArgumentException cae)
957 {
958 cae.printStackTrace();
959 }
960 if (args != null)
961 {
962 if(args.isSet("help") || (args.isSet("h")))
963 {
964 printHelp();
965 System.exit(0);
966 }
967
968 if (args.isSet("nmea"))
969 {
970 resources_.setString(KEY_GPS_DEVICE_PROTOCOL,VALUE_KEY_DEVICE_PROTOCOL_NMEA);
971 }
972 if (args.isSet("garmin"))
973 {
974 resources_.setString(KEY_GPS_DEVICE_PROTOCOL,VALUE_KEY_DEVICE_PROTOCOL_GARMIN);
975 }
976 if (args.isSet("device"))
977 {
978 resources_.setString(KEY_GPS_DEVICE_SERIAL_PORT,args.getStringValue("device"));
979 resources_.setString(KEY_GPS_DEVICE_MODE,VALUE_KEY_DEVICE_MODE_SERIAL);
980 }
981 else
982 if (args.isSet("d"))
983 {
984 resources_.setString(KEY_GPS_DEVICE_SERIAL_PORT,args.getStringValue("d"));
985 resources_.setString(KEY_GPS_DEVICE_MODE,VALUE_KEY_DEVICE_MODE_SERIAL);
986 }
987
988 if (args.isSet("speed") || args.isSet("s"))
989 {
990 String protocol = resources_.getString(KEY_GPS_DEVICE_PROTOCOL);
991 int speed = args.getIntegerValue("speed").intValue();
992 int default_speed = -1;
993 if(protocol.equals(VALUE_KEY_DEVICE_PROTOCOL_GARMIN))
994 default_speed = resources_.getInt(KEY_GPS_DEVICE_SERIAL_SPEED_DEFAULT_GARMIN);
995 if(protocol.equals(VALUE_KEY_DEVICE_PROTOCOL_NMEA))
996 default_speed = resources_.getInt(KEY_GPS_DEVICE_SERIAL_SPEED_DEFAULT_NMEA);
997 // if(resources_.getString(KEY_GPS_DEVICE_PROTOCOL).equals(VALUE_KEY_DEVICE_PROTOCOL_SIRF2))
998 // default_speed = resources_.getInt(KEY_GPS_DEVICE_SERIAL_SPEED_DEFAULT_SIRF2);
999
1000 if((speed != default_speed) && (default_speed > 0))
1001 {
1002 logger_.warn("WARNING: selected speed ("+speed+") is not the default speed ("+default_speed+")\n"
1003 +" for the chosen protocol! GPS device may not work!");
1004 }
1005 resources_.setInt(KEY_GPS_DEVICE_SERIAL_SPEED,speed);
1006 resources_.setString(KEY_GPS_DEVICE_MODE,VALUE_KEY_DEVICE_MODE_SERIAL);
1007 }
1008 else
1009 if (args.isSet("s"))
1010 {
1011 resources_.setInt(KEY_GPS_DEVICE_SERIAL_SPEED,args.getIntegerValue("s").intValue());
1012 resources_.setString(KEY_GPS_DEVICE_MODE,VALUE_KEY_DEVICE_MODE_SERIAL);
1013 }
1014
1015 if (args.isSet("gpsfile") || args.isSet("f"))
1016 {
1017 String filename;
1018 if(args.isSet("f"))
1019 filename = args.getStringValue("f");
1020 else
1021 filename = args.getStringValue("gpsfile");
1022
1023 if(filename.equals("none"))
1024 {
1025 resources_.setString(KEY_GPS_DEVICE_DATA_FILENAME,"");
1026 resources_.setString(KEY_GPS_DEVICE_MODE,VALUE_KEY_DEVICE_MODE_NONE);
1027 }
1028 else
1029 {
1030 resources_.setString(KEY_GPS_DEVICE_DATA_FILENAME,filename);
1031 resources_.setString(KEY_GPS_DEVICE_MODE,VALUE_KEY_DEVICE_MODE_FILE);
1032 }
1033
1034 }
1035 else
1036 if (args.isSet("f"))
1037 {
1038 resources_.setString(KEY_GPS_DEVICE_DATA_FILENAME,args.getStringValue("f"));
1039 resources_.setString(KEY_GPS_DEVICE_MODE,VALUE_KEY_DEVICE_MODE_FILE);
1040 }
1041
1042 if (args.isSet("nmealogfile") || (args.isSet("l")))
1043 {
1044 String nmea_log_file;
1045 if(args.isSet("nmealogfile"))
1046 nmea_log_file = args.getStringValue("nmealogfile");
1047 else
1048 nmea_log_file = args.getStringValue("l");
1049
1050 if(nmea_log_file.equals("none"))
1051 resources_.setString(KEY_GPS_DEVICE_NMEALOGFILE,"");
1052 else
1053 resources_.setString(KEY_GPS_DEVICE_NMEALOGFILE,nmea_log_file);
1054 }
1055
1056 if (args.isSet("gpsdhost"))
1057 {
1058 resources_.setString(KEY_GPS_DEVICE_GPSD_HOST,args.getStringValue("gpsdhost"));
1059 resources_.setString(KEY_GPS_DEVICE_MODE,VALUE_KEY_DEVICE_MODE_FILE);
1060 }
1061 else
1062 if (args.isSet("g"))
1063 {
1064 resources_.setString(KEY_GPS_DEVICE_GPSD_HOST,args.getStringValue("g"));
1065 resources_.setString(KEY_GPS_DEVICE_MODE,VALUE_KEY_DEVICE_MODE_FILE);
1066 }
1067
1068 if (args.isSet("gpsdport"))
1069 {
1070 resources_.setString(KEY_GPS_DEVICE_GPSD_PORT,args.getStringValue("gpsdport"));
1071 resources_.setString(KEY_GPS_DEVICE_MODE,VALUE_KEY_DEVICE_MODE_FILE);
1072 }
1073 else
1074 if (args.isSet("p"))
1075 {
1076 resources_.setString(KEY_GPS_DEVICE_GPSD_PORT,args.getStringValue("p"));
1077 resources_.setString(KEY_GPS_DEVICE_MODE,VALUE_KEY_DEVICE_MODE_FILE);
1078 }
1079
1080 if (args.isSet("file"))
1081 {
1082 resources_.setString(KEY_GPS_DEVICE_MODE,VALUE_KEY_DEVICE_MODE_FILE);
1083 }
1084 if (args.isSet("gpsd"))
1085 {
1086 resources_.setString(KEY_GPS_DEVICE_MODE,VALUE_KEY_DEVICE_MODE_GPSD);
1087 }
1088 if (args.isSet("serial"))
1089 {
1090 resources_.setString(KEY_GPS_DEVICE_MODE,VALUE_KEY_DEVICE_MODE_SERIAL);
1091 }
1092// if (args.isSet("alarmfile"))
1093// {
1094// String filename = args.getStringValue("alarmfile");
1095// if(filename.equals("none"))
1096// filename = "";
1097// resources_.setString(KEY_ALARM_FILE,filename);
1098// }
1099 }
1100 }
1101
1102//----------------------------------------------------------------------
1103/**
1104 * Prints help for commandline options.
1105 */
1106
1107 public void printHelp()
1108 {
1109 System.out.println("GPSMap "+GPSMAP_VERSION);
1110 System.out.println("Written by Christof Dallermassl in 2002");
1111 System.out.println("email: cdaller@iicm.edu");
1112 System.out.println("This Programm is licenced under the GPL");
1113 System.out.println("Comments are welcomed!");
1114 System.out.println("");
1115 System.out.println("Usage:");
1116 System.out.println("GPSMap [options]");
1117 System.out.println();
1118 System.out.println("Available Options:");
1119 System.out.println("--help, -h: this screen");
1120 System.out.println("--device, -d <device>: serial device for NMEA device (e.g. /dev/ttyS0 or COM1)");
1121 System.out.println("--speed, -s <speed>: speed for serial device (NMEA uses 4800 (default))");
1122 System.out.println("--nmea: the serial device is a NMEA device");
1123 System.out.println("--garmin: the serial device is a Garmin device");
1124 System.out.println("--gpsfile, -f <filename>: the file is used as input for NMEA data (if set to 'none', no file is used)");
1125 System.out.println("--gpsdhost, -g <hostname> : NMEA data is fetched from gpsd (gps data server)");
1126 System.out.println("--gpsdport, -p <port>: the port of the gpsd server");
1127 System.out.println("--nmealogfile, -l <filename>: NMEA data is logged to this file (if set to 'none', no file is used)");
1128 System.out.println("--file: NMEA data is read from a file (given on commandline or set in properties)");
1129 System.out.println("--serial: NMEA data is read from serial device (given on commandline or set in properties)");
1130 System.out.println("--gpsd: NMEA data is read from gpsd server (given on