Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

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