fix: DEM elevation overcounting and add hysteresis-only recalculation button
- dem.py: apply 45s median filter before hysteresis to suppress SRTM tile-boundary steps that were accumulating through the 5m threshold; raise DEM hysteresis threshold from 5m to 10m - dem.py: back up elevation_m as elevation_m_original in timeseries before the first DEM overwrite, so original sensor data is preserved - dem.py: add recalculate_elevation_hysteresis() — recomputes gain/loss from original recorded elevation (reads elevation_m_original if a DEM run already replaced elevation_m) using source-aware thresholds (5m barometric, 10m GPS/unknown); does not touch the elevation array - edit/server.py, serve/server.py: split /recalculate-elevation into two endpoints: /recalculate-elevation/dem and /recalculate-elevation/hysteresis - EditDrawer.svelte: replace single DEM button with two side-by-side buttons — "Recalculate (hysteresis)" (fast, offline) and "Recalculate (DEM)" (SRTM lookup)
This commit is contained in:
+19
-2
@@ -428,8 +428,8 @@ async def save_activity(activity_id: str, payload: dict[str, Any]) -> JSONRespon
|
||||
return JSONResponse({"ok": True, "sidecar": str(sidecar_path)})
|
||||
|
||||
|
||||
@app.post("/api/activity/{activity_id}/recalculate-elevation")
|
||||
async def recalculate_elevation_endpoint(activity_id: str) -> JSONResponse:
|
||||
@app.post("/api/activity/{activity_id}/recalculate-elevation/dem")
|
||||
async def recalculate_elevation_dem_endpoint(activity_id: str) -> JSONResponse:
|
||||
"""Replace GPS altitude with DEM terrain elevation and recompute gain/loss.
|
||||
|
||||
Requires --dem-url to be set when starting bincio edit.
|
||||
@@ -450,6 +450,23 @@ async def recalculate_elevation_endpoint(activity_id: str) -> JSONResponse:
|
||||
raise HTTPException(422, str(e))
|
||||
|
||||
|
||||
@app.post("/api/activity/{activity_id}/recalculate-elevation/hysteresis")
|
||||
async def recalculate_elevation_hysteresis_endpoint(activity_id: str) -> JSONResponse:
|
||||
"""Recompute gain/loss from original recorded elevation using source-aware hysteresis."""
|
||||
dd = _get_data_dir()
|
||||
_check_id(activity_id)
|
||||
try:
|
||||
from bincio.extract.dem import recalculate_elevation_hysteresis
|
||||
from bincio.render.merge import merge_one
|
||||
result = recalculate_elevation_hysteresis(dd, activity_id)
|
||||
merge_one(dd, activity_id)
|
||||
return JSONResponse(result)
|
||||
except FileNotFoundError as e:
|
||||
raise HTTPException(404, str(e))
|
||||
except ValueError as e:
|
||||
raise HTTPException(422, str(e))
|
||||
|
||||
|
||||
@app.post("/api/activity/{activity_id}/images")
|
||||
async def upload_image(activity_id: str, file: UploadFile = File(...)) -> JSONResponse:
|
||||
dd = _get_data_dir()
|
||||
|
||||
Reference in New Issue
Block a user