If you're doing a multi-day walk, it is nice to see the whole thing on one GPS trace. Sadly Strava provides no facilities for doing this. But if you want to, here is one way. There are various online utilities that do similar but I found none of them compelling.Firstly, it is convenient to export your track as a GPX (XML) file. When you edit that, you'll discover that each file is <header><trkpt>info</trkpt>(repeats)<trailer>. So one way to merge them is by hand: strip off all the headers, concatenate the files, then prepend a header, and postpend a trailer. This gets a bit tedious, especially with Windoze type utilities. So I wrote a Perl script to do it. This, in addition to doing the above, also:
* reduces the trace to one trackpoint per minute. I had my watch set to every-second recording, and the files from that are vast, and at walking pace once a minute is all you need.
* strips out the <extension> tags, because you don't need to see your heartrate or cadence at this scale.
* removes some linefeeds, for convenience.
One thing my Perl doesn't do, because I couldn't be bothered, is the last fiddly bit: Strava's algorithm to detect duplicate traces is very primitive: it flags anything that starts within a minute of any of your existing trace starts (I forget where I learnt this; not by guessing it myself I assure you). So, you need to delete a trackpoint or two from the start of the trace.
Here, for your <cough>edification</cough> is my Perl.
my $header = '<?xml version="1.0" encoding="UTF-8"?> <gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd" creator="StravaGPX" version="1.1" xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"> <trk> <name>William</name> <type>hiking</type> <trkseg>';
my $trailer = '</trkseg> </trk> </gpx>';
undef $/; # Ah, don't you just love Perl?
$contents = "";
while (my $file = shift) {
print "Processing $file\n";
open(my $fh, "<", "$file") or die "oh dear";
$content = <$fh>;
$content =~ s/^.*<trkseg>//ms; # Throw away "header"
$content =~ s/<\/trkseg>.*//ms; # And "trailer"
$content =~ s/<extensions>.*?<\/extensions>\n//msg; # And extensions
$content =~ s/\n\s+<ele/<ele/g; # And some line feeds
$content =~ s/\n\s+<time/<time/g; # And some more
$content =~ s/\n\s+<\/trkpt/<\/trkpt/g; # And a few more
$old_min = 0;
for (split "\n", $content) { # Reduce to one per minute
# 2025-08-27T07:03:36Z
/<time>(.*)<\/time>/;
my $time = $1;
$time =~ /(\d{2}):\d{2}Z/;
my $min = $1;
if ($min != $old_min) {
$contents .= "$_\n";
$old_min = $min;
}
}
}
open(my $out, ">", "out.gpx") or die "oh dearie me";
print $out "$header $contents $trailer";
Charming I'm sure you agree. Non-native speakers are invited to guess what "undef $/" does.
No comments:
Post a Comment