How to split a GPX track file into several files of N trackpoints each?
Surprisingly it seems gpsbabel indeed can't do it. But at least it can help by first converting to csv. Then I split the result with Unix' split
and convert back to gpx with gpsbabel. A similar strategy might work with PowerShell, but I don't know if it has a split
equivalent. Here is the bash function I used:
splitTrack() {
# $1 shall be the gpx file to split
pfx="${1%.*}-"
gpsbabel -i gpx -f "$1" -t -o csv -F - \
| split -d -l 500 --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
}
EDIT: Added hint from comments about getting track points out instead of way points.
Thanks for the script! It's useful to me as well because my Garmin bike navigator starts to throw trackpoints away after a certain number of trackpoints is reached.
I added a separation of waypoints and tracks and a little bit of "compression" to Harald's script (which works in zsh as well).
splitTrack() {
# $1 shall be the gpx file to split
pfx="${1%.*}-"
# Split tracks off and simplify track (reduce number of trackpoints but keep
# sufficient accuracy for bike navigation)
gpsbabel -i gpx -f "$1" -x nuketypes,waypoints,routes \
-x simplify,crosstrack,error=0.003k -o gpx -F "${pfx}tracks.gpx"
# Split waypoints off (import as extra POI gpx to device)
gpsbabel -i gpx -f "$1" -x nuketypes,tracks,routes -o gpx \
-F "${pfx}waypoints.gpx"
# 500 pack from tracks in CSV, start suffix with 01 instead of 00
gpsbabel -i gpx -f "${pfx}tracks.gpx" -t -o csv -F - \
| split -d --numeric=1 -l 500 --additional-suffix=.csv - "$pfx"
rm "${pfx}tracks.gpx"
# CSV back to gpx
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
}
If you want to keep elevation data as well, you may want to use the UNICSV format. Please adjust the re-import command to the field set exported from the GPX to (Uni)CSV. For more information see https://www.gpsbabel.org/htmldoc-development/fmt_unicsv.html. The following snippet requires the usual GNU toolset (sed/tail/split) installed.
splitTrack() {
# ===
# abort if no file is passed as argument 1
if ! [[ -f "$1" ]]
then
echo File missing!
return
fi
# ===
# ===
# Set prefix for files according to source file name
pfx="${1%.*}-"
# ===
# ===
# save waypoints in another file
gpsbabel \
-i gpx \
-f "$1" \
-x nuketypes,tracks,routes \
-o gpx \
-F "${pfx}waypoints.gpx"
# ===
# ===
# filter only track
# simplify track
# transform simplified track into waypoints
# print waypoints in UNICSV format
# pipe
# ignore UNICSV header
# pipe
# take 500 lines and duplicate each 500th line (overlap 1 line)
# in order to avoid gap in transition from one to next track part
# credit goes to https://stackoverflow.com/questions/21756040/extract-a-range-of-rows-with-overlap-using-sed/21757062#21757062
# pipe
# split/save each block of 500 lines into separated UNICSV files with prefix according to source file
gpsbabel \
-i gpx \
-f "$1" \
-x nuketypes,waypoints,routes \
-x simplify,crosstrack,error=0.003k \
-x transform,wpt=trk \
-o unicsv \
-F - \
| tail \
-n +2 \
| sed \
-nr ':a;$!{N;s/[^\n]+/&/500;Ta};p;$q;s/.*((\n[^\n]*){1})$/\1/;D' \
| split \
-d \
-a 3 \
--numeric=1 \
-l 500 \
--additional-suffix=.csv \
- \
"$pfx"
# ===
# ===
# convert separated UNICSV files back to GPX track files
# by transforming UNICSV waypoints back to trackpoints
# also filter out superfluous name tag
for f in "$pfx"*.csv; do
gpsbabel \
-i unicsv,fields=no+lat+lon+name+ele \
-f "$f" \
-x transform,trk=wpt \
-x nuketypes,waypoints \
-o gpx \
-F - \
| grep \
-v '<name>.*</name>\|<cmt>.*</cmt>\|<desc>.*</desc>' \
> "${f%.*}.gpx"
rm "$f"
done
# ===
return
}
This should work for example with the GPX tracks generated by https://brouter.de/brouter-web