from __future__ import annotations from dataclasses import dataclass from pathlib import Path @dataclass(frozen=True) class GpsRecord: rel_path: str lon: float lat: float height: float def parse_dense_gps_txt(path: Path) -> list[GpsRecord]: """ DenseUAV формат строки (эмпирически): E N пример: train/satellite/000001/H80.tif E120.387... N30.324... 94.761 """ records: list[GpsRecord] = [] with path.open("r", encoding="utf-8", errors="replace") as f: for i, line in enumerate(f, start=1): line = line.strip() if not line: continue parts = line.split() if len(parts) != 4: raise ValueError(f"Bad GPS line {path}:{i}: expected 4 fields, got {len(parts)}: {line!r}") rel_path, e_lon, n_lat, height_s = parts if not e_lon.startswith("E") or not n_lat.startswith("N"): raise ValueError(f"Bad GPS line {path}:{i}: expected E.. N.. fields: {line!r}") lon = float(e_lon[1:]) lat = float(n_lat[1:]) height = float(height_s) records.append(GpsRecord(rel_path=rel_path, lon=lon, lat=lat, height=height)) return records def write_gps_csv(records: list[GpsRecord], out_csv: Path) -> None: out_csv.parent.mkdir(parents=True, exist_ok=True) with out_csv.open("w", encoding="utf-8") as f: f.write("rel_path,lon,lat,height\n") for r in records: f.write(f"{r.rel_path},{r.lon:.12f},{r.lat:.12f},{r.height:.6f}\n")