local conversion

This commit is contained in:
Davide Scaini
2026-04-06 22:25:57 +02:00
parent b633d72258
commit 5bf0f3636c
11 changed files with 426 additions and 28 deletions
+44 -4
View File
@@ -2,11 +2,51 @@
from typing import Optional
from rdp import rdp
from bincio.extract.models import DataPoint
def _rdp_mask(coords: list[list[float]], epsilon: float) -> list[bool]:
"""Pure-Python RDP — returns a boolean keep-mask of the same length as coords."""
n = len(coords)
if n < 2:
return [True] * n
mask = [False] * n
mask[0] = mask[-1] = True
stack = [(0, n - 1)]
while stack:
start, end = stack.pop()
if end - start < 2:
continue
x1, y1 = coords[start]
x2, y2 = coords[end]
dx, dy = x2 - x1, y2 - y1
seg_len_sq = dx * dx + dy * dy
max_dist = -1.0
max_idx = start + 1
for i in range(start + 1, end):
x0, y0 = coords[i]
if seg_len_sq == 0:
d = ((x0 - x1) ** 2 + (y0 - y1) ** 2) ** 0.5
else:
t = ((x0 - x1) * dx + (y0 - y1) * dy) / seg_len_sq
t = max(0.0, min(1.0, t))
px, py = x1 + t * dx, y1 + t * dy
d = ((x0 - px) ** 2 + (y0 - py) ** 2) ** 0.5
if d > max_dist:
max_dist = d
max_idx = i
if max_dist >= epsilon:
mask[max_idx] = True
stack.append((start, max_idx))
stack.append((max_idx, end))
return mask
def simplify_track(
points: list[DataPoint],
epsilon: float = 0.0001,
@@ -21,7 +61,7 @@ def simplify_track(
return [p for p, _, _ in gps_pts]
coords = [[lon, lat] for _, lat, lon in gps_pts]
mask = rdp(coords, epsilon=epsilon, return_mask=True)
mask = _rdp_mask(coords, epsilon=epsilon)
return [p for (p, _, _), keep in zip(gps_pts, mask) if keep]
@@ -40,7 +80,7 @@ def preview_coords(
# Coarse RDP (larger epsilon = fewer points)
coords = [[lon, lat] for lat, lon in gps]
mask = rdp(coords, epsilon=0.001, return_mask=True)
mask = _rdp_mask(coords, epsilon=0.001)
reduced = [gps[i] for i, keep in enumerate(mask) if keep]
# Subsample if still too many — always include last point without exceeding max_points