diff options
Diffstat (limited to 'rideanalysis')
| -rw-r--r-- | rideanalysis/analysis.go | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/rideanalysis/analysis.go b/rideanalysis/analysis.go index 5e08e65..a9cf93d 100644 --- a/rideanalysis/analysis.go +++ b/rideanalysis/analysis.go @@ -3,6 +3,8 @@ package rideanalysis import ( "slices" + "github.com/martinlehoux/biking_home/climb" + "github.com/martinlehoux/biking_home/core" "github.com/martinlehoux/biking_home/mountain_pass" "github.com/martinlehoux/biking_home/official_climb" "github.com/martinlehoux/biking_home/ride" @@ -21,7 +23,7 @@ type Result struct { } type AnalyzedClimb struct { - Segment ride.Climb + Segment climb.Climb Name string Category string DistanceM float64 @@ -29,6 +31,7 @@ type AnalyzedClimb struct { Cotacol float64 OfficialClimbID int64 OfficialName string + Interval core.Interval } func Analyze(parsed ride.Ride, passes []mountain_pass.MountainPass, officialClimbs []official_climb.OfficialClimb, matchPolicy official_climb.MatchPolicy) Result { @@ -37,45 +40,57 @@ func Analyze(parsed ride.Ride, passes []mountain_pass.MountainPass, officialClim Crossings: make([]mountain_pass.Crossing, 0), } claimedClimbs := make([]AnalyzedClimb, 0) - claimedRanges := make([]ride.Range, 0) + claimedRanges := make([]core.Interval, 0) for _, official := range officialClimbs { - for _, matched := range official_climb.MatchClimbs(parsed.Coords(), official, matchPolicy.EndpointRadiusM) { - claimedRanges = append(claimedRanges, ride.Range{Start: matched.StartIndex, End: matched.EndIndex}) - claimedClimbs = append(claimedClimbs, analyzedClimb(parsed, parsed.ClimbFromIndexes(matched.StartIndex, matched.EndIndex), official.Name, official.ID)) + for _, matched := range official_climb.MatchClimbs(parsed.Coords, official, matchPolicy.EndpointRadiusM) { + interval := core.NewInterval(matched.StartIndex, matched.EndIndex) + claimedRanges = append(claimedRanges, interval) + claimedClimbs = append(claimedClimbs, analyzedClimb(routeClimb(parsed.Route, interval), interval, official.Name, official.ID)) } } - slices.SortFunc(claimedRanges, func(a, b ride.Range) int { return a.Start - b.Start }) - for _, detectedClimb := range parsed.DetectClimbs(claimedRanges, ride.ClimbSlopeMinimum) { - displayClimb := detectedClimb - if matchedPass, ok := mountain_pass.MatchClimb(displayClimb, passes, passMatchRadiusM, passMatchElevationToleranceM); ok { - displayClimb.Name = matchedPass.Name + slices.SortFunc(claimedRanges, func(a, b core.Interval) int { return a.Start - b.Start }) + for _, detected := range climb.Detect(parsed.Route, claimedRanges, climb.ClimbSlopeMinimum) { + name := "" + if matchedPass, ok := mountain_pass.MatchClimb(detected.Climb, passes, passMatchRadiusM, passMatchElevationToleranceM); ok { + name = matchedPass.Name } - result.Climbs = append(result.Climbs, analyzedClimb(parsed, displayClimb, displayClimb.Name, 0)) + interval := core.NewInterval(detected.Start, detected.Start+len(detected.Climb.Distances)-1) + result.Climbs = append(result.Climbs, analyzedClimb(detected.Climb, interval, name, 0)) } climbs := make([]AnalyzedClimb, 0, len(claimedClimbs)+len(result.Climbs)) climbs = append(climbs, claimedClimbs...) climbs = append(climbs, result.Climbs...) slices.SortFunc(climbs, func(a, b AnalyzedClimb) int { - return a.Segment.StartIndex() - b.Segment.StartIndex() + return a.Interval.Start - b.Interval.Start }) result.Climbs = climbs - for _, crossing := range mountain_pass.DetectCrossings(parsed.Coords(), parsed.Distances(), parsed.Elevations(), passes, passCrossingRadiusM, passCrossingElevationToleranceM) { + for _, crossing := range mountain_pass.DetectCrossings(parsed.Coords, parsed.Distances, parsed.Elevations, passes, passCrossingRadiusM, passCrossingElevationToleranceM) { result.Crossings = append(result.Crossings, crossing) } return result } -func analyzedClimb(parsed ride.Ride, segment ride.Climb, name string, officialID int64) AnalyzedClimb { +// routeClimb returns the climb segment of route covered by interval. +func routeClimb(route climb.Route, interval core.Interval) climb.Climb { + return climb.Climb{Route: climb.Route{ + Distances: route.Distances[interval.Start : interval.End+1], + Elevations: route.Elevations[interval.Start : interval.End+1], + Coords: route.Coords[interval.Start : interval.End+1], + }} +} + +func analyzedClimb(segment climb.Climb, interval core.Interval, name string, officialID int64) AnalyzedClimb { cotacol := segment.DifficultyScore() return AnalyzedClimb{ Segment: segment, Name: name, - Category: ride.CategoryOf(cotacol).String(), - DistanceM: segment.EndDistanceM() - segment.StartDistanceM(), - SlopePercent: ride.Slope(parsed.Distances(), parsed.Elevations(), segment.StartIndex(), segment.EndIndex()) * 100, + Category: climb.CategoryOf(cotacol).String(), + DistanceM: segment.Distances[len(segment.Distances)-1] - segment.Distances[0], + SlopePercent: climb.Slope(segment.Distances, segment.Elevations) * 100, Cotacol: cotacol, OfficialClimbID: officialID, OfficialName: officialClimbNameForID(name, officialID), + Interval: interval, } } |
