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:
@@ -174,6 +174,11 @@ import Base from '../../layouts/Base.astro';
|
||||
data-handle="${u.handle}"
|
||||
title="Re-run merge_all and trigger a site rebuild"
|
||||
>Rebuild</button>
|
||||
<button
|
||||
class="recompute-elev-btn text-xs px-3 py-1.5 rounded-lg bg-zinc-800 hover:bg-zinc-700 text-zinc-400 hover:text-zinc-200 transition-colors"
|
||||
data-handle="${u.handle}"
|
||||
title="Recompute elevation gain/loss from stored timeseries (fixes leading-zero no-fix artefacts)"
|
||||
>Recompute elev.</button>
|
||||
<button
|
||||
class="pwreset-btn text-xs px-3 py-1.5 rounded-lg bg-zinc-800 hover:bg-zinc-700 text-zinc-400 hover:text-zinc-200 transition-colors"
|
||||
data-handle="${u.handle}"
|
||||
@@ -336,6 +341,32 @@ import Base from '../../layouts/Base.astro';
|
||||
});
|
||||
});
|
||||
|
||||
tbodyEl.querySelectorAll<HTMLButtonElement>('.recompute-elev-btn').forEach(btn => {
|
||||
btn.addEventListener('click', async () => {
|
||||
const h = btn.dataset.handle!;
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Running…';
|
||||
try {
|
||||
const r = await fetch(`/api/admin/users/${h}/recompute-elevation`, {
|
||||
method: 'POST', credentials: 'include',
|
||||
});
|
||||
const d = await r.json();
|
||||
if (r.ok) {
|
||||
btn.textContent = `Done (${d.patched} patched)`;
|
||||
btn.classList.add('text-green-400');
|
||||
} else {
|
||||
btn.textContent = 'Error: ' + (d.detail ?? r.status);
|
||||
btn.classList.add('text-red-400');
|
||||
btn.disabled = false;
|
||||
}
|
||||
} catch {
|
||||
btn.textContent = 'Error';
|
||||
btn.classList.add('text-red-400');
|
||||
btn.disabled = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
tbodyEl.querySelectorAll<HTMLButtonElement>('.pwreset-btn').forEach(btn => {
|
||||
btn.addEventListener('click', async () => {
|
||||
const h = btn.dataset.handle!;
|
||||
|
||||
Reference in New Issue
Block a user