From df7c9b5130ba193fc918a947a461f2a70dc2dd3c Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Sun, 16 Aug 2026 14:55:26 +0200 Subject: fix(web): use Cotacol for climb difficulty --- ride/.snapshots/TestRideClimbLaCride | 6 ++--- ride/climb.go | 47 +++++++++++++++------------------- ride/climb_test.go | 42 +++++++++++++++--------------- ride/ride.go | 21 +++------------ rideanalysis/analysis.go | 8 +++--- web/frontend/ride-detail-canvas.ts | 4 +-- web/frontend/ride-detail-logic.test.ts | 12 ++++++--- web/frontend/ride-detail-logic.ts | 27 +++++++++---------- web/frontend/types.d.ts | 2 -- web/server.go | 6 ++--- web/server_test.go | 1 + web/views.go | 10 +++----- 12 files changed, 84 insertions(+), 102 deletions(-) diff --git a/ride/.snapshots/TestRideClimbLaCride b/ride/.snapshots/TestRideClimbLaCride index 456818e..d81ca17 100644 --- a/ride/.snapshots/TestRideClimbLaCride +++ b/ride/.snapshots/TestRideClimbLaCride @@ -1,5 +1,5 @@ ([]string) (len=3) { - (string) (len=69) "Climb 17.1km-18.8km: 1.7km at 4.8% (38 pts - Cat 4) (5m50s, 17.0km/h)", - (string) (len=65) " 17.2km-18.8km: 1.6km at 4.9% (38 pts - Cat 4) (7m42s, 12.8km/h)", - (string) (len=70) "Climb 35.1km-40.1km: 5.1km at 4.3% (94 pts - Cat 3) (18m48s, 16.2km/h)" + (string) (len=69) "Climb 17.1km-18.8km: 1.7km at 4.8% (45 pts - Cat 4) (5m50s, 17.0km/h)", + (string) (len=65) " 17.2km-18.8km: 1.6km at 4.9% (45 pts - Cat 4) (7m42s, 12.8km/h)", + (string) (len=71) "Climb 35.1km-40.1km: 5.1km at 4.3% (126 pts - Cat 3) (18m48s, 16.2km/h)" } diff --git a/ride/climb.go b/ride/climb.go index 788cd61..56e47c6 100644 --- a/ride/climb.go +++ b/ride/climb.go @@ -79,18 +79,14 @@ func (climb Climb) TopCoord() geodist.Coord { func (climb Climb) String() string { startDistance := climb.StartDistanceM() endDistance := climb.EndDistanceM() - score := climb.Score() - body := fmt.Sprintf("%.1fkm-%.1fkm: %.1fkm at %.1f%% (%d pts - %s)", startDistance/1000, endDistance/1000, (endDistance-startDistance)/1000, Slope(climb.ride, climb.rideStart, climb.rideEnd)*100, int(score), Category(score)) + cotacol := climb.DifficultyScore() + body := fmt.Sprintf("%.1fkm-%.1fkm: %.1fkm at %.1f%% (%d pts - %s)", startDistance/1000, endDistance/1000, (endDistance-startDistance)/1000, Slope(climb.ride, climb.rideStart, climb.rideEnd)*100, int(cotacol), Category(cotacol)) if climb.Name == "" { return body } return climb.Name + ": " + body } -func (climb Climb) Score() float64 { - return Score(climb.ride, climb.rideStart, climb.rideEnd) -} - func (climb Climb) DifficultyScore() float64 { return difficultyScore(climb.ride, climb.rideStart, climb.rideEnd) } @@ -99,28 +95,27 @@ func Slope(r Ride, start, end int) float64 { return (r.ElevationM(end) - r.ElevationM(start)) / (r.DistanceM(end) - r.DistanceM(start)) } -func Score(r Ride, start, end int) float64 { - kcore.Assert(end > start, "no points for score") +func climbDetectionScore(r Ride, start, end int) float64 { + kcore.Assert(end > start, "no points for climb detection") distance := r.DistanceM(end) - r.DistanceM(start) if distance == 0 { return 0 } dElevation := r.ElevationM(end) - r.ElevationM(start) - return math.Abs(dElevation) * dElevation / distance * 100.0 * 100.0 / 1000.0 } -func Category(score float64) string { +func Category(cotacol float64) string { switch { - case score < 35: + case cotacol < 35: return "NO" - case score < 80: + case cotacol < 80: return "Cat 4" - case score < 180: + case cotacol < 180: return "Cat 3" - case score < 250: + case cotacol < 250: return "Cat 2" - case score < 600: + case cotacol < 600: return "Cat 1" default: return "HC" @@ -130,28 +125,28 @@ func Category(score float64) string { func bestClimbBetween(r Ride, start, end int) Climb { kcore.Assert(end > start, "empty points") - bestScore := Score(r, start, end) + bestDetectionScore := climbDetectionScore(r, start, end) bestStart := start for i := start; i < end; i++ { - score := Score(r, i, end) - if score > bestScore { + detectionScore := climbDetectionScore(r, i, end) + if detectionScore > bestDetectionScore { bestStart = i - bestScore = score + bestDetectionScore = detectionScore } } bestEnd := end for i := end; i > bestStart; i-- { - score := Score(r, bestStart, i) - if score > bestScore { + detectionScore := climbDetectionScore(r, bestStart, i) + if detectionScore > bestDetectionScore { bestEnd = i - bestScore = score + bestDetectionScore = detectionScore } } for i := bestStart; i < bestEnd; i++ { - score := Score(r, i, bestEnd) - if score > bestScore { + detectionScore := climbDetectionScore(r, i, bestEnd) + if detectionScore > bestDetectionScore { bestStart = i - bestScore = score + bestDetectionScore = detectionScore } } kcore.Assert(bestStart < bestEnd, "empty climb") @@ -175,7 +170,7 @@ func climbsBetween(r Ride, start, end int) []Climb { return climbsBetween(r, start+1, end) } climb := bestClimbBetween(r, start, highest) - if climb.Score() >= 35 && climb.EndDistanceM()-climb.StartDistanceM() >= ClimbDistanceMinimum { + if climbDetectionScore(r, climb.rideStart, climb.rideEnd) >= 35 && climb.EndDistanceM()-climb.StartDistanceM() >= ClimbDistanceMinimum { slog.Debug("Found climb between", slog.Int("start", int(climb.StartDistanceM())), slog.Int("end", int(climb.EndDistanceM()))) climbs = append(climbs, climb) } diff --git a/ride/climb_test.go b/ride/climb_test.go index 3dd6e53..feca001 100644 --- a/ride/climb_test.go +++ b/ride/climb_test.go @@ -86,12 +86,12 @@ func TestPogacar20220721(t *testing.T) { climbs := r.AllClimbs() assert.Len(t, climbs, 6) - assert.Equal(t, "0.6km-5.6km: 5.0km at 3.5% (62 pts - Cat 4)", climbs[0].String()) - assert.Equal(t, "42.9km-45.2km: 2.3km at 5.0% (59 pts - Cat 4)", climbs[1].String()) - assert.Equal(t, "60.0km-76.4km: 16.4km at 7.2% (854 pts - HC)", climbs[2].String()) - assert.Equal(t, "83.8km-85.9km: 2.0km at 5.4% (59 pts - Cat 4)", climbs[3].String()) - assert.Equal(t, "99.2km-109.3km: 10.2km at 8.4% (710 pts - HC)", climbs[4].String()) - assert.Equal(t, "128.6km-142.2km: 13.6km at 7.8% (832 pts - HC)", climbs[5].String()) + assert.Equal(t, "0.6km-5.6km: 5.0km at 3.5% (92 pts - Cat 3)", climbs[0].String()) + assert.Equal(t, "42.9km-45.2km: 2.3km at 5.0% (74 pts - Cat 4)", climbs[1].String()) + assert.Equal(t, "60.0km-76.4km: 16.4km at 7.2% (977 pts - HC)", climbs[2].String()) + assert.Equal(t, "83.8km-85.9km: 2.0km at 5.4% (79 pts - Cat 4)", climbs[3].String()) + assert.Equal(t, "99.2km-109.3km: 10.2km at 8.4% (751 pts - HC)", climbs[4].String()) + assert.Equal(t, "128.6km-142.2km: 13.6km at 7.8% (930 pts - HC)", climbs[5].String()) } func TestBouclesVerdon2024(t *testing.T) { @@ -100,12 +100,12 @@ func TestBouclesVerdon2024(t *testing.T) { climbs := r.AllClimbs() assert.Len(t, climbs, 6) - assert.Equal(t, "3.6km-13.8km: 10.3km at 2.1% (44 pts - Cat 4)", climbs[0].String()) // TODO: Not steep enough - assert.Equal(t, "34.7km-37.3km: 2.5km at 5.0% (62 pts - Cat 4)", climbs[1].String()) - assert.Equal(t, "41.9km-51.0km: 9.0km at 2.5% (55 pts - Cat 4)", climbs[2].String()) // TODO: Not steep enough - assert.Equal(t, "57.6km-60.8km: 3.1km at 6.3% (124 pts - Cat 3)", climbs[3].String()) - assert.Equal(t, "71.7km-74.7km: 3.0km at 5.3% (84 pts - Cat 3)", climbs[4].String()) - assert.Equal(t, "77.4km-78.7km: 1.3km at 5.3% (37 pts - Cat 4)", climbs[5].String()) + assert.Equal(t, "3.6km-13.8km: 10.3km at 2.1% (98 pts - Cat 3)", climbs[0].String()) // TODO: Not steep enough + assert.Equal(t, "34.7km-37.3km: 2.5km at 5.0% (67 pts - Cat 4)", climbs[1].String()) + assert.Equal(t, "41.9km-51.0km: 9.0km at 2.5% (113 pts - Cat 3)", climbs[2].String()) // TODO: Not steep enough + assert.Equal(t, "57.6km-60.8km: 3.1km at 6.3% (139 pts - Cat 3)", climbs[3].String()) + assert.Equal(t, "71.7km-74.7km: 3.0km at 5.3% (89 pts - Cat 3)", climbs[4].String()) + assert.Equal(t, "77.4km-78.7km: 1.3km at 5.3% (39 pts - Cat 4)", climbs[5].String()) } func TestMimetArbois20241229(t *testing.T) { @@ -114,8 +114,8 @@ func TestMimetArbois20241229(t *testing.T) { climbs := r.AllClimbs() assert.Len(t, climbs, 2) - assert.Equal(t, "3.9km-5.3km: 1.4km at 10.3% (153 pts - Cat 3)", climbs[0].String()) - assert.Equal(t, "14.4km-19.8km: 5.4km at 4.3% (98 pts - Cat 3)", climbs[1].String()) + assert.Equal(t, "3.9km-5.3km: 1.4km at 10.3% (165 pts - Cat 3)", climbs[0].String()) + assert.Equal(t, "14.4km-19.8km: 5.4km at 4.3% (113 pts - Cat 3)", climbs[1].String()) } func TestMimetArbois20250104(t *testing.T) { @@ -124,8 +124,8 @@ func TestMimetArbois20250104(t *testing.T) { climbs := r.AllClimbs() assert.Len(t, climbs, 2) - assert.Equal(t, "4.5km-5.9km: 1.4km at 10.1% (148 pts - Cat 3)", climbs[0].String()) - assert.Equal(t, "12.0km-20.2km: 8.2km at 2.9% (67 pts - Cat 4)", climbs[1].String()) // TODO: Not steep enough + assert.Equal(t, "4.5km-5.9km: 1.4km at 10.1% (159 pts - Cat 3)", climbs[0].String()) + assert.Equal(t, "12.0km-20.2km: 8.2km at 2.9% (148 pts - Cat 3)", climbs[1].String()) // TODO: Not steep enough } // https://www.strava.com/activities/9282265844 @@ -135,10 +135,10 @@ func TestAlpesVerdonTour20230617(t *testing.T) { climbs := r.AllClimbs() assert.Len(t, climbs, 6) - assert.Equal(t, "0.7km-18.6km: 17.9km at 3.5% (217 pts - Cat 2)", climbs[0].String()) // TODO: Should split in 2 (10km at 4.5% is Cat 2) - assert.Equal(t, "36.1km-41.6km: 5.4km at 5.8% (182 pts - Cat 2)", climbs[1].String()) + assert.Equal(t, "0.7km-18.6km: 17.9km at 3.5% (364 pts - Cat 1)", climbs[0].String()) // TODO: Should split in 2 (10km at 4.5% is Cat 2) + assert.Equal(t, "36.1km-41.6km: 5.4km at 5.8% (193 pts - Cat 2)", climbs[1].String()) assert.Equal(t, "47.0km-48.2km: 1.2km at 6.1% (45 pts - Cat 4)", climbs[2].String()) - assert.Equal(t, "51.9km-54.7km: 2.8km at 4.0% (45 pts - Cat 4)", climbs[3].String()) - assert.Equal(t, "86.7km-92.8km: 6.1km at 2.7% (44 pts - Cat 4)", climbs[4].String()) - assert.Equal(t, "114.1km-114.7km: 0.6km at 14.3% (118 pts - Cat 3)", climbs[5].String()) + assert.Equal(t, "51.9km-54.7km: 2.8km at 4.0% (48 pts - Cat 4)", climbs[3].String()) + assert.Equal(t, "86.7km-92.8km: 6.1km at 2.7% (60 pts - Cat 4)", climbs[4].String()) + assert.Equal(t, "114.1km-114.7km: 0.6km at 14.3% (119 pts - Cat 3)", climbs[5].String()) } diff --git a/ride/ride.go b/ride/ride.go index 3458483..152bca4 100644 --- a/ride/ride.go +++ b/ride/ride.go @@ -226,21 +226,6 @@ func metricValue(point gpx.GPXPoint, name string) (*float64, error) { return &value, nil } -func (r *Ride) ScoreFromKm(start, end float64) float64 { - i := 0 - j := 0 - for k, distance := range r.distances { - if i == 0 && distance >= start*1000 { - i = k - } - if j == 0 && distance >= end*1000 { - j = k - break - } - } - return Score(*r, i, j) -} - const CotacolAlgorithmVersion = "v1" func Cotacol(ride Ride) float64 { @@ -256,7 +241,7 @@ func difficultyScore(r Ride, startIndex, endIndex int) float64 { if lastDistance <= startDistance { return 0 } - score := 0.0 + cotacol := 0.0 i := startIndex for start := startDistance; start < lastDistance; start += 100 { end := math.Min(start+100, lastDistance) @@ -270,10 +255,10 @@ func difficultyScore(r Ride, startIndex, endIndex int) float64 { endElevation := interpolateElevation(r, i, end) slope := (endElevation - startElevation) / (end - start) if slope > 0 { - score += (end - start) / 1000 * (slope * 100) * (slope * 100) + cotacol += (end - start) / 1000 * (slope * 100) * (slope * 100) } } - return score + return cotacol } func interpolateElevation(r Ride, i int, distance float64) float64 { diff --git a/rideanalysis/analysis.go b/rideanalysis/analysis.go index 3d34855..122a29f 100644 --- a/rideanalysis/analysis.go +++ b/rideanalysis/analysis.go @@ -17,7 +17,6 @@ type Result struct { type AnalyzedClimb struct { Segment ride.Climb Name string - Score float64 Category string DistanceM float64 SlopePercent float64 @@ -48,15 +47,14 @@ func Analyze(parsed ride.Ride, passes []mountain_pass.MountainPass, officialClim matchedOfficial = official_climb.OfficialClimb{} } } - score := displayClimb.Score() + cotacol := displayClimb.DifficultyScore() result.Climbs = append(result.Climbs, AnalyzedClimb{ Segment: displayClimb, Name: displayClimb.Name, - Score: score, - Category: ride.Category(score), + Category: ride.Category(cotacol), DistanceM: displayClimb.EndDistanceM() - displayClimb.StartDistanceM(), SlopePercent: ride.Slope(parsed, displayClimb.StartIndex(), displayClimb.EndIndex()) * 100, - Cotacol: displayClimb.DifficultyScore(), + Cotacol: cotacol, OfficialClimbID: officialClimbID(matchedOfficial, officialFound), OfficialName: officialClimbName(matchedOfficial, officialFound), }) diff --git a/web/frontend/ride-detail-canvas.ts b/web/frontend/ride-detail-canvas.ts index 1453013..c61afee 100644 --- a/web/frontend/ride-detail-canvas.ts +++ b/web/frontend/ride-detail-canvas.ts @@ -1,4 +1,4 @@ -import { clamp, climbMetrics, formatDistance, formatElevation, nearestPointIndex } from "./ride-detail-logic.js"; +import { clamp, climbMetrics, formatClimbLabel, formatDistance, formatElevation, nearestPointIndex } from "./ride-detail-logic.js"; import type { BoundarySource, ClimbBounds, RideDetailColors, RideProfile, RideProfilePoint } from "./types.js"; interface Plot { @@ -137,7 +137,7 @@ export class RideProfileCanvas { const endX = clamp(this.xForDistance(metrics.end.distanceKm), plot.left, plot.right); this.context.fillStyle = climbIndex === this.focusedClimbIndex ? this.colors.climbFocusFill : this.colors.accentFill; this.context.fillRect(startX, plot.top, Math.max(endX - startX, 1), plot.bottom - plot.top); - const label = climb.name || `${metrics.category} ${Math.round(metrics.score)}`; + const label = formatClimbLabel(climb.name, metrics.category, metrics.cotacol); this.context.fillStyle = this.colors.climbLabel; this.context.textAlign = "center"; this.context.textBaseline = "top"; diff --git a/web/frontend/ride-detail-logic.test.ts b/web/frontend/ride-detail-logic.test.ts index 024f018..b848f7e 100644 --- a/web/frontend/ride-detail-logic.test.ts +++ b/web/frontend/ride-detail-logic.test.ts @@ -1,10 +1,11 @@ import test from "node:test"; import assert from "node:assert/strict"; import { - categoryForScore, + categoryForCotacol, climbMetrics, cotacolForClimb, elevationAtDistance, + formatClimbLabel, formatDistance, formatElevation, nearestPointIndex, @@ -28,7 +29,7 @@ test("interpolates elevation between route points", () => { assert.equal(elevationAtDistance(points, 2, 250), 120); }); -test("calculates climb metrics with the Cotacol score", () => { +test("calculates climb metrics with Cotacol", () => { const metrics = climbMetrics(points, { startIndex: 0, endIndex: 3 }); assert.ok(metrics); @@ -36,7 +37,12 @@ test("calculates climb metrics with the Cotacol score", () => { assert.equal(metrics.elevationGain, 20); assert.equal(metrics.slope, 8); assert.equal(metrics.cotacol, cotacolForClimb(points, 0, 3)); - assert.equal(metrics.category, categoryForScore(metrics.score)); + assert.equal(metrics.category, categoryForCotacol(metrics.cotacol)); +}); + +test("formats profile climb labels with Cotacol", () => { + assert.equal(formatClimbLabel("", "Cat 4", 45.9), "Cat 4 45.9"); + assert.equal(formatClimbLabel("Col de Test", "Cat 4", 45.9), "Col de Test"); }); test("formats profile labels consistently", () => { diff --git a/web/frontend/ride-detail-logic.ts b/web/frontend/ride-detail-logic.ts index 825bb2c..a2ba80a 100644 --- a/web/frontend/ride-detail-logic.ts +++ b/web/frontend/ride-detail-logic.ts @@ -19,15 +19,17 @@ export const nearestPointIndex = (points: ProfilePoint[], distance: number): num return distance - previous.distanceKm < points[low].distanceKm - distance ? low - 1 : low; }; -export const categoryForScore = (score: number): string => { - if (score < 35) return "NO"; - if (score < 80) return "Cat 4"; - if (score < 180) return "Cat 3"; - if (score < 250) return "Cat 2"; - if (score < 600) return "Cat 1"; +export const categoryForCotacol = (cotacol: number): string => { + if (cotacol < 35) return "NO"; + if (cotacol < 80) return "Cat 4"; + if (cotacol < 180) return "Cat 3"; + if (cotacol < 250) return "Cat 2"; + if (cotacol < 600) return "Cat 1"; return "HC"; }; +export const formatClimbLabel = (name: string, category: string, cotacol: number): string => name || `${category} ${cotacol.toFixed(1)}`; + export const elevationAtDistance = (points: ProfilePoint[], index: number, distanceM: number): number => { if (index + 1 >= points.length) return points[index].elevationM; const startDistanceM = points[index].distanceKm * 1000; @@ -40,7 +42,7 @@ export const cotacolForClimb = (points: ProfilePoint[], startIndex: number, endI const startDistanceM = points[startIndex].distanceKm * 1000; const lastDistanceM = points[endIndex].distanceKm * 1000; if (lastDistanceM <= startDistanceM) return 0; - let score = 0; + let cotacol = 0; let pointIndex = startIndex; for (let segmentStartM = startDistanceM; segmentStartM < lastDistanceM; segmentStartM += 100) { const segmentEndM = Math.min(segmentStartM + 100, lastDistanceM); @@ -49,9 +51,9 @@ export const cotacolForClimb = (points: ProfilePoint[], startIndex: number, endI while (pointIndex < endIndex && points[pointIndex + 1].distanceKm * 1000 < segmentEndM) pointIndex++; const endElevation = elevationAtDistance(points, pointIndex, segmentEndM); const slope = (endElevation - startElevation) / (segmentEndM - segmentStartM); - if (slope > 0) score += ((segmentEndM - segmentStartM) / 1000) * (slope * 100) ** 2; + if (slope > 0) cotacol += ((segmentEndM - segmentStartM) / 1000) * (slope * 100) ** 2; } - return score; + return cotacol; }; export const climbMetrics = (points: ProfilePoint[], bounds: ClimbBounds | undefined): ClimbMetrics | null => { @@ -70,15 +72,14 @@ export const climbMetrics = (points: ProfilePoint[], bounds: ClimbBounds | undef const distanceKm = end.distanceKm - start.distanceKm; const elevationGain = end.elevationM - start.elevationM; const slope = distanceKm > 0 ? elevationGain / (distanceKm * 10) : 0; - const score = distanceKm > 0 ? ((Math.abs(elevationGain) * elevationGain) / (distanceKm * 1000)) * 10 : 0; + const cotacol = cotacolForClimb(points, bounds.startIndex, bounds.endIndex); return { start, end, distanceKm, elevationGain, slope, - score, - cotacol: cotacolForClimb(points, bounds.startIndex, bounds.endIndex), - category: categoryForScore(score), + cotacol, + category: categoryForCotacol(cotacol), }; }; diff --git a/web/frontend/types.d.ts b/web/frontend/types.d.ts index 66f1ad2..3642971 100644 --- a/web/frontend/types.d.ts +++ b/web/frontend/types.d.ts @@ -18,7 +18,6 @@ export interface RideProfileClimb { topKm: number; topElevationM: number; name: string; - score: number; category: string; distanceKm: number; slopePercent: number; @@ -69,7 +68,6 @@ export interface ClimbMetrics { distanceKm: number; elevationGain: number; slope: number; - score: number; cotacol: number; category: string; } diff --git a/web/server.go b/web/server.go index 5d5e239..42ee21d 100644 --- a/web/server.go +++ b/web/server.go @@ -218,10 +218,10 @@ func buildRideViews(items []rides.Ride) []RideView { func buildRideView(item rides.Ride) RideView { view := RideView{Ride: item, Cotacol: "-", CotacolPer100Km: "-"} - score, ready := item.CotacolScore() + cotacol, ready := item.CotacolScore() if ready && item.CotacolAlgorithmVersion() == ride.CotacolAlgorithmVersion && item.DistanceM > 0 { - view.Cotacol = formatCotacol(score) - view.CotacolPer100Km = formatCotacolPer100Km(score, item.DistanceM) + view.Cotacol = formatCotacol(cotacol) + view.CotacolPer100Km = formatCotacolPer100Km(cotacol, item.DistanceM) } return view } diff --git a/web/server_test.go b/web/server_test.go index 654d6d5..f719372 100644 --- a/web/server_test.go +++ b/web/server_test.go @@ -151,6 +151,7 @@ func TestHandlerRendersRideDetailWithEmbeddedRoute(t *testing.T) { assert.Contains(t, body, `"type":"FeatureCollection"`) assert.Contains(t, body, `"type":"LineString"`) assert.Contains(t, body, `"coordinates":[[5,43]`) + assert.NotContains(t, body, `"score":`) profileStaticRequest := httptest.NewRequest(http.MethodGet, "/static/official-climb-profile.js", nil) profileStaticResponse := httptest.NewRecorder() diff --git a/web/views.go b/web/views.go index f8a45d3..551a74f 100644 --- a/web/views.go +++ b/web/views.go @@ -68,7 +68,6 @@ type RideProfileClimb struct { TopKm float64 `json:"topKm"` TopElevationM float64 `json:"topElevationM"` Name string `json:"name"` - Score float64 `json:"score"` Category string `json:"category"` DistanceKm float64 `json:"distanceKm"` SlopePercent float64 `json:"slopePercent"` @@ -269,7 +268,6 @@ func buildRideProfile(parsed ride.Ride, passes []mountain_pass.MountainPass, off TopKm: segment.TopDistanceM() / 1000, TopElevationM: segment.TopElevationM(), Name: analyzedClimb.Name, - Score: analyzedClimb.Score, Category: analyzedClimb.Category, DistanceKm: analyzedClimb.DistanceM / 1000, SlopePercent: analyzedClimb.SlopePercent, @@ -327,16 +325,16 @@ func formatElevation(meters float64) string { return fmt.Sprintf("%.0f m", meters) } -func formatCotacol(score float64) string { - return fmt.Sprintf("%.1f", score) +func formatCotacol(cotacol float64) string { + return fmt.Sprintf("%.1f", cotacol) } -func formatCotacolPer100Km(score, distanceM float64) string { +func formatCotacolPer100Km(cotacol, distanceM float64) string { distanceKm := distanceM / 1000 if distanceKm <= 0 { return "-" } - return fmt.Sprintf("%.1f", score*100/distanceKm) + return fmt.Sprintf("%.1f", cotacol*100/distanceKm) } func formatRouteIndex(index int) string { -- cgit v1.2.3