| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
An official climb matched on endpoint coordinates alone. On a loop ridden
the other way the route meets the climb's top before its bottom, so pairing
each start with the first end inside its lap window credited a 5.9 km
passage as the 850 m Chemin de la Tour Pey Blanc, and a 49 km one on
another ride.
Climbs now keep the sample of the segment they were created from: the
recorded length and elevation gain of the selected route points, captured
by the ride detail and preview handlers and stored NOT NULL. Matching takes
the whole route and drops any candidate outside ±50% of that sample on
either axis, and attempts are refreshed by upsert and prune so re-analyzing
a ride keeps the recorded-at stamp of the passages that survive.
The backfill leaves the web package: backfill.Run recomputes ride values
then official climb attempts as a single `go run . backfill` command
(climbs-backfill is gone), rideanalysis owns the attempt snapshot, and the
mountain-pass loading margin is shared. Applied to the stored rides it
stamps 78 samples, drops the four bogus attempts and leaves ride 800 with
its three Pont Rout passages.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Move climb detection, slope, and Cotacol scoring out of ride into a new
climb package that operates on a geometry-only Route (distances, elevations,
coords). Ride embeds climb.Route and keeps its timing and telemetry columns.
- climb.Detect returns []DetectedClimb (Climb + ride-absolute Start).
- Climb owns its sliced geometry; indices are local, with Start reported at
the detection boundary for absolute position.
- Detected bounds use core.Interval; freeRegions claim suppression fixed.
- ride no longer builds slices: ClimbFromDist/ClimbFromIndexes/climbFrom and
ride.Climb/Interval/Range are removed; rideanalysis, mountain_pass MatchClimb,
and web views are rewired to climb types.
- New internal/routetest builds climb.Route from the ride DSL; ridetest reuses
it and adds timestamps and telemetry.
- Tests moved to climb (synthetic detection and difficulty) and kept in ride
for GPX-example integration; ride.comparison detection coverage retained.
- mountain_pass.nearestCrossing now reuses geo.Nearest.
|
| |
|
|
|
|
|
|
|
|
|
| |
Replace raw FromColumns 4-array blocks in official_climb, mountain_pass
and web test rides with ridetest.MustRide strings. Add a Heading option to
ridetest for routes whose points are spaced differently per kilometer
(e.g. the mountain_pass expanded-bounds route at 0.1 degrees/km).
Lap, direction and cluster tests in official_climb keep FromColumns: the
DSL generates monotonic northeast coords and cannot express per-point
loops or reversals.
|
| |
|
|
|
|
|
|
| |
The DistanceM, ElevationM, Coord, Timestamp and optional metric index
accessors (HeartRateBpm, CadenceRpm, PowerW) are no longer used by any
production code now that algorithms and consumers read ride components.
Tests that asserted metric parsing and coordinates now read the component
slices (Distances, Coords, HeartRates, Cadences, Powers).
|
| |
|
|
|
|
|
|
|
|
|
| |
they read
Ride now exposes its columns as component getters (Distances, Elevations,
Coords, Timestamps, and the optional Powers, Cadences, HeartRates) with the
coords field unexported. difficultyScore, movingTime, Slope and the climb
detection internals are pure functions over the specific slices they use,
and Climb carries only the component slices it needs instead of a whole
Ride.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Official climb matching now returns all non-overlapping occurrences
per ride instead of only the globally nearest pair. Each lap is
detected by clustering contiguous points within the endpoint radius
and pairing each start cluster with the first end cluster inside its
window, preserving direction. The ride analysis aggregates all matches
and sorts claimed ranges before excluding them from auto-detection.
Fixes the case where a looping ride only showed one instance of a
saved climb while the user expected one per repetition.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Detected climbs no longer absorb an official climb's range: official climbs
matched to the route by coordinates claim their stored start/end range, and
climb detection now runs only in the free regions around them. On ride 263 a
single absorbed Cat 2 ascent is split so creating a first-half official climb
lets the second half be detected on its own.
- ride: add Range, freeRegions, and DetectClimbs(claimed); exclude claimed
ranges so a climb never overlaps one
- official_climb: MatchClimb now bounds-matches purely by coordinates without
needing a detected climb; extract geo.Nearest shared helper
- rideanalysis: Analyze builds claimed climbs from matched official climbs and
detects only in free regions; render official vs unmatched climbs separately
|
| | |
|
| | |
|
| |
|