Fix elevation gain inflation from device no-fix leading zeros
Apple Watch and similar devices record exactly 0.0 for elevation while
waiting for barometric/GPS lock, then jump to the real altitude. The
hysteresis accumulator was seeding from 0.0, counting the full jump as
ascent. Fix: detect a leading near-zero run followed by a large jump
and seed the accumulator from the first real value instead.
Applied in both _elevation() (fresh extractions) and
recalculate_elevation_hysteresis() (recompute path). Added a bulk
admin endpoint POST /api/admin/users/{handle}/recompute-elevation and
corresponding button to fix existing stored activities.
This commit is contained in:
@@ -371,9 +371,23 @@ def _elevation(
|
||||
if len(elevations) < 2:
|
||||
return None, None
|
||||
threshold = _ELEVATION_THRESHOLD.get(altitude_source, 10.0)
|
||||
|
||||
# Some devices (e.g. Apple Watch) record exactly 0.0 for the initial samples
|
||||
# while waiting for barometric/GPS lock, then jump to the real altitude.
|
||||
# Detect this by checking for a leading near-zero run followed by a large
|
||||
# jump: skip those zeros and seed the accumulator from the first real value.
|
||||
# Safety: if the activity genuinely stays near sea level, no value in the
|
||||
# series will exceed `threshold`, so `start` stays 0 — unchanged behaviour.
|
||||
start = 0
|
||||
if abs(elevations[0]) < 0.5:
|
||||
for i, e in enumerate(elevations):
|
||||
if abs(e) > threshold:
|
||||
start = i
|
||||
break
|
||||
|
||||
gain = loss = 0.0
|
||||
committed = elevations[0]
|
||||
for e in elevations[1:]:
|
||||
committed = elevations[start]
|
||||
for e in elevations[start + 1:]:
|
||||
diff = e - committed
|
||||
if abs(diff) >= threshold:
|
||||
if diff > 0:
|
||||
|
||||
Reference in New Issue
Block a user