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