Skip to content

Commit

Permalink
Merge pull request #20 from pixelspark/fix/multi-segment-tracks-pauses
Browse files Browse the repository at this point in the history
fix: deal correctly with GPX files that have multiple segments and count time between segments as pause time
  • Loading branch information
jovandeginste authored Mar 3, 2024
2 parents 5c7f3d3 + 3e5e688 commit 108ee5d
Showing 1 changed file with 41 additions and 23 deletions.
64 changes: 41 additions & 23 deletions pkg/database/workouts_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,15 @@ func (m *MapCenter) Address() *geo.Address {

// allGPXPoints returns the first track segment's points
func allGPXPoints(gpxContent *gpx.GPX) []gpx.GPXPoint {
gpxContent.ReduceGpxToSingleTrack()

if len(gpxContent.Tracks) == 0 {
return nil
}
var points []gpx.GPXPoint

if len(gpxContent.Tracks[0].Segments) == 0 {
return nil
for _, track := range gpxContent.Tracks {
for _, segment := range track.Segments {
points = append(points, segment.Points...)
}
}

return gpxContent.Tracks[0].Segments[0].Points
return points
}

func gpxName(gpxContent *gpx.GPX) string {
Expand Down Expand Up @@ -158,37 +156,57 @@ func distanceBetween(p1 gpx.GPXPoint, p2 gpx.GPXPoint) float64 {
}

func createMapData(gpxContent *gpx.GPX) *MapData {
gpxContent.ReduceGpxToSingleTrack()

if len(gpxContent.Tracks) == 0 {
return nil
}

if len(gpxContent.Tracks[0].Segments) == 0 {
return nil
var (
totalDistance, maxElevation, minElevation, uphill, downhill, maxSpeed float64
totalDuration, pauseDuration time.Duration
lastSegmentEnd *gpx.GPXPoint
)

for _, track := range gpxContent.Tracks {
for _, segment := range track.Segments {
if len(segment.Points) > 0 {
totalDistance += segment.Length3D()
totalDuration += time.Duration(segment.Duration()) * time.Second
pauseDuration += (time.Duration(segment.MovingData().StoppedTime)) * time.Second
minElevation = min(minElevation, segment.ElevationBounds().MinElevation)
maxElevation = max(maxElevation, segment.ElevationBounds().MaxElevation)
uphill += segment.UphillDownhill().Uphill
downhill += segment.UphillDownhill().Downhill
maxSpeed = max(maxSpeed, segment.MovingData().MaxSpeed)

firstPoint := &segment.Points[0]
if lastSegmentEnd != nil {
// Calculate time between this segment's first point and last segment's last point, and add to pause time
pauseDuration += firstPoint.Timestamp.Sub(lastSegmentEnd.Timestamp)
}

lastPoint := &segment.Points[len(segment.Points)-1]
lastSegmentEnd = lastPoint
}
}
}

// Now reduce the whole GPX to a single track to calculate the center
gpxContent.ReduceGpxToSingleTrack()
mapCenter := center(gpxContent)

totalDistance := gpxContent.Tracks[0].Segments[0].Length3D()
totalDuration := time.Duration(gpxContent.Tracks[0].Segments[0].Duration()) * time.Second
pauseDuration := time.Duration(gpxContent.Tracks[0].Segments[0].MovingData().StoppedTime) * time.Second

updown := gpxContent.Tracks[0].Segments[0].UphillDownhill()

data := &MapData{
Creator: gpxContent.Creator,
Name: gpxName(gpxContent),
Center: mapCenter,
Address: mapCenter.Address(),
TotalDistance: totalDistance,
TotalDuration: totalDuration,
MaxSpeed: gpxContent.Tracks[0].Segments[0].MovingData().MaxSpeed,
MaxSpeed: maxSpeed,
PauseDuration: pauseDuration,
MinElevation: correctAltitude(gpxContent.Creator, mapCenter.Lat, mapCenter.Lng, gpxContent.Tracks[0].Segments[0].ElevationBounds().MinElevation),
MaxElevation: correctAltitude(gpxContent.Creator, mapCenter.Lat, mapCenter.Lng, gpxContent.Tracks[0].Segments[0].ElevationBounds().MaxElevation),
TotalUp: updown.Uphill,
TotalDown: updown.Downhill,
MinElevation: correctAltitude(gpxContent.Creator, mapCenter.Lat, mapCenter.Lng, minElevation),
MaxElevation: correctAltitude(gpxContent.Creator, mapCenter.Lat, mapCenter.Lng, maxElevation),
TotalUp: uphill,
TotalDown: downhill,
}

return data
Expand Down

0 comments on commit 108ee5d

Please sign in to comment.