GPX-Dateien verbinden mit der PowerShell

Der Dotnet-Doktor Holger Schwichtenberg  –  0 Kommentare

Dieses PowerShell-Skript verbindet eine beliebige Anzahl von GPX-Dateien zu einer Datei anhand von Datum und Uhrzeit.

Sportler (egal, ob Hobby oder Profi) haben immer wieder mal das Problem, dass die Datenaufzeichnung ihrer Trainingseinheiten aufgrund technischer Probleme mit dem Aufzeichnungsgerät (z.B. Absturz des Smartphones oder Garmin-Geräts) in mehreren einzelnen GPX-Dateien vorliegen. Als ich nach dem Training gestern morgen drei Dateien hatte (Bugs im Garmin-Gerät sei Dank :-( ), habe ich mir ein PowerShell-Skript geschrieben, das eine beliebige Anzahl von GPX-Dateien chronologisch zu einer Datei verbindet.

# Combine several GPX-Files in current directory
# Dr. Holger Schwichtenberg, www.IT-Visions.de 21.08.2020

$ErrorActionPreference = "stop"

$path = $PSScriptRoot # Specify the directory differently here if necessary

$resultGPX = $null
$fileListOrderedByTime = New-Object 'System.Collections.Generic.SortedDictionary[datetime,string]'

"--- Step 1: Sort .gpx-Files by time of first point"
foreach($f in (dir $path -Filter "*.gpx"))
{
if ($f.name -ne "result.gpx")
{
$gpx = [xml] (Get-Content ($f.FullName))
$trkpt = $gpx.gpx.trk.trkseg.trkpt
$start = ($gpx.gpx.trk.trkseg.trkpt[0].time -as [DateTime])
$f.Name + " Points: " + $trkpt.Length + " Start: " + $start
$fileListOrderedByTime.Add($start,$f.FullName)
}
}

"--- Step 2: Combine GPX"
foreach($time in $fileListOrderedByTime.Keys)
{
$gpx = [xml] (Get-Content ($fileListOrderedByTime[$time]))
$trkpt = $gpx.gpx.trk.trkseg.trkpt

if ($resultGPX -eq $null) {
# Create a new GPX document from the first file
$resultGPX = New-Object System.Xml.XmlDocument
$resultGPX.LoadXml($gpx.OuterXml);
$time.ToLongTimeString() + " adding " + $gpx.gpx.trk.trkseg.trkpt.Length + " points"
}
else {
# Add all points from annother GPX document
$time.ToLongTimeString() + " adding " + $gpx.gpx.trk.trkseg.trkpt.Length + " points"
foreach($n in $gpx.gpx.trk.trkseg.trkpt)
{ # "The node to be inserted is from a different document context"
$importNode = $resultGPX.ImportNode($n, $true)
$resultGPX.gpx.trk.trkseg.AppendChild($importNode) | out-null
}
}
}

$trkpt = $resultGPX.gpx.trk.trkseg.trkpt
"Resulting number of <trkpt> elements: " + $trkpt.Length

# Save
$trkpt = $resultGPX.gpx.trk.trkseg.trkpt
$result = "$path\result.gpx"
$resultGPX.Save($result)
write-host "Done: Saved $($trkpt.Length) points in $result" -ForegroundColor:Green

Für meine drei Dateien, die ich nicht in der richtigen Reihenfolge gespeichert hatte, bekam ich folgende Kontrollausgabe:

--- Step 1: Sort .gpx-Files by time of first point
EinTeil.gpx Points: 9036 Start: 08/21/2020 10:17:22
NochEinTeil.gpx Points: 2511 Start: 08/21/2020 09:13:06
UndNochEiner.gpx Points: 237 Start: 08/21/2020 10:11:30
--- Step 2: Combine GPX
09:13:06 adding 2511 points
10:11:30 adding 237 points
10:17:22 adding 9036 points
Done: Saved 11784 points in Z:\_Prog\GPX\Combine\result.gpx