From 4b791309760497470df043fc6f23f4d0dbfdeb21 Mon Sep 17 00:00:00 2001
From: Jo Vandeginste <Jo.Vandeginste@kuleuven.be>
Date: Sun, 12 Jan 2025 22:08:02 +0100
Subject: [PATCH] Add route segment tests

This is only the beginning...

Signed-off-by: Jo Vandeginste <Jo.Vandeginste@kuleuven.be>
---
 pkg/database/route_segment_matching.go |  41 +-
 pkg/database/route_segment_test.go     | 108 ++++
 pkg/database/segment1_test.go          |  77 +++
 pkg/database/segment2_test.go          |  75 +++
 pkg/database/track_test.go             | 654 +++++++++++++++++++++++++
 views/route_segments/add.templ         |   6 +-
 views/route_segments/add_templ.go      |   2 +-
 views/route_segments/list.templ        |   5 +
 views/route_segments/list_templ.go     |  37 +-
 9 files changed, 981 insertions(+), 24 deletions(-)
 create mode 100644 pkg/database/route_segment_test.go
 create mode 100644 pkg/database/segment1_test.go
 create mode 100644 pkg/database/segment2_test.go
 create mode 100644 pkg/database/track_test.go

diff --git a/pkg/database/route_segment_matching.go b/pkg/database/route_segment_matching.go
index b1997299..389b6634 100644
--- a/pkg/database/route_segment_matching.go
+++ b/pkg/database/route_segment_matching.go
@@ -7,26 +7,26 @@ import (
 
 // MaxDeltaMeter is the maximum distance in meters that a point can be away from
 // the route segment
-const MaxDeltaMeter = 20
+const MaxDeltaMeter = 20.0
 
 // MaxTotalDistancePercentage is the maximum percentage of the total distance of
 // the route segment that can be exceeded by the total distance matching part of
 // the route
-const MaxTotalDistancePercentage = 0.02
+const MaxTotalDistanceFraction = 0.9
 
 // RouteSegmentMatch is a match between a route segment and a workout
 type RouteSegmentMatch struct {
 	Workout      *Workout
 	RouteSegment *RouteSegment
 
-	first, last, end MapPoint // The first and last point of the route
+	first, last MapPoint // The first and last point of the route
+	end         MapPoint // The last point of the workout
 
 	RouteSegmentID  uint          `gorm:"primaryKey"` // The ID of the route segment
 	WorkoutID       uint          `gorm:"primaryKey"` // The ID of the workout
 	FirstID, LastID int           // The index of the first and last point of the route
 	Distance        float64       // The total distance of the route segment for this workout
 	Duration        time.Duration // The total duration of the route segment for this workout
-	Points          int           // The total number of points of the route segment for this workout
 }
 
 func (rsm *RouteSegmentMatch) AverageSpeed() float64 {
@@ -37,14 +37,10 @@ func (rsm *RouteSegmentMatch) AverageSpeed() float64 {
 // the first and last point of the route along the route segment
 func (rs *RouteSegment) NewRouteSegmentMatch(workout *Workout, p, last int) *RouteSegmentMatch {
 	rsm := &RouteSegmentMatch{
-		RouteSegmentID: rs.ID,
-		WorkoutID:      workout.ID,
-		FirstID:        p,
-		LastID:         last,
-
-		first: workout.Data.Details.Points[p],
-		last:  workout.Data.Details.Points[last],
-		end:   workout.Data.Details.Points[len(workout.Data.Details.Points)-1],
+		Workout:      workout,
+		RouteSegment: rs,
+		FirstID:      p,
+		LastID:       last,
 	}
 
 	rsm.calculate()
@@ -62,13 +58,19 @@ func (rsm *RouteSegmentMatch) IsBetterThan(current *RouteSegmentMatch) bool {
 // within MaxTotalDistancePercentage of the distance of the current route
 // segment
 func (rsm *RouteSegmentMatch) MatchesDistance(distance float64) bool {
-	return math.Abs(1-(rsm.Distance/distance)) < MaxTotalDistancePercentage
+	return math.Abs(rsm.Distance/distance) > MaxTotalDistanceFraction
 }
 
 // calculate will calculate the total distance and duration of the route
 // segment, and the total number of points of this workout along the route
 // segment
 func (rsm *RouteSegmentMatch) calculate() {
+	rsm.RouteSegmentID = rsm.RouteSegment.ID
+	rsm.WorkoutID = rsm.Workout.ID
+	rsm.first = rsm.Workout.Data.Details.Points[rsm.FirstID]
+	rsm.last = rsm.Workout.Data.Details.Points[rsm.LastID]
+	rsm.end = rsm.Workout.Data.Details.Points[len(rsm.Workout.Data.Details.Points)-1]
+
 	if rsm.FirstID <= rsm.LastID {
 		rsm.Distance = rsm.last.TotalDistance - rsm.first.TotalDistance
 		rsm.Duration = rsm.last.TotalDuration - rsm.first.TotalDuration
@@ -166,12 +168,16 @@ func (rs *RouteSegment) MatchSegment(workout *Workout, start int, forward bool)
 
 		if forward {
 			cur++
+
+			if cur == segmentLength {
+				return index, true
+			}
 		} else {
 			cur--
-		}
 
-		if cur%segmentLength == 0 {
-			return index, true
+			if cur == 0 {
+				return index, true
+			}
 		}
 
 		if !rs.Circular && index < start {
@@ -190,7 +196,8 @@ func (rs *RouteSegment) StartingPoints(points []MapPoint) []int {
 	start := rs.Points[0]
 
 	for i, p := range points {
-		if start.DistanceTo(&p) < MaxDeltaMeter {
+		d := start.DistanceTo(&p)
+		if d < MaxDeltaMeter {
 			r = append(r, i)
 		}
 	}
diff --git a/pkg/database/route_segment_test.go b/pkg/database/route_segment_test.go
new file mode 100644
index 00000000..c6c73b59
--- /dev/null
+++ b/pkg/database/route_segment_test.go
@@ -0,0 +1,108 @@
+package database
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestRouteSegment_Parse(t *testing.T) {
+	{
+		rs, err := NewRouteSegment("", "meer.gpx", []byte(meer))
+		assert.NoError(t, err)
+		assert.NotNil(t, rs)
+		assert.Greater(t, rs.TotalDistance, 1800.0)
+	}
+
+	{
+		rs, err := NewRouteSegment("", "finsepiste.gpx", []byte(finsepiste))
+		assert.NoError(t, err)
+		assert.NotNil(t, rs)
+		assert.Greater(t, rs.TotalDistance, 900.0)
+	}
+}
+
+func TestRouteSegment_FindMatches(t *testing.T) {
+	rs, err := NewRouteSegment("", "finsepiste.gpx", []byte(finsepiste))
+	assert.NoError(t, err)
+
+	w1, err := NewWorkout(AnonymousUser(), WorkoutTypeAutoDetect, "", "match.gpx", []byte(track))
+	assert.NoError(t, err)
+	assert.True(t, w1.Type.IsLocation())
+	assert.True(t, w1.HasTracks())
+
+	w2, err := NewWorkout(AnonymousUser(), WorkoutTypeAutoDetect, "", "nomatch.gpx", []byte(GpxSample1))
+	assert.NoError(t, err)
+	assert.True(t, w2.Type.IsLocation())
+	assert.True(t, w2.HasTracks())
+
+	workouts := []*Workout{w1, w2}
+	matches := rs.FindMatches(workouts)
+
+	assert.Len(t, matches, 1)
+	assert.Len(t, matches[0].Workout.Data.Details.Points, 158)
+}
+
+func TestRouteSegment_StartingPoints_NoMatch(t *testing.T) {
+	rs, err := NewRouteSegment("", "finsepiste.gpx", []byte(finsepiste))
+	assert.NoError(t, err)
+
+	w, err := NewWorkout(AnonymousUser(), WorkoutTypeAutoDetect, "", "nomatch.gpx", []byte(GpxSample1))
+	assert.NoError(t, err)
+
+	sp := rs.StartingPoints(w.Data.Details.Points)
+	assert.Empty(t, sp)
+}
+
+func TestRouteSegment_StartingPoints_Match(t *testing.T) {
+	rs, err := NewRouteSegment("", "finsepiste.gpx", []byte(finsepiste))
+	assert.NoError(t, err)
+
+	w, err := NewWorkout(AnonymousUser(), WorkoutTypeAutoDetect, "", "match.gpx", []byte(track))
+	assert.NoError(t, err)
+
+	sp := rs.StartingPoints(w.Data.Details.Points)
+	assert.NotEmpty(t, sp)
+	assert.Greater(t, len(sp), 0)
+
+	for _, p := range sp {
+		assert.Less(t, rs.Points[0].DistanceTo(&w.Data.Details.Points[p]), MaxDeltaMeter)
+	}
+}
+
+func TestRouteSegment_StartingPoints_MatchSegment(t *testing.T) {
+	rs, err := NewRouteSegment("", "finsepiste.gpx", []byte(finsepiste))
+	assert.NoError(t, err)
+
+	w, err := NewWorkout(AnonymousUser(), WorkoutTypeAutoDetect, "", "match.gpx", []byte(track))
+	assert.NoError(t, err)
+
+	sp := rs.StartingPoints(w.Data.Details.Points)
+	assert.NotEmpty(t, sp)
+	assert.Greater(t, len(sp), 0)
+
+	{
+		last, ok := rs.MatchSegment(w, 3, true)
+		assert.Zero(t, last)
+		assert.False(t, ok)
+	}
+
+	{
+		last, ok := rs.MatchSegment(w, 4, true)
+		assert.NotZero(t, last)
+		assert.True(t, ok)
+	}
+}
+
+func TestRouteSegment_Match(t *testing.T) {
+	rs, err := NewRouteSegment("", "finsepiste.gpx", []byte(finsepiste))
+	assert.NoError(t, err)
+
+	w, err := NewWorkout(AnonymousUser(), WorkoutTypeAutoDetect, "", "match.gpx", []byte(track))
+	assert.NoError(t, err)
+
+	rsm := rs.Match(w)
+	assert.NotNil(t, rsm)
+	assert.Greater(t, rsm.Distance, 900.0)
+	assert.True(t, rsm.MatchesDistance(rs.TotalDistance))
+}
diff --git a/pkg/database/segment1_test.go b/pkg/database/segment1_test.go
new file mode 100644
index 00000000..b77c362f
--- /dev/null
+++ b/pkg/database/segment1_test.go
@@ -0,0 +1,77 @@
+package database
+
+//nolint:lll
+const meer = `
+<?xml version="1.0" encoding="UTF-8"?>
+<gpx version="1.1" creator="RunnerMaps" xmlns="http://www.topografix.com/GPX/1/1" 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">
+<metadata>
+<link href="http://runnermaps.nl/route/197237">
+<text>Runnermaps route</text>
+</link>
+<time>2020-11-01T09:21:37Z</time>
+</metadata>
+<trk>
+<name>Rotselaar Het meer</name>
+<trkseg>
+<trkpt lat="50.96020" lon="4.72376"><ele>0</ele></trkpt>
+<trkpt lat="50.96014" lon="4.72463"><ele>0</ele></trkpt>
+<trkpt lat="50.95964" lon="4.72605"><ele>0</ele></trkpt>
+<trkpt lat="50.95882" lon="4.72761"><ele>0</ele></trkpt>
+<trkpt lat="50.95822" lon="4.72853"><ele>0</ele></trkpt>
+<trkpt lat="50.95818" lon="4.72864"><ele>0</ele></trkpt>
+<trkpt lat="50.95811" lon="4.72913"><ele>0</ele></trkpt>
+<trkpt lat="50.95811" lon="4.72913"><ele>0</ele></trkpt>
+<trkpt lat="50.95809" lon="4.72965"><ele>0</ele></trkpt>
+<trkpt lat="50.95811" lon="4.72990"><ele>0</ele></trkpt>
+<trkpt lat="50.95815" lon="4.73002"><ele>0</ele></trkpt>
+<trkpt lat="50.95861" lon="4.73054"><ele>0</ele></trkpt>
+<trkpt lat="50.95867" lon="4.73064"><ele>0</ele></trkpt>
+<trkpt lat="50.95871" lon="4.73099"><ele>0</ele></trkpt>
+<trkpt lat="50.95885" lon="4.73123"><ele>0</ele></trkpt>
+<trkpt lat="50.95995" lon="4.73151"><ele>0</ele></trkpt>
+<trkpt lat="50.96020" lon="4.73164"><ele>0</ele></trkpt>
+<trkpt lat="50.96020" lon="4.73164"><ele>0</ele></trkpt>
+<trkpt lat="50.96092" lon="4.73213"><ele>0</ele></trkpt>
+<trkpt lat="50.96103" lon="4.73207"><ele>0</ele></trkpt>
+<trkpt lat="50.96121" lon="4.73189"><ele>0</ele></trkpt>
+<trkpt lat="50.96139" lon="4.73177"><ele>0</ele></trkpt>
+<trkpt lat="50.96161" lon="4.73182"><ele>0</ele></trkpt>
+<trkpt lat="50.96170" lon="4.73176"><ele>0</ele></trkpt>
+<trkpt lat="50.96176" lon="4.73168"><ele>0</ele></trkpt>
+<trkpt lat="50.96181" lon="4.73118"><ele>0</ele></trkpt>
+<trkpt lat="50.96187" lon="4.73102"><ele>0</ele></trkpt>
+<trkpt lat="50.96206" lon="4.73073"><ele>0</ele></trkpt>
+<trkpt lat="50.96208" lon="4.73042"><ele>0</ele></trkpt>
+<trkpt lat="50.96191" lon="4.72954"><ele>0</ele></trkpt>
+<trkpt lat="50.96192" lon="4.72945"><ele>0</ele></trkpt>
+<trkpt lat="50.96198" lon="4.72950"><ele>0</ele></trkpt>
+<trkpt lat="50.96204" lon="4.72978"><ele>0</ele></trkpt>
+<trkpt lat="50.96204" lon="4.72978"><ele>0</ele></trkpt>
+<trkpt lat="50.96198" lon="4.72950"><ele>0</ele></trkpt>
+<trkpt lat="50.96192" lon="4.72945"><ele>0</ele></trkpt>
+<trkpt lat="50.96225" lon="4.72914"><ele>0</ele></trkpt>
+<trkpt lat="50.96218" lon="4.72881"><ele>0</ele></trkpt>
+<trkpt lat="50.96214" lon="4.72774"><ele>0</ele></trkpt>
+<trkpt lat="50.96217" lon="4.72764"><ele>0</ele></trkpt>
+<trkpt lat="50.96225" lon="4.72758"><ele>0</ele></trkpt>
+<trkpt lat="50.96225" lon="4.72752"><ele>0</ele></trkpt>
+<trkpt lat="50.96225" lon="4.72752"><ele>0</ele></trkpt>
+<trkpt lat="50.96226" lon="4.72723"><ele>0</ele></trkpt>
+<trkpt lat="50.96220" lon="4.72653"><ele>0</ele></trkpt>
+<trkpt lat="50.96203" lon="4.72537"><ele>0</ele></trkpt>
+<trkpt lat="50.96187" lon="4.72474"><ele>0</ele></trkpt>
+<trkpt lat="50.96182" lon="4.72379"><ele>0</ele></trkpt>
+<trkpt lat="50.96186" lon="4.72370"><ele>0</ele></trkpt>
+<trkpt lat="50.96186" lon="4.72370"><ele>0</ele></trkpt>
+<trkpt lat="50.96187" lon="4.72366"><ele>0</ele></trkpt>
+<trkpt lat="50.96153" lon="4.72362"><ele>0</ele></trkpt>
+<trkpt lat="50.96119" lon="4.72350"><ele>0</ele></trkpt>
+<trkpt lat="50.96098" lon="4.72347"><ele>0</ele></trkpt>
+<trkpt lat="50.96058" lon="4.72331"><ele>0</ele></trkpt>
+<trkpt lat="50.96049" lon="4.72333"><ele>0</ele></trkpt>
+<trkpt lat="50.96037" lon="4.72341"><ele>0</ele></trkpt>
+<trkpt lat="50.96021" lon="4.72371"><ele>0</ele></trkpt>
+</trkseg>
+</trk>
+</gpx>
+`
diff --git a/pkg/database/segment2_test.go b/pkg/database/segment2_test.go
new file mode 100644
index 00000000..90f98a37
--- /dev/null
+++ b/pkg/database/segment2_test.go
@@ -0,0 +1,75 @@
+package database
+
+//nolint:lll
+const finsepiste = `
+<?xml version="1.0" encoding="UTF-8"?>
+<gpx version="1.1" creator="RunnerMaps" schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns="http://www.topografix.com/GPX/1/1" 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 http://www.garmin.com/xmlschemas/PowerExtension/v1 http://www.garmin.com/xmlschemas/PowerExtensionv1.xsd http://www.topografix.com/GPX/gpx_style/0/2 http://www.topografix.com/GPX/gpx_style/0/2/gpx_style.xsd" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:gpxpx="http://www.garmin.com/xmlschemas/PowerExtension/v1" xmlns:gpx_style="http://www.topografix.com/GPX/gpx_style/0/2">
+  <metadata>
+    <name>route_86636_track</name>
+    <author>
+      <name>gpx.studio</name>
+      <link href="https://gpx.studio"/>
+    </author>
+    <link href="http://runnermaps.nl/route/86636">
+      <text>Runnermaps route</text>
+    </link>
+    <time>2016-10-24T12:59:28.000Z</time>
+  </metadata>
+  <trk>
+    <name>finsepiste</name>
+    <trkseg>
+      <trkpt lat="50.957865" lon="4.724102">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.95805" lon="4.72462">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.958" lon="4.72495">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.95704" lon="4.72542">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.95686" lon="4.7245">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.95659" lon="4.72441">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.95636" lon="4.7232">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.95554" lon="4.72355">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.95538" lon="4.7229">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.95677" lon="4.72225">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.956884" lon="4.722784">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.95747" lon="4.72242">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.9576" lon="4.72307">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.95801" lon="4.72294">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.95819" lon="4.72384">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.95787" lon="4.72395">
+        <ele>0</ele>
+      </trkpt>
+      <trkpt lat="50.95787" lon="4.7241">
+        <ele>0</ele>
+      </trkpt>
+    </trkseg>
+  </trk>
+</gpx>
+`
diff --git a/pkg/database/track_test.go b/pkg/database/track_test.go
new file mode 100644
index 00000000..0f721661
--- /dev/null
+++ b/pkg/database/track_test.go
@@ -0,0 +1,654 @@
+package database
+
+const track = `
+<?xml version="1.0" encoding="UTF-8"?>
+<gpx creator="FitoTrack" version="1.1" schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns="http://www.topografix.com/GPX/1/1" 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 http://www.garmin.com/xmlschemas/PowerExtension/v1 http://www.garmin.com/xmlschemas/PowerExtensionv1.xsd http://www.topografix.com/GPX/gpx_style/0/2 http://www.topografix.com/GPX/gpx_style/0/2/gpx_style.xsd" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:gpxpx="http://www.garmin.com/xmlschemas/PowerExtension/v1" xmlns:gpx_style="http://www.topografix.com/GPX/gpx_style/0/2">
+  <metadata>
+    <name>24 aug. 2024 15:17:28</name>
+    <author>
+      <name>gpx.studio</name>
+      <link href="https://gpx.studio"/>
+    </author>
+    <time>2024-08-24T13:17:28.000Z</time>
+  </metadata>
+  <trk>
+    <name>24 aug. 2024 15:17:28</name>
+    <src>FitoTrack</src>
+    <type>running</type>
+    <trkseg>
+      <trkpt lat="50.95815638" lon="4.72390736">
+        <ele>52.4583417160683</ele>
+        <time>2024-08-24T13:19:17.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95810515" lon="4.7238998">
+        <ele>52.438713463766405</ele>
+        <time>2024-08-24T13:19:19.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95804426" lon="4.72393291">
+        <ele>52.41191358060513</ele>
+        <time>2024-08-24T13:19:22.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95799495" lon="4.7239685">
+        <ele>52.43342956309676</ele>
+        <time>2024-08-24T13:19:25.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95795052" lon="4.72395358">
+        <ele>52.34359235257779</ele>
+        <time>2024-08-24T13:19:27.000Z</time>
+      </trkpt>
+      <trkpt lat="50.9579015" lon="4.72392695">
+        <ele>52.37737585651892</ele>
+        <time>2024-08-24T13:19:29.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95785294" lon="4.72396457">
+        <ele>52.44022462884034</ele>
+        <time>2024-08-24T13:19:32.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95785389" lon="4.72404801">
+        <ele>52.444188099299325</ele>
+        <time>2024-08-24T13:19:34.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95787105" lon="4.72411641">
+        <ele>52.40361007457137</ele>
+        <time>2024-08-24T13:19:36.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95791272" lon="4.72419661">
+        <ele>52.39681555378454</ele>
+        <time>2024-08-24T13:19:39.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95794013" lon="4.72428155">
+        <ele>52.388510957837276</ele>
+        <time>2024-08-24T13:19:42.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95794917" lon="4.72436415">
+        <ele>52.391719663194415</ele>
+        <time>2024-08-24T13:19:44.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95796929" lon="4.72447457">
+        <ele>52.43890310871618</ele>
+        <time>2024-08-24T13:19:47.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95799303" lon="4.72454747">
+        <ele>52.504582931365455</ele>
+        <time>2024-08-24T13:19:50.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95801274" lon="4.72462389">
+        <ele>52.48193507369944</ele>
+        <time>2024-08-24T13:19:53.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95798586" lon="4.72468795">
+        <ele>52.51798341790284</ele>
+        <time>2024-08-24T13:19:57.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95796504" lon="4.72475845">
+        <ele>52.52062536823767</ele>
+        <time>2024-08-24T13:19:59.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95793229" lon="4.72486792">
+        <ele>52.53327054471646</ele>
+        <time>2024-08-24T13:20:02.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95790401" lon="4.72493466">
+        <ele>52.63443195654681</ele>
+        <time>2024-08-24T13:20:05.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95785898" lon="4.72499881">
+        <ele>52.64084882230435</ele>
+        <time>2024-08-24T13:20:08.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95781113" lon="4.72502636">
+        <ele>52.63782867198348</ele>
+        <time>2024-08-24T13:20:10.000Z</time>
+      </trkpt>
+      <trkpt lat="50.9577609" lon="4.7250553">
+        <ele>52.627448335766964</ele>
+        <time>2024-08-24T13:20:13.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95771292" lon="4.72508668">
+        <ele>52.73710289858086</ele>
+        <time>2024-08-24T13:20:16.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95765958" lon="4.72510077">
+        <ele>52.74672846969553</ele>
+        <time>2024-08-24T13:20:19.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95759359" lon="4.72511179">
+        <ele>52.76522430186629</ele>
+        <time>2024-08-24T13:20:22.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95752763" lon="4.7251443">
+        <ele>52.81674887287634</ele>
+        <time>2024-08-24T13:20:26.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95748423" lon="4.72517556">
+        <ele>52.79900835076417</ele>
+        <time>2024-08-24T13:20:29.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95743625" lon="4.72520527">
+        <ele>52.74880475492154</ele>
+        <time>2024-08-24T13:20:32.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95738346" lon="4.72523549">
+        <ele>52.76314856159704</ele>
+        <time>2024-08-24T13:20:35.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95733647" lon="4.72525192">
+        <ele>52.770697847485714</ele>
+        <time>2024-08-24T13:20:38.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95728578" lon="4.7252937">
+        <ele>52.78938277964949</ele>
+        <time>2024-08-24T13:20:42.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95723598" lon="4.72532553">
+        <ele>52.80655763665284</ele>
+        <time>2024-08-24T13:20:45.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95718872" lon="4.72533055">
+        <ele>52.7907037548169</ele>
+        <time>2024-08-24T13:20:47.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95711906" lon="4.72531918">
+        <ele>52.84524793119107</ele>
+        <time>2024-08-24T13:20:50.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95706505" lon="4.72529096">
+        <ele>52.87544561970251</ele>
+        <time>2024-08-24T13:20:53.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95700348" lon="4.72527408">
+        <ele>52.90904002365061</ele>
+        <time>2024-08-24T13:20:56.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95695868" lon="4.72526159">
+        <ele>52.92111899006384</ele>
+        <time>2024-08-24T13:20:58.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95693816" lon="4.72519586">
+        <ele>52.955091049041236</ele>
+        <time>2024-08-24T13:21:01.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95692116" lon="4.72512292">
+        <ele>52.958865964463946</ele>
+        <time>2024-08-24T13:21:03.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95691437" lon="4.72504402">
+        <ele>52.91545688940814</ele>
+        <time>2024-08-24T13:21:05.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95692062" lon="4.72496014">
+        <ele>52.961507914798766</ele>
+        <time>2024-08-24T13:21:08.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95690458" lon="4.72488939">
+        <ele>53.01341014083811</ele>
+        <time>2024-08-24T13:21:11.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95688054" lon="4.72479731">
+        <ele>53.043418729356524</ele>
+        <time>2024-08-24T13:21:15.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95685712" lon="4.72473054">
+        <ele>53.09267791514754</ele>
+        <time>2024-08-24T13:21:18.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95686605" lon="4.72465232">
+        <ele>53.12683852916121</ele>
+        <time>2024-08-24T13:21:22.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95685788" lon="4.72455673">
+        <ele>53.12249740367293</ele>
+        <time>2024-08-24T13:21:26.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95685968" lon="4.72447888">
+        <ele>53.13363250499129</ele>
+        <time>2024-08-24T13:21:29.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95681928" lon="4.72442543">
+        <ele>53.067009362203905</ele>
+        <time>2024-08-24T13:21:34.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95676349" lon="4.72445062">
+        <ele>53.020203571711434</ele>
+        <time>2024-08-24T13:21:37.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95669707" lon="4.72448228">
+        <ele>53.05757289108225</ele>
+        <time>2024-08-24T13:21:40.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95663955" lon="4.72443546">
+        <ele>53.046814899836434</ele>
+        <time>2024-08-24T13:21:43.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95660373" lon="4.72435618">
+        <ele>53.01529623615759</ele>
+        <time>2024-08-24T13:21:46.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95658545" lon="4.72425601">
+        <ele>53.00869027040703</ele>
+        <time>2024-08-24T13:21:49.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95657133" lon="4.72417599">
+        <ele>53.02209021198767</ele>
+        <time>2024-08-24T13:21:53.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95654482" lon="4.72410576">
+        <ele>53.002272859692745</ele>
+        <time>2024-08-24T13:21:56.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95654405" lon="4.72402932">
+        <ele>52.94357665782332</ele>
+        <time>2024-08-24T13:22:00.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95654084" lon="4.72393375">
+        <ele>52.92734566591484</ele>
+        <time>2024-08-24T13:22:03.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95653266" lon="4.72386265">
+        <ele>52.899979572688</ele>
+        <time>2024-08-24T13:22:05.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95651571" lon="4.72378433">
+        <ele>52.84222723591345</ele>
+        <time>2024-08-24T13:22:07.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95648124" lon="4.72370855">
+        <ele>52.80617889171004</ele>
+        <time>2024-08-24T13:22:09.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95644379" lon="4.72365518">
+        <ele>52.800328236018075</ele>
+        <time>2024-08-24T13:22:11.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95642429" lon="4.72358637">
+        <ele>52.82486327891707</ele>
+        <time>2024-08-24T13:22:13.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95640509" lon="4.72352187">
+        <ele>52.82259843865479</ele>
+        <time>2024-08-24T13:22:15.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95638438" lon="4.72345555">
+        <ele>52.770319102542906</ele>
+        <time>2024-08-24T13:22:17.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95636571" lon="4.72338824">
+        <ele>52.71879507648962</ele>
+        <time>2024-08-24T13:22:19.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95634725" lon="4.72331335">
+        <ele>52.7104910254991</ele>
+        <time>2024-08-24T13:22:21.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95632318" lon="4.7232474">
+        <ele>52.691995193328346</ele>
+        <time>2024-08-24T13:22:24.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95629078" lon="4.72316629">
+        <ele>52.66576152023264</ele>
+        <time>2024-08-24T13:22:27.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95623982" lon="4.72315455">
+        <ele>52.635564376677955</ele>
+        <time>2024-08-24T13:22:30.000Z</time>
+      </trkpt>
+      <trkpt lat="50.9561953" lon="4.72317114">
+        <ele>52.657457469242125</ele>
+        <time>2024-08-24T13:22:32.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95613284" lon="4.72320458">
+        <ele>52.676141856449156</ele>
+        <time>2024-08-24T13:22:35.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95608549" lon="4.72321892">
+        <ele>52.676896621551</ele>
+        <time>2024-08-24T13:22:38.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95603702" lon="4.72326515">
+        <ele>52.716719336220365</ele>
+        <time>2024-08-24T13:22:41.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95599195" lon="4.72329659">
+        <ele>52.722004326803514</ele>
+        <time>2024-08-24T13:22:44.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95594848" lon="4.72332763">
+        <ele>52.738424418705016</ele>
+        <time>2024-08-24T13:22:48.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95590428" lon="4.72336014">
+        <ele>52.80976579705323</ele>
+        <time>2024-08-24T13:22:51.000Z</time>
+      </trkpt>
+      <trkpt lat="50.9558566" lon="4.72339452">
+        <ele>52.85090948689001</ele>
+        <time>2024-08-24T13:22:54.000Z</time>
+      </trkpt>
+      <trkpt lat="50.9558029" lon="4.72342647">
+        <ele>52.91583399948069</ele>
+        <time>2024-08-24T13:22:57.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95574957" lon="4.7234701">
+        <ele>52.92904538602505</ele>
+        <time>2024-08-24T13:23:00.000Z</time>
+      </trkpt>
+      <trkpt lat="50.9556956" lon="4.72351263">
+        <ele>52.989817328163724</ele>
+        <time>2024-08-24T13:23:03.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95563322" lon="4.72354783">
+        <ele>53.012465730786495</ele>
+        <time>2024-08-24T13:23:06.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95558205" lon="4.72358562">
+        <ele>53.07380388299073</ele>
+        <time>2024-08-24T13:23:09.000Z</time>
+      </trkpt>
+      <trkpt lat="50.9555389" lon="4.72360949">
+        <ele>53.15099591703091</ele>
+        <time>2024-08-24T13:23:12.000Z</time>
+      </trkpt>
+      <trkpt lat="50.9555116" lon="4.72354835">
+        <ele>53.176474825024776</ele>
+        <time>2024-08-24T13:23:15.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95549779" lon="4.72347973">
+        <ele>53.147410101601224</ele>
+        <time>2024-08-24T13:23:17.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95547456" lon="4.72337987">
+        <ele>53.13457637008616</ele>
+        <time>2024-08-24T13:23:20.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95545347" lon="4.72329784">
+        <ele>53.13608644524659</ele>
+        <time>2024-08-24T13:23:23.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95543103" lon="4.7232292">
+        <ele>53.129291924459764</ele>
+        <time>2024-08-24T13:23:26.000Z</time>
+      </trkpt>
+      <trkpt lat="50.955427" lon="4.72315702">
+        <ele>53.10211438626919</ele>
+        <time>2024-08-24T13:23:28.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95543662" lon="4.72304983">
+        <ele>53.073238217881915</ele>
+        <time>2024-08-24T13:23:30.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95544776" lon="4.72298072">
+        <ele>53.020015561631915</ele>
+        <time>2024-08-24T13:23:32.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95549057" lon="4.72291894">
+        <ele>52.99208271338275</ele>
+        <time>2024-08-24T13:23:36.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95553527" lon="4.72289237">
+        <ele>53.046060134734596</ele>
+        <time>2024-08-24T13:23:38.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95559356" lon="4.7228505">
+        <ele>53.03228253812466</ele>
+        <time>2024-08-24T13:23:41.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95564771" lon="4.7228246">
+        <ele>53.030017697862384</ele>
+        <time>2024-08-24T13:23:44.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95569633" lon="4.72280449">
+        <ele>52.98415577246478</ele>
+        <time>2024-08-24T13:23:46.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95574881" lon="4.72277826">
+        <ele>52.933952721578905</ele>
+        <time>2024-08-24T13:23:48.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95580536" lon="4.72274488">
+        <ele>52.910549553854295</ele>
+        <time>2024-08-24T13:23:50.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95585039" lon="4.72271696">
+        <ele>52.953958083953346</ele>
+        <time>2024-08-24T13:23:52.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95590365" lon="4.72269842">
+        <ele>52.94074669740898</ele>
+        <time>2024-08-24T13:23:54.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95595991" lon="4.7226852">
+        <ele>52.95414663898962</ele>
+        <time>2024-08-24T13:23:56.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95600481" lon="4.72266738">
+        <ele>52.95433519402589</ele>
+        <time>2024-08-24T13:23:58.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95606102" lon="4.72265237">
+        <ele>52.945842043042354</ele>
+        <time>2024-08-24T13:24:00.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95611773" lon="4.72263801">
+        <ele>52.891109311631915</ele>
+        <time>2024-08-24T13:24:02.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95618298" lon="4.72262339">
+        <ele>52.883182370713946</ele>
+        <time>2024-08-24T13:24:05.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95622802" lon="4.72260527">
+        <ele>52.817125437992125</ele>
+        <time>2024-08-24T13:24:07.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95627089" lon="4.72257389">
+        <ele>52.73974484891568</ele>
+        <time>2024-08-24T13:24:09.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95632035" lon="4.72251213">
+        <ele>52.690674218160936</ele>
+        <time>2024-08-24T13:24:14.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95636639" lon="4.72248724">
+        <ele>52.63461996662634</ele>
+        <time>2024-08-24T13:24:19.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95642249" lon="4.72248076">
+        <ele>52.59517436202952</ele>
+        <time>2024-08-24T13:24:23.000Z</time>
+      </trkpt>
+      <trkpt lat="50.9564848" lon="4.72247799">
+        <ele>52.511754017268075</ele>
+        <time>2024-08-24T13:24:27.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95652871" lon="4.72244929">
+        <ele>52.40360952961462</ele>
+        <time>2024-08-24T13:24:29.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95658075" lon="4.72243418">
+        <ele>52.29810753725273</ele>
+        <time>2024-08-24T13:24:33.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95663106" lon="4.72241298">
+        <ele>52.26715508363945</ele>
+        <time>2024-08-24T13:24:37.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95668445" lon="4.72240784">
+        <ele>52.213931882432696</ele>
+        <time>2024-08-24T13:24:40.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95673499" lon="4.72242246">
+        <ele>52.16089778121897</ele>
+        <time>2024-08-24T13:24:43.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95678547" lon="4.72245371">
+        <ele>52.11409144576975</ele>
+        <time>2024-08-24T13:24:46.000Z</time>
+      </trkpt>
+      <trkpt lat="50.9568009" lon="4.72252665">
+        <ele>52.02840626074603</ele>
+        <time>2024-08-24T13:24:49.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95681967" lon="4.72260488">
+        <ele>52.055206143907306</ele>
+        <time>2024-08-24T13:24:52.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95683725" lon="4.72267073">
+        <ele>52.10635305988806</ele>
+        <time>2024-08-24T13:24:54.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95686443" lon="4.72277479">
+        <ele>52.10956122028845</ele>
+        <time>2024-08-24T13:24:57.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95689141" lon="4.7228403">
+        <ele>52.07502295124548</ele>
+        <time>2024-08-24T13:25:00.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95693609" lon="4.72285738">
+        <ele>52.11918679140312</ele>
+        <time>2024-08-24T13:25:03.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95698635" lon="4.72283548">
+        <ele>52.165615471823045</ele>
+        <time>2024-08-24T13:25:05.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95704366" lon="4.722817">
+        <ele>52.21204360728621</ele>
+        <time>2024-08-24T13:25:08.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95711029" lon="4.72279125">
+        <ele>52.3535939438515</ele>
+        <time>2024-08-24T13:25:11.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95715739" lon="4.72278353">
+        <ele>52.42701160742572</ele>
+        <time>2024-08-24T13:25:14.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95721192" lon="4.72275906">
+        <ele>52.480234808632474</ele>
+        <time>2024-08-24T13:25:17.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95725127" lon="4.72272403">
+        <ele>52.50967773204207</ele>
+        <time>2024-08-24T13:25:19.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95730388" lon="4.72270628">
+        <ele>52.57724419496758</ele>
+        <time>2024-08-24T13:25:22.000Z</time>
+      </trkpt>
+      <trkpt lat="50.9573721" lon="4.72266515">
+        <ele>52.61574593446953</ele>
+        <time>2024-08-24T13:25:25.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95741777" lon="4.722665">
+        <ele>52.66651519542098</ele>
+        <time>2024-08-24T13:25:27.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95746647" lon="4.72266034">
+        <ele>52.71067903557862</ele>
+        <time>2024-08-24T13:25:30.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95751823" lon="4.72262439">
+        <ele>52.71520871610318</ele>
+        <time>2024-08-24T13:25:36.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95752801" lon="4.72269767">
+        <ele>52.742197699257474</ele>
+        <time>2024-08-24T13:25:44.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95754553" lon="4.72279602">
+        <ele>52.84486918624827</ele>
+        <time>2024-08-24T13:25:47.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95756443" lon="4.72287621">
+        <ele>52.879407455291236</ele>
+        <time>2024-08-24T13:25:50.000Z</time>
+      </trkpt>
+      <trkpt lat="50.9575831" lon="4.72296048">
+        <ele>52.90337628812466</ele>
+        <time>2024-08-24T13:25:54.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95760449" lon="4.72304368">
+        <ele>52.920928800157306</ele>
+        <time>2024-08-24T13:25:57.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95763536" lon="4.72311433">
+        <ele>52.886768186143634</ele>
+        <time>2024-08-24T13:26:00.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95769295" lon="4.72314608">
+        <ele>52.875632539868526</ele>
+        <time>2024-08-24T13:26:04.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95774087" lon="4.72313496">
+        <ele>52.9097931538822</ele>
+        <time>2024-08-24T13:26:06.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95780676" lon="4.72313088">
+        <ele>52.905829683423214</ele>
+        <time>2024-08-24T13:26:09.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95785568" lon="4.72312355">
+        <ele>52.925080825652564</ele>
+        <time>2024-08-24T13:26:11.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95792031" lon="4.7231221">
+        <ele>52.94678536318047</ele>
+        <time>2024-08-24T13:26:13.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95798286" lon="4.72313266">
+        <ele>53.04889064010569</ele>
+        <time>2024-08-24T13:26:15.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95803812" lon="4.72314905">
+        <ele>52.98623096777728</ele>
+        <time>2024-08-24T13:26:17.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95808694" lon="4.72320352">
+        <ele>52.981324177180184</ele>
+        <time>2024-08-24T13:26:20.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95810398" lon="4.72327503">
+        <ele>53.096640840649776</ele>
+        <time>2024-08-24T13:26:25.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95811096" lon="4.72335601">
+        <ele>53.0813531688794</ele>
+        <time>2024-08-24T13:26:28.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95812237" lon="4.72342726">
+        <ele>53.04889118506244</ele>
+        <time>2024-08-24T13:26:30.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95814309" lon="4.72350866">
+        <ele>53.037189873678514</ele>
+        <time>2024-08-24T13:26:32.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95816353" lon="4.72357949">
+        <ele>52.939048067212276</ele>
+        <time>2024-08-24T13:26:34.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95817685" lon="4.72366206">
+        <ele>52.93168733635987</ele>
+        <time>2024-08-24T13:26:37.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95816869" lon="4.72374155">
+        <ele>52.928667730995755</ele>
+        <time>2024-08-24T13:26:41.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95818485" lon="4.72382919">
+        <ele>52.88129573043772</ele>
+        <time>2024-08-24T13:26:44.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95818237" lon="4.72390931">
+        <ele>52.949616958465064</ele>
+        <time>2024-08-24T13:26:46.000Z</time>
+      </trkpt>
+      <trkpt lat="50.95813191" lon="4.72393309">
+        <ele>52.96396076514056</ele>
+        <time>2024-08-24T13:26:49.000Z</time>
+      </trkpt>
+    </trkseg>
+  </trk>
+</gpx>
+`
diff --git a/views/route_segments/add.templ b/views/route_segments/add.templ
index c103b4d7..0a72cdd6 100644
--- a/views/route_segments/add.templ
+++ b/views/route_segments/add.templ
@@ -68,9 +68,9 @@ templ Add() {
 					<h3>{ i18n.T(ctx, "Resources") }</h3>
 					<div>{ i18n.T(ctx, "You can find inspiration here:") }</div>
 					<ul>
-						<li><a href="https://runnermaps.nl/">RunnerMaps</a></li>
-						<li><a href="https://www.plotaroute.com/">plotaroute.com - Free Route Planner for Outdoor Pursuits</a></li>
-						<li><a href="https://www.komoot.com">Komoot | Find, plan and share your adventures</a></li>
+						<li><a target="_blank" href="https://runnermaps.nl/">RunnerMaps</a></li>
+						<li><a target="_blank" href="https://www.plotaroute.com/">plotaroute.com - Free Route Planner for Outdoor Pursuits</a></li>
+						<li><a target="_blank" href="https://www.komoot.com">Komoot | Find, plan and share your adventures</a></li>
 					</ul>
 				</div>
 			</div>
diff --git a/views/route_segments/add_templ.go b/views/route_segments/add_templ.go
index fa4d717b..a66b3b32 100644
--- a/views/route_segments/add_templ.go
+++ b/views/route_segments/add_templ.go
@@ -151,7 +151,7 @@ func Add() templ.Component {
 			if templ_7745c5c3_Err != nil {
 				return templ_7745c5c3_Err
 			}
-			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</div><ul><li><a href=\"https://runnermaps.nl/\">RunnerMaps</a></li><li><a href=\"https://www.plotaroute.com/\">plotaroute.com - Free Route Planner for Outdoor Pursuits</a></li><li><a href=\"https://www.komoot.com\">Komoot | Find, plan and share your adventures</a></li></ul></div></div></div>")
+			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</div><ul><li><a target=\"_blank\" href=\"https://runnermaps.nl/\">RunnerMaps</a></li><li><a target=\"_blank\" href=\"https://www.plotaroute.com/\">plotaroute.com - Free Route Planner for Outdoor Pursuits</a></li><li><a target=\"_blank\" href=\"https://www.komoot.com\">Komoot | Find, plan and share your adventures</a></li></ul></div></div></div>")
 			if templ_7745c5c3_Err != nil {
 				return templ_7745c5c3_Err
 			}
diff --git a/views/route_segments/list.templ b/views/route_segments/list.templ
index 1f7d09f9..3f81d843 100644
--- a/views/route_segments/list.templ
+++ b/views/route_segments/list.templ
@@ -41,6 +41,11 @@ templ List(segments []*database.RouteSegment) {
 							@listDetails(s)
 						</th>
 						<td class="hidden lg:table-cell">
+							if s.Dirty {
+								<span title={ i18n.T(ctx, "refresh in progress") }>
+									@helpers.IconFor("refresh")
+								</span>
+							}
 							<span class="actions">
 								@actions(s)
 							</span>
diff --git a/views/route_segments/list_templ.go b/views/route_segments/list_templ.go
index fe2f9ebf..88f14e4f 100644
--- a/views/route_segments/list_templ.go
+++ b/views/route_segments/list_templ.go
@@ -164,7 +164,38 @@ func List(segments []*database.RouteSegment) templ.Component {
 				if templ_7745c5c3_Err != nil {
 					return templ_7745c5c3_Err
 				}
-				templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "</th><td class=\"hidden lg:table-cell\"><span class=\"actions\">")
+				templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "</th><td class=\"hidden lg:table-cell\">")
+				if templ_7745c5c3_Err != nil {
+					return templ_7745c5c3_Err
+				}
+				if s.Dirty {
+					templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "<span title=\"")
+					if templ_7745c5c3_Err != nil {
+						return templ_7745c5c3_Err
+					}
+					var templ_7745c5c3_Var10 string
+					templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.T(ctx, "refresh in progress"))
+					if templ_7745c5c3_Err != nil {
+						return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/route_segments/list.templ`, Line: 45, Col: 56}
+					}
+					_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
+					if templ_7745c5c3_Err != nil {
+						return templ_7745c5c3_Err
+					}
+					templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\">")
+					if templ_7745c5c3_Err != nil {
+						return templ_7745c5c3_Err
+					}
+					templ_7745c5c3_Err = helpers.IconFor("refresh").Render(ctx, templ_7745c5c3_Buffer)
+					if templ_7745c5c3_Err != nil {
+						return templ_7745c5c3_Err
+					}
+					templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</span> ")
+					if templ_7745c5c3_Err != nil {
+						return templ_7745c5c3_Err
+					}
+				}
+				templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<span class=\"actions\">")
 				if templ_7745c5c3_Err != nil {
 					return templ_7745c5c3_Err
 				}
@@ -172,12 +203,12 @@ func List(segments []*database.RouteSegment) templ.Component {
 				if templ_7745c5c3_Err != nil {
 					return templ_7745c5c3_Err
 				}
-				templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</span></td></tr>")
+				templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "</span></td></tr>")
 				if templ_7745c5c3_Err != nil {
 					return templ_7745c5c3_Err
 				}
 			}
-			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</tbody></table>")
+			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</tbody></table>")
 			if templ_7745c5c3_Err != nil {
 				return templ_7745c5c3_Err
 			}