summaryrefslogtreecommitdiff
path: root/ride/climb.go
diff options
context:
space:
mode:
authorMartin Kagamino Lehoux <martin@lehoux.net>2025-04-21 10:46:17 +0200
committerMartin Kagamino Lehoux <martin@lehoux.net>2025-04-21 10:46:17 +0200
commit87850541aa6f719721209ed994b93ad4d7ab4077 (patch)
treeb7aeb56f6cacabf6bf80e7c6ae142ca176046aa4 /ride/climb.go
parent81645d9a6995bb2f44019948b3f45c277772da5d (diff)
Add more data in climb & point
Diffstat (limited to 'ride/climb.go')
-rw-r--r--ride/climb.go46
1 files changed, 26 insertions, 20 deletions
diff --git a/ride/climb.go b/ride/climb.go
index 190225e..d2d5d0e 100644
--- a/ride/climb.go
+++ b/ride/climb.go
@@ -1,43 +1,49 @@
package ride
import (
+ "fmt"
"log/slog"
"math"
"slices"
+ "time"
+ "github.com/jftuga/geodist"
"github.com/martinlehoux/kagamigo/kcore"
)
const ClimbDistanceMinimum = 500
type Climb struct {
- start int
- end int
+ start int
+ end int
+ points []Point
}
-type Point struct {
- distance float64
- elevation float64
+func (climb Climb) String() string {
+ start := climb.points[0]
+ end := climb.points[len(climb.points)-1]
+ score := Score(climb.points, 0, len(climb.points)-1)
+ return fmt.Sprintf("%.1fkm-%.1fkm: %.1fkm at %.1f%% (%d pts - %s)", start.DistanceM/1000, end.DistanceM/1000, (end.DistanceM-start.DistanceM)/1000, Slope(start, end)*100, int(score), Category(score))
}
-func NewPoint(distance float64, elevation float64) Point {
- return Point{
- distance: distance,
- elevation: elevation,
- }
+type Point struct {
+ DistanceM float64
+ ElevationM float64
+ Coord geodist.Coord
+ Timestamp time.Time
}
func Slope(start, end Point) float64 {
- return (end.elevation - start.elevation) / (end.distance - start.distance)
+ return (end.ElevationM - start.ElevationM) / (end.DistanceM - start.DistanceM)
}
func Score(points []Point, start int, end int) float64 {
kcore.Assert(end > start, "no points for score")
- distance := points[end].distance - points[start].distance
+ distance := points[end].DistanceM - points[start].DistanceM
if distance == 0 {
return 0
}
- dElevation := points[end].elevation - points[start].elevation
+ dElevation := points[end].ElevationM - points[start].ElevationM
return math.Abs(dElevation) * dElevation / distance * 100.0 * 100.0 / 1000.0
}
@@ -86,7 +92,7 @@ func bestClimbBetween(points []Point, start int, end int) Climb {
bestScore = score
}
}
- climb := Climb{bestStart, bestEnd}
+ climb := Climb{start: bestStart, end: bestEnd, points: points[bestStart : bestEnd+1]}
kcore.Assert(climb.start < climb.end, "empty climb")
return climb
@@ -94,23 +100,23 @@ func bestClimbBetween(points []Point, start int, end int) Climb {
func climbsBetween(points []Point, start int, end int) []Climb {
climbs := []Climb{}
- if points[end].distance-points[start].distance < ClimbDistanceMinimum {
+ if points[end].DistanceM-points[start].DistanceM < ClimbDistanceMinimum {
return climbs
}
- slog.Debug("Searching climbs between", slog.Int("start", int(points[start].distance)), slog.Int("end", int(points[end].distance)))
+ slog.Debug("Searching climbs between", slog.Int("start", int(points[start].DistanceM)), slog.Int("end", int(points[end].DistanceM)))
highest := start
for i := start; i <= end; i++ {
- if points[i].elevation > points[highest].elevation {
+ if points[i].ElevationM > points[highest].ElevationM {
highest = i
}
}
// TODO: Use descent to reduce recursion
- if points[highest].distance-points[start].distance < ClimbDistanceMinimum {
+ if points[highest].DistanceM-points[start].DistanceM < ClimbDistanceMinimum {
return climbsBetween(points, start+1, end)
}
climb := bestClimbBetween(points, start, highest)
- if Score(points, climb.start, climb.end) >= 35 && points[climb.end].distance-points[climb.start].distance >= ClimbDistanceMinimum {
- slog.Debug("Found climb between", slog.Int("start", int(points[climb.start].distance)), slog.Int("end", int(points[climb.end].distance)))
+ if Score(points, climb.start, climb.end) >= 35 && points[climb.end].DistanceM-points[climb.start].DistanceM >= ClimbDistanceMinimum {
+ slog.Debug("Found climb between", slog.Int("start", int(points[climb.start].DistanceM)), slog.Int("end", int(points[climb.end].DistanceM)))
climbs = append(climbs, climb)
}
climbs = append(climbs, climbsBetween(points, start, climb.start)...)