Uploading Large Files to the Garmin inReach Explorer+
I was joining my friends for a section of their Catamount Trail thru-ski down Vermont from Canada to Massachussetts. They brought a Garmin inReach Explorer+ and wanted a map of the trail on device for redundancy. The Garmin website explains how to do this:
- Upload GPX (or KML or KMZ) file to your account on the Garmin Explore website
- Install inReach Sync desktop app and login with your Garmin account
- Connect inReach to computer via USB and use inReach Sync to sync the uploaded file from account to device
I downloaded the GPX files from the Catamount Trail website and found I could upload to Garmin as "tracks" or "routes". When I tried uploading as route, I found the upload to be much more coarse than the original GPX file (far fewer waypoints). But uploading as a "track" wasn't even usable for navigating. The Garmin website said about routes: "Any line will be reduced to 200 data points." I couldn't find anything else from Garmin about specific file constraints so I started experimenting to get the map on the device in full resolution.
GPX Background
GPX is just an XML schema. It can represent things like a "route", which is a series of points to be followed, and a "track", which is a series of points (optionally timestamped) representing a journey taken:
<?xml version="1.0" encoding="UTF-8"?> <gpx version="1.0" creator="GPSBabel - https://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/0"> <time>2022-01-13T18:37:13.323Z</time> <bounds minlat="42.739060000" minlon="-72.945140000" maxlat="42.801320000" maxlon="-72.910070000"/> <trk> <trkseg> <trkpt lat="42.739060000" lon="-72.925210000"/> <trkpt lat="42.740510000" lon="-72.923980000"/> <trkpt lat="42.740640000" lon="-72.923910000"/> <trkpt lat="42.740640000" lon="-72.923910000"/> <trkpt lat="42.740920000" lon="-72.923760000"/> </trkseg> </trk> </gpx>
The GPX file from the trail association had a single track, with a single track segment, with about 17,000 points over ~300 miles (one waypoint every ~100 feet). Even though the file contained a track, it could still be uploaded as a route to Garmin.
Splitting the GPX file
I looked for a tool to split a GPX file into smaller parts. I found lots of software that I couldn't get to work:
- gpxtracksplitter (windows)
- gpxsplitter (web app)
- Lots of repos on github
But then a post on the GIS stackexchange explained how to do it with gpsbabel:
#!/bin/bash # $1 shall be the gpx file to split pfx="${1%.*}-" gpsbabel -i gpx -f "$1" -t -o csv -F - \ | gsplit -d -l 200 --additional-suffix=.csv - "$pfx" for f in "$pfx"*.csv; do fout=${f%.*}.gpx gpsbabel -i csv -f "$f" -x transform,trk=wpt -x nuketypes,waypoints \ -o gpx -F "$fout" rm "$f" done
It converts the GPX to a CSV, chunks the CSV into smaller CSVs, then converts each CSV back to GPX.
So now instead of one GPX with 17,000 points in a single track segment, I had 86 GPXs, each with a single track of 200 points. They could be losslessly uploaded to Garmin as routes, but I would have to upload them by hand.
Concatenating the smaller files
I've been doing a lot of functional programming lately, so I used a "fold" to accumulate the output GPXs into a single file (yikes):
#!/bin/bash # $1 is input # $2 is output # $3 is (optionally) max number of points per file prefix="${1%.*}-" gpsbabel -i gpx -f "$1" -t -o csv -F - \ | gsplit -d -l ${3:-200} --additional-suffix=.csv - "$prefix" echo -e "<?xml version=\"1.0\" ?>\n<gpx>\n</gpx>" > "$2" for f in "$prefix"*.csv; do gpsbabel -i csv -f "$f" \ -i gpx -f "$2" \ -x transform,trk=wpt -x nuketypes,waypoints \ -o gpx -F "$2" rm "$f" done
There is definitely a better way but this one worked. A single GPX with 86 tracks, each with a single segment of 200 points. It may be that 1 track of 86 segments would work too.