Converting GPX data to useful hard copy

I like to use OpenCPN for route planning, but I want to be able to keep a paper printout of critical routes like entering the Golden Gate - for when all the electronics are dead. For key waypoints I put in the description field, the bearings to nearby objects or other useful clues.

Navigation tools like OpenCPN and iNavX can export routes in GPX (GPS Exchange) format, but this provides little more than the Latitude and Longitude of each waypoint, so even if you convert the XML to text, it is of little value.

But with a little math we can fill in the blanks.

To compute the distance and bearing from one Lat/Long to another requires a bit more than basic trigonometry, but the necessary formula are easily found on the web.

GPX format in a nutshell

The GPX data exported by tools like OpenCPN provides a set of routes (rte) containing a list of waypoints (rtept)

Each waypoint has a latitude and longitude in decimal degree format as well as a name, and description.

We want to output each route (they also have names), with each waypoint on a separate line with bearing and distance to next waypoint.

This tool does what we want - it parses the GPX data and allows us to output a configurable set of fields per waypoint.

You can specify the fields via command line option or a configuration file.

You can even specify undefined fields (eg Compass) which will result in a blank field being output - to be filled in by hand. If you provide a deviation table then Compass headings will be computed.

Similarly if you know the error of your log you can provide that, and then the cDistance and cLog fields will be auto-populated, otherwise they will be blank columns.


name of the waypoint


latitude and longitude (in decimal minutes format)


True bearing to next waypoint


Variation is computed for each waypoint using the latest WMM data and Christopher Weiss's geomag routine.


Magnetic bearing to next waypoint.


If a deviation table is provided, we can lookup and report. The data can be supplied as a comma separated list of 12 (30 degree intervals) or 24 (15 degree intervals) values with negative values representing West error.

The data can also be provided in a file with one entry per line.


If a deviation table is provided we can compute compass course, otherwise this field will be blank.


Distance in nautical miles to next waypoint


Corrected distance - that is what our log will show (see cLog below)


Estimate of time to next waypoint at nominal cruising speed


Estimated time enroute. This is the cumulative time since the start of this route.


Cumulative distance since the start of this route.


Corrected log. It is rare for the ships log to be perfectly accurate. We multiply log by the log_error factor.


Nominal cruising speed (6.0 kts)


In OpenCPN at least, there is a description field in which I can record useful things like bearings to nearby objects etc.

This is where the real value in printing this stuff out comes from. Since you can have a printout of critical entry/exit plans for use when all the electronics are dead.


In the descriptions below the arg to each option is the variable name you might set in a config file. Eg.:

fields = cLog,Waypoint,Postion,Course,Magnetic,Compass,Distance,cDistance,Remarks
log_error = 0.9
sep = |
fmt = csv will automatically read config from ${progdir}/GPX.rc as well as ${HOME}/.GPXrc and .GPXrc if they exist.


-c config

config can set all the same variables as these options.

-D deviation

deviation is a comma separated list of 12 or 24 values or a file containing 12 or 24 values; one per line. Negative is West error. The first entry represents 000/360 degrees.

-F fields

The list of fields to output for each leg of a route.

-f fmt

Format of output, csv is useful if wanting to populate a spreadsheet.

-l log_error

The error factor to correct the log.

-o ofile

If ofile ends in - or / we will save each route to a separate file with route name appended to ofile.

If ofile contains {} the route name will be inserted at that point.

-p min_precision

How many decimals we show for minutes of lat/long. Default is 1 (approximately 200m resolution)

-s speed

Nominal cruising speed used to compute Time and ETE

-t sep

Separator between fields. For csv the default is , otherwise it is a space.


Below is the command I use to produce a custom CSV format file for importing into Google Sheets (using | as column separator): -D boat.deviation -f csv -t \| \
-F Waypoint,Position,Course,Magnetic,Compass,Distance,Log,Remarks \
-o /tmp/sheets/ routes.gpx

If no deviation data is available, skip -D and the Compass column will be empty.

The above will create a separate .csv file for each route from routes.gpx in /tmp/sheets/.

Used by to compute the course and distance from one position to the next. It also handles converting Latitude and Longitude from one format to another (I like decimal minutes).

Like this script will automatically load config from rc files named for it (${progdir}/latlong.rc etc).

For example, take the positions of St Francis Yaught Club and the Farallon Islands as given by - in decimal degrees:

# from St Francis Yaught Club  to Farallon Islands
(echo 37.8073169,-122.4489734; echo 37.7342623,-123.0932778 ) |
37 48.439 N, 122 26.938 W
course 262T distance 30.89 NMi
37 44.056 N, 123  5.597 W

or if you prefer seconds of arc:

(echo 37.8073169,-122.4489734; echo 37.7342623,-123.0932778 ) | -s
37 48 26.3 N, 122 26 56.3 W
course 262T distance 30.89 NMi
37 44 3.3 N, 123 5 35.8 W


You can fetch the latest archive from

ReadMe is the latest version of this document. /* imagine something very witty here */