diff options
Diffstat (limited to 'web/frontend/ride-detail-logic.ts')
| -rw-r--r-- | web/frontend/ride-detail-logic.ts | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/web/frontend/ride-detail-logic.ts b/web/frontend/ride-detail-logic.ts index b4d4dba..e7fc822 100644 --- a/web/frontend/ride-detail-logic.ts +++ b/web/frontend/ride-detail-logic.ts @@ -1,4 +1,4 @@ -import type { ClimbBounds, ClimbMetrics, ProfilePoint } from "./types.js"; +import type { ClimbBounds, ClimbMetrics, ClimbSample, ProfilePoint } from "./types.js"; export const clamp = (value: number, min: number, max: number): number => Math.max(min, Math.min(max, value)); @@ -71,15 +71,13 @@ export const cotacolForClimb = (points: ProfilePoint[], startIndex: number, endI return cotacol; }; +const boundsAreValid = (points: ProfilePoint[], bounds: ClimbBounds | undefined): bounds is ClimbBounds => { + if (!bounds || !Number.isInteger(bounds.startIndex) || !Number.isInteger(bounds.endIndex)) return false; + return bounds.startIndex >= 0 && bounds.endIndex < points.length && bounds.startIndex < bounds.endIndex; +}; + export const climbMetrics = (points: ProfilePoint[], bounds: ClimbBounds | undefined): ClimbMetrics | null => { - if ( - !bounds || - !Number.isInteger(bounds.startIndex) || - !Number.isInteger(bounds.endIndex) || - bounds.startIndex < 0 || - bounds.endIndex >= points.length || - bounds.startIndex >= bounds.endIndex - ) { + if (!boundsAreValid(points, bounds)) { return null; } const start = points[bounds.startIndex]; @@ -98,3 +96,19 @@ export const climbMetrics = (points: ProfilePoint[], bounds: ClimbBounds | undef category: categoryForCotacol(cotacol), }; }; + +// climbSample returns the segment's recorded length and upward-only gain, as the server computes it for an official climb sample. +export const climbSample = (points: ProfilePoint[], bounds: ClimbBounds | undefined): ClimbSample | null => { + if (!boundsAreValid(points, bounds)) { + return null; + } + const sample: ClimbSample = { + distanceM: (points[bounds.endIndex].distanceKm - points[bounds.startIndex].distanceKm) * 1000, + elevationGainM: 0, + }; + for (let index = bounds.startIndex + 1; index <= bounds.endIndex; index++) { + const gain = points[index].elevationM - points[index - 1].elevationM; + if (gain > 0) sample.elevationGainM += gain; + } + return sample; +}; |
