This is a short "How-To" on using Garmin MapSource inside a Linux system, including use of the USB connection to the GPS receiver. Essentially, it makes use of a virtual system based on VirtualBox that is running Microsoft Windows XP as "guest" on the Linux "host". Please note that this description is rather specific to Fedora 8, with some additional notes for Fedora 11.
The standard software for Garmin GPS units is Garmin MapSource. It is used to plan routes, to upload data (maps, routes, waypoints etc.) to the GPS receiver, and to retrieve track, waypoint and route information from the GPSr.
Garmin MapSource is one of the few applications that still have no equivalent in the Linux world. Although a dual-boot system is easy to set up, I see no point in rebooting the computer just for a single application.
One solution that is now truly mature is "virtualisation". Essentially, this allows to run one OS, such as Microsoft Windows, as "guest" inside another OS, the "host" - in my case Linux.
The product that I am using with success is VirtualBox, a commercial and proprietary (with a limited GPL version) x86 virtualizer. Albeit an open-source version is available, I had to go for the proprietary release since this is the only one that provides USB controller emulation.
Installation is straightforward. In a nutshell, you download the "VirtualBox for Linux Hosts" binary for your distribution (here, Fedora 8) from the manufacturer's website, and install it using yum:
yum install kernel-devel yum --nogpgcheck localinstall VirtualBox-1.5.4_27034_fedora8-1.i586.rpm
The kernel headers are required since VirtualBox compiles and loads its own Kernel module. Thus, whenever the kernel is updated, the kernel module has to be recompiled (it just takes a few seconds):
/etc/init.d/vboxdrv setup
Fedora 11: you need the package dkms, kernel-headers and the devel-package for your specific kernel. On my system, the latter is now called kernel-PAE-devel. With dkms installed, the recompilation of the kernel module is performed automagically!
All that remains is to add the user that is running VirtualBox in the group vboxusers.
After that, you can launch VirtualBox and set up a virtual system, then install the guest operating system - simply use the Wizard and/or refer to the manual. In my case, the guest is Microsoft Windows XP SP2.
When the install is complete, do not forget to install the "VirtualBox Guest Additions". Among others, they provide a video driver that allows re-sizing the Windows window ;-) to any size and at any time.
To exchange data between this Microsoft Windows guest and the Linux host, I use a shared drive (please refer to the manual). For reasons of security and privacy, I do not allow any Internet connection for the Windows guest.
From time to time, updates for VirtualBox are released. The update is even easier than the initial install - download the "VirtualBox for Linux Hosts" binary for your distribution (here, Fedora 8) from the manufacturer's website, and install it as above using yum:
yum --nogpgcheck localinstall VirtualBox-2.1.4_42893_fedora8-1.i386.rpm
yum will automatically take care about the details of the update process, remove the obsolete version and compile and load the new Kernel module.
At this time, you can install Garmin Mapsource. The only problem that remains is the USB connection to the GPSr, and it took me one evening to resolve this.
The key problem was that the current user (running VirtualBox) needs access to the USB filesystem, which is by default not the case in most distributions. A clear symptom was that the USB devices are listed but "greyed out" in the VirtualBox menu.
This issue is resolved as of VirtualBox 3.0.8. The following information is thus provided mainly for historical reference:
As usbfs is a virtual filesystem, its permissions can only be changed at boot time. How this is done in depends on the particular distribution - the VirtualBox manual says it nicely: "The various distributions are very creative from which script the usbfs filesystem is mounted. Sometimes the command is hidden in unexpected places."
For Fedora 11, it is sufficient to umount /proc/bus/usb ... see this bug report for an explanation.
For Fedora 8, usbfs is mounted via /etc/rc.sysinit. The two commented lines below show the original entries; what is added is the mount option -o devgid=500,devmode=664, where "500" is the numerical group id for the group vboxusers (see /etc/group).
if [ ! -d /proc/bus/usb ]; then
modprobe usbcore >/dev/null 2>&1 && mount -n -t usbfs -o devgid=500,devmode=664 /proc/bus/usb /proc/bus/usb
# modprobe usbcore >/dev/null 2>&1 && mount -n -t usbfs /proc/bus/usb /proc/bus/usb
else
mount -n -t usbfs -o devgid=500,devmode=664 /proc/bus/usb /proc/bus/usb
# mount -n -t usbfs /proc/bus/usb /proc/bus/usb
fi
Note: For Fedora 8, it is useless to add a mount command for usbfs in /etc/fstab, and it is not necessary to blacklist garmin_gps in /etc/modprobe.conf either. - For Ubuntu Linux, the approach is slightly different; see this thread.
(End of "historical" insert)
With that, the USB devices should be available to Windows XP, and upon connecting the Garmin GPSr the Hardware Wizard should guide you through the process of installing the Garmin USB drivers. If you run into problems in this process, please verify the following settings:
The image below shows the Fedora 8 Desktop, running Microsoft Windows XP in a window, and this in turn is running Garmin Mapsource in a window ;-) Note that the "Find Device" dialog is active; my GPSmap 60CS was detected on the USB port.
There was still one additional problem: Albeit Windows XP recognises the connection of the GPSr, MapSource would not find the device. The solution is to reset (disable and re-enable) the proprietary Garmin USB drivers inside Microsoft Windows. Probably the most elegant solution was posted in the VirtualBox forums; in short:
If you export track information from Garmin GDB files as text files, the resulting files are tab-delimited, with the coordinates written in lat/long pairs. The following one-liner extracts coordinates and altitude of a track, leaving a file that can be plotted directly e.g. with gnuplot:
cat /path/to/logfile.txt | grep "^Trackpoint" \
| awk -F '\t' '{print $2, $4}'
| tr NSWE +--+ > /path/to/out.dat
To get the axis right, you need to swap the first and second column in gnuplot:
set size ratio 1 splot 'file' using 2:1:3 w lin title '' unset xtics unset ytics
Sometimes I like to generate an altitude profile from a GPS track in gpx format. gpsdings is a java command line tool for the manipulation and analysis of track and waypoint data. Among others, it comprises a GPS track analyzer.
To generate a plot of elevation over distance from the file 20080622.gpx:
java -jar gpsdings.jar trackanalyzer --plot "DistanceTravelled|Elevation|20080622.altitude.svg|Jura, 20080622" 20080622.gpx
To generate a kml file for use with Google Earth from the file 20080622.gpx:
java -jar gpsdings.jar trackanalyzer --kml "Elevation|20080622.kml|Jura, 20080622" 20080622.gpx
The gpx files that are exported by Garmin's MapSource are not exactly like I want them to be. Using GPSBabel, the following one-liner extracts and merges all the tracks (-x track,merge), adjusts time so that the data points show the "real" time (-x move=+2h), drops any routes (-x nuketypes,routes), plus invokes some more clean-up:
gpsbabel -t -i gpx -f /path/to/infile.gpx \
-x track,merge,title="Title of Track",move=+2h -x nuketypes,routes \
-o gpx -c latin1 -F path/to/outfile.gpx
I have put this into a shell script:
click here to download the gpxclean.sh script.
Sometimes I need to reduce the number of points in a gpx file, but preserve the overall shape of the track. I found this useful e.g. to create overview maps from large gpx files. The following one-liner will reduce all points within a radius of 1 km. Applied to a file with more than 40'000 trackpoints (4.5 MB), the resulting track was reduced to about 400 points (45 kB) but still represented the original track shape very well:
gpsbabel -r -i gpx -f in.gpx -x simplify,error=1k -o gpx -F out.gpx
If, in addition, you want to pack all tracks into one, use something like this:
gpsbabel -r -i gpx -f in.gpx -x simplify,error=1k -x track,pack -o gpx -F out.gpx
A memory-saving technique to carry your favourite tracks with you is to convert them into a transparent overlay map. This can be achieved by manual import of the tracks into an empty map, then compiling manually ... but since the process as such does not really require manual interaction, I wrote a Perl script for this purpose.
The script is called gpx2ovl.pl ("gpx to overlay") and takes exactly one gpx file as argument. By default, it will extract all tracks and convert each of them into a polyline of type "0x0003". The display of these lines is customised using a TYP file (which is generated on-the-fly). The result is a complete set of files that can be used directly with MapSource.
Click here to download the gpx2ovl.pl script.
Please note that a number of variables (such as map names, etc) are hardcoded at the beginning of the script;
you may want to change them to suit your needs.
Similar to the above, I wrote a script that converts arbitrary "points of interest" into a transparent overlay map. Again, this is a Perl script that does not require manual interaction. The script is somewhat more sophisticated than the previous one, since it will automatically cut large areas into suitable tiles.
The script is called csv2ms.pl ("csv to MapSource") and takes exactly one csv file as argument. It will parse all coordinate pairs in the file and convert each of them into a [RGN10]-symbol of type "0x1610", which will show up as a red dot on most Garmin GPSr. The result is a complete set of files that can be used directly with MapSource.
Click here to download the csv2ms.pl script.
Please note that a number of variables (such as map names, etc) are hardcoded at the beginning of the script;
you may want to change them to suit your needs. - The script was updated 2008-11-30; the maps now work
also with the "infamous" MapSource version 6.14.x.
For most GPS data conversions, I use GPSBabel. However, here are a few cases that can be done easily on the command line.
The following one-liner converts GPX waypoints into plain text:
cat file.gpx | grep "<wpt" | sed 's/[^0-9.]/ /g'| awk '{print $2,$1}'
To convert a comma-delimited list of waypoints to GPX format, I wrote a script called csv2pgx.pl. Please note that this is extremely basic; in particular the resulting GPX file is not complete: it merely consists of waypoints in GPX format, but without the formal XML header. I use this script mosty to convert geographic locations that I then include into (other) GPX files.
Most of this is specific to the maps used by Garmin GPS receivers.