Scripts/GPS Waypoint Utils

From J Wiki
Jump to navigation Jump to search

This script defines a set of verbs that process GPS waypoints from a variety of sources. The utilities are oriented toward Garmin Etrex and Nuvi GPS units but can be easily adapted.

The main words are:

etrexwaypointgpx v formats Etrex waypoints in gpx files for Garmin POI loader
relabelwaypoints v relabel Google Earth/KmlToGPX end to end waypoints
gpxfrpoicsv v converts POI csv files to gpx files

Download the script: File:Waypoints.ijs


I have been collecting GPS waypoints with my trusty old Garmin Etrex since early 2001. This verb scans a directory containing Garmin GPX files and generates a single GPX file that can be loaded with the Garmin POI loader into current car navigation units like the Nuvi 200. [{{#file: "waypoints.ijs"}} Download script: waypoints.ijs ]

etrexwaypointgpx=:3 : 0

NB.*etrexwaypointgpx v-- formats etrex waypoints in gpx for nuvi.
NB. This  verbs scans a directory for gpx files and then extracts
NB. all waypoints with less than six  characters and  generates a
NB. point  of interest  (poi) gpx  file that  can be loaded  with
NB. Garmin POI loader to Garmin Nuvi GPS devices.
NB. monad:  etrexwaypointgpx clDirectory
NB.   NB. process gpx files
NB.   gpx=. etrexwaypointgpx 'c:\pd\coords\gpx'
NB.   NB. write POI gpx
NB.   gpx write 'c:\pd\coords\poi\etrex waypoints.gpx'

NB. read and clean gpx files !(*)=. dir
NB. NIMP add (dir) to utils
gpx=. read&.> 1 dir (tslash y),'*.gpx'
gpx=. gpx -.&.> <CR,LF,TAB

NB. cut out waypoints
gpx=. ; 'wpt'&geteleattr&.> gpx

NB. remove names with more than six chars
NB. these are not Garmin Etrex waypoints
names=. 'name' geteletext ;gpx
mask=. 6 >: #&> names

NB. remove any duplicate names
mask=. mask *. ~: names
gpx=. mask # gpx

NB. sort by alphabetic name order
gpx=. (/: mask#names){gpx

NB. collect latitude longitude headers
wpthead=.('>'&beforestr&.> gpx) ,&.> '>'

NB. keep only time, name and symbols
gpx=. (<"0 wpthead) ,&.> ('time'&getele , 'name'&getele , 'sym'&getele)&.> gpx
gpx=. ;; gpx ,&.> <<'</wpt>'

NB. convert all symbols to "waypoint"
'idx gpx'=. 'sym' geteletextidx gpx
gpx=. ;(<'waypoint') idx} gpx

NB. return gpx


Google Earth is one of the great software toys. One of the features I really like is the ability to save road and trail routes as KML files. KML is very useful but it cannot be directly loaded into many GPS devices. To load Google Earth data into GPS units you have to convert the KML to GPX.

To convert KML to GPX do:

1. Process Google Earth KML with the Java program KMLtoGPX to generate a GPX file.

2. Use relabelwaypoints to convert the KMLtoGPX output into a GPX file that be loaded with G7toWIN.exe into Garmin Etrex units. [{{#file: "waypoints.ijs"}} Download script: waypoints.ijs ]

relabelwaypoints=:3 : 0

NB.*relabelwaypoints v-- relabel  GoogleEarth/KmlToGPX end to end
NB. waypoints.
NB. This  verb  extracts long numbered  suffix label route  names
NB. from GPX documents and  generates sequential short, less than
NB. six  characters, names  that can  be loaded into Garmin Etrex
NB. GPS  units. The GPX this verb processes is generated with the
NB. following procedure:
NB. verbatim:
NB.   1) Get start to finish directions in GoogleEarth.
NB.   2) Save the directions to a KML file.
NB.   3) Process the KML with KmltoGPX using end to end route
NB.      optimization.
NB.   4) Save the result as GPX.
NB.   5) Process the GPX of step (4) with this verb.
NB.   6) Load the GPX output of this verb to the Garmin GPS unit
NB.      using G7toWin.exe
NB.   7) You can define a route within G7toWin.exe that follows
NB.      your directed path from start to finish.
NB. monad:  clGPX =. relabelwaypoints clGPXml
NB.   gpx=. read 'c:\pd\coords\test.gpx'
NB.   'newgpx table'=. relabelwaypoints gpx
NB.   newgpx write 'c:\pd\coords\text2.gpx'
NB. dyad:  clGPX =. clPrefix relabelwaypoints clGPXml
NB.   'WA' relabelwaypoints gpx  NB. use prefix

'X' relabelwaypoints y

'more than three char prefixes' assert 3 >: # , x

NB. GPX is an XML document - the labels are in 'name' elements
nametags=. tags 'name'
taglens=. 1 _1 * #&> nametags

NB. split GPX into 'name' and other
sgx=. nametags splitstrs y

NB. index the name elements
nidx=. I. 0 {&> (0{nametags) E.&.> sgx

NB. exclude name elements that begin with 'Route_'
names=. (<taglens) cliptags&.> nidx{sgx
nmsk=. -. 0 {&> 'Route_'&E.&.> names
nidx=. nmsk # nidx

'more than 500 waypoints' assert 500 >: #nidx

NB. cut name text into a table of suffixes and remaining text
names=. nmsk # names
names=. ( '_'&afterlaststr ; '_'&beforelaststr)&> names

points=. _1&".&> 0 {"1 names
'suffixes should be positive integer representations' assert -. _1 e. ,points

'sorted points should form an integer sequence' assert (i. #points) -: /:~ points

NB. increment points to match GoogleMaps items
points=. >:points

NB. relabel using (x) prefix
labels=. <"1 x ,"1  ' 0' charsub rjust ": ,. points
newnames=. (0{nametags) ,&.> labels ,&.> 1 { nametags
gpx=. ;newnames nidx} sgx

NB. format sorted index table with full names
names=. 63&textform2&.> 1 {"1 names
table=. (/: labels) { labels ,. names

NB. return the gpx with full name table
gpx ;< ctl ": table


There are many POI (Point of Interest) GPS files available. One of the better sources is the POI Factory. POI Factory files are in comma delimited (CSV) format. CSV files can be directly loaded with the Garmin POI loader into current automobile GPS units but CSV files cannot be loaded into older Etrex GPS devices or dragged and dropped onto Google Earth. The following verb converts POI CSV files to GPX. [{{#file: "waypoints.ijs"}} Download script: waypoints.ijs ]

gpxfrpoicsv=:3 : 0

NB.*gpxfrpoicsv v-- converts poi csv files to gpx.
NB. This  verb converts  comma delimited point of interest  (POI)
NB. *.csv files to Garmin compatible gpx files. Example POI files
NB. can be downloaded from:
NB. monad:  clGpx =. gpxfrpoicsv clCsvfile
NB.   gpx=. gpxfrpoicsv 'c:\pd\coords\poicsv\ca-park_m.csv'

NB. read csv file
csv=. parsecsv read y

NB. sanity test latitude and longitude
lbcheck=. -. _9999 e. , _9999 ".&> 0 1 {"1 csv
'invalid longitude latitude number representations' assert lbcheck

NB. clean names
names=. 2 {"1 csv
names=. alltrim&.> names -.&.> names -.&.> <GPXNAMECHARS
'names cannot be null' assert -. 0 e. #&> names

NB. format latitude and longitude
csv=. (dblquote 0 1 {"1 csv) (1 0)}"1 csv
wpt=.  (<LF,'<wpt lat=') ,. (0{"1 csv) ,. (<' lon=') ,. (1{"1 csv) ,.  <'>'

NB. times set to now
wpt=.  wpt ,. <'time' eletags gpxtimestamp 6!:0''

NB. waypoint names & descriptions
wpt=. wpt ,. _1 |."1 names ,"0 1 |. tags 'name'
NB. wpt=. wpt ,. _1 |."1 (alltrim&.> 3 {"1 csv) ,"0 1 |. tags 'desc'

NB. symbols
wpt=. wpt ,. <'sym' eletags 'waypoint'
wpt=.  wpt ,. <'</wpt>'

NB. large gpx files choke various programs used
NB. to further process this file and load gps units
NB. wpt=. (1000<.#wpt) {. wpt

NB. return gpx

Contributed December 22, 2007 by John Baker