aboutsummaryrefslogtreecommitdiff
path: root/rideanalysis
Commit message (Collapse)AuthorAge
* Expose ride data as components and make algorithms consume only the slices ↵Martin Kagamino Lehoux2026-08-25
| | | | | | | | | | | 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.
* Match official climbs once per lap on looping ridesMartin Kagamino Lehoux2026-08-23
| | | | | | | | | | | | 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.
* Require a 3.5% minimum slope on detected climbs, re-segmenting gentler stretchesMartin Kagamino Lehoux2026-08-21
| | | | | | | | | | | | | | A detected climb must now average at least 3.5% slope with re-segmentation: gentle drags are split into their qualifying steeper parts instead of being reported wholesale or dropped. Qualifying climbs keep their previous boundaries exactly; only regions whose classic best climb averages below the threshold get re-segmented (full-scan for the best qualifying sub-segment, found=false when none exists). QA: A/B across data/rides (362 rides) went from 137 to 133 climbs, 23 rides changed; the 7 fully-dropped rides were audited to contain zero qualifying sub-segments. Example-ride tests updated for the new behavior; the resolved "minimum slope" TODO was removed.
* feat: bound climb detection by matched official climbsMartin Kagamino Lehoux2026-08-21
| | | | | | | | | | | | | | | 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
* refactor(ride,rideanalysis): replace magic numbers with named constantsMartin Kagamino Lehoux2026-08-21
|
* fix: match official climbs outside detected boundsMartin Kagamino Lehoux2026-08-18
|
* fix(web): use Cotacol for climb difficultyMartin Kagamino Lehoux2026-08-16
|
* refactor: extract ride analysisMartin Kagamino Lehoux2026-08-14