48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
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 формат строки (эмпирически):
|
|
<rel_path> E<lon> N<lat> <height>
|
|
пример:
|
|
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")
|
|
|