feat: log OBD speed before GPS fix so rolling starts aren't lost

- _log_loop: when GPS has no fix but OBD speed > 1, write speed-only rows
  (NULL coordinates) instead of dropping the motion
- insert_tracking: accept None gps_x/gps_y -> NULL GPSX/GPSY
- app_trip: keep NULL-coord rows through normalize; _segment returns 0 for
  missing coords; route_points drops them (no position to draw)
- tests: speed-only rows build a trip with max speed + zero distance
- docs: FEAT-12 + readme note; server already filters NULL-GPS safely
This commit is contained in:
Mathieu Moran
2026-08-13 02:02:45 -04:00
parent fa8ae0001a
commit 3d49764855
5 changed files with 64 additions and 6 deletions
+12 -2
View File
@@ -47,9 +47,11 @@ def normalize_tracking_rows(rows):
longitude = _number(row[3])
speed = _number(row[4]) or 0
odometer = _number(row[5]) if len(row) > 5 else None
if timestamp is None or latitude is None or longitude is None:
if timestamp is None:
continue
if not (-90 <= latitude <= 90 and -180 <= longitude <= 180):
if latitude is not None and not (-90 <= latitude <= 90):
continue
if longitude is not None and not (-180 <= longitude <= 180):
continue
normalized.append({
"id": int(row[0]),
@@ -66,6 +68,11 @@ def _segment(row, previous):
seconds = (row["datetime"] - previous["datetime"]).total_seconds()
if seconds <= 0:
return 0, 0
if (
previous["latitude"] is None or previous["longitude"] is None
or row["latitude"] is None or row["longitude"] is None
):
return 0, 0
distance_km = haversine_km(
(previous["latitude"], previous["longitude"]),
(row["latitude"], row["longitude"]),
@@ -218,6 +225,9 @@ def build_trip_summaries(raw_rows):
def route_points(raw_rows, max_points=2000, odometer_baseline=0.0, prior_km=0.0):
rows = normalize_tracking_rows(raw_rows)
# The route polyline needs coordinates — drop speed-only rows logged before
# the first GPS fix (no position to draw; they add 0 distance anyway).
rows = [r for r in rows if r["latitude"] is not None and r["longitude"] is not None]
filtered_rows = []
for row in rows:
if filtered_rows: