diff options
Diffstat (limited to 'rideanalysis/analysis.go')
| -rw-r--r-- | rideanalysis/analysis.go | 80 |
1 files changed, 34 insertions, 46 deletions
diff --git a/rideanalysis/analysis.go b/rideanalysis/analysis.go index a4c319f..f055676 100644 --- a/rideanalysis/analysis.go +++ b/rideanalysis/analysis.go @@ -1,9 +1,8 @@ package rideanalysis import ( - "math" + "slices" - "github.com/jftuga/geodist" "github.com/martinlehoux/biking_home/mountain_pass" "github.com/martinlehoux/biking_home/official_climb" "github.com/martinlehoux/biking_home/ride" @@ -37,64 +36,53 @@ func Analyze(parsed ride.Ride, passes []mountain_pass.MountainPass, officialClim Climbs: make([]AnalyzedClimb, 0), Crossings: make([]mountain_pass.Crossing, 0), } - for _, detectedClimb := range parsed.AllClimbs() { + claimedClimbs := make([]AnalyzedClimb, 0) + claimedRanges := make([]ride.Range, 0) + for _, official := range officialClimbs { + matched, found := official_climb.MatchClimb(parsed.Coords, official, matchPolicy.EndpointRadiusM) + if !found { + continue + } + 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 _, detectedClimb := range parsed.DetectClimbs(claimedRanges) { displayClimb := detectedClimb if matchedPass, ok := mountain_pass.MatchClimb(displayClimb, passes, passMatchRadiusM, passMatchElevationToleranceM); ok { displayClimb.Name = matchedPass.Name } - matchedOfficial, officialFound := official_climb.MatchClimb(parsed, detectedClimb, officialClimbs, matchPolicy) - if officialFound { - startIndex := nearestCoordIndex(parsed, matchedOfficial.StartCoord) - endIndex := nearestCoordIndex(parsed, matchedOfficial.EndCoord) - if startIndex < endIndex { - displayClimb = parsed.ClimbFromIndexes(startIndex, endIndex) - displayClimb.Name = matchedOfficial.Name - } else { - officialFound = false - matchedOfficial = official_climb.OfficialClimb{} - } - } - cotacol := displayClimb.DifficultyScore() - result.Climbs = append(result.Climbs, AnalyzedClimb{ - Segment: displayClimb, - Name: displayClimb.Name, - Category: ride.CategoryOf(cotacol).String(), - DistanceM: displayClimb.EndDistanceM() - displayClimb.StartDistanceM(), - SlopePercent: ride.Slope(parsed, displayClimb.StartIndex(), displayClimb.EndIndex()) * 100, - Cotacol: cotacol, - OfficialClimbID: officialClimbID(matchedOfficial, officialFound), - OfficialName: officialClimbName(matchedOfficial, officialFound), - }) + result.Climbs = append(result.Climbs, analyzedClimb(parsed, displayClimb, displayClimb.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() + }) + result.Climbs = climbs for _, crossing := range mountain_pass.DetectCrossings(parsed, passes, passCrossingRadiusM, passCrossingElevationToleranceM) { result.Crossings = append(result.Crossings, crossing) } return result } -func nearestCoordIndex(parsed ride.Ride, target geodist.Coord) int { - bestIndex := 0 - bestDistance := math.Inf(1) - for index := 0; index < parsed.Len(); index++ { - _, distanceKm := geodist.HaversineDistance(parsed.Coord(index), target) - if distanceKm < bestDistance { - bestDistance = distanceKm - bestIndex = index - } - } - return bestIndex -} - -func officialClimbID(climb official_climb.OfficialClimb, found bool) int64 { - if !found { - return 0 +func analyzedClimb(parsed ride.Ride, segment ride.Climb, 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, segment.StartIndex(), segment.EndIndex()) * 100, + Cotacol: cotacol, + OfficialClimbID: officialID, + OfficialName: officialClimbNameForID(name, officialID), } - return climb.ID } -func officialClimbName(climb official_climb.OfficialClimb, found bool) string { - if !found { +func officialClimbNameForID(name string, officialID int64) string { + if officialID == 0 { return "" } - return climb.Name + return name } |
