Prometheus-prototype / api /routes /telemetry.py
Tadiwa-M
Deploy: auto-derive dedup radius (drop hardcoded 3m bypass)
58aefd4
Raw
History Blame Contribute Delete
1.97 kB
"""Telemetry endpoint — read flight metadata from an uploaded image.
Lets the dashboard auto-fill survey geometry (altitude, FOV, nadir/oblique)
from a drone frame's EXIF/XMP instead of asking the user to type it.
"""
from __future__ import annotations
import shutil
import tempfile
from pathlib import Path
from fastapi import APIRouter, File, HTTPException, UploadFile
router = APIRouter(prefix="/api/telemetry", tags=["telemetry"])
@router.post("/read")
async def read_telemetry(file: UploadFile = File(...)) -> dict:
"""Parse EXIF/XMP flight telemetry from an uploaded image.
Returns what was found (altitude, gimbal angle → nadir/oblique, FOV, GPS),
whether it's enough to georeference, and which fields are missing. Never
guesses — missing stays missing.
"""
try:
from src.geolocation.telemetry import parse_telemetry
except ImportError as exc:
raise HTTPException(status_code=503, detail="Pillow not installed.") from exc
suffix = Path(file.filename or "frame.jpg").suffix or ".jpg"
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp:
shutil.copyfileobj(file.file, tmp)
tmp_path = tmp.name
try:
tel = parse_telemetry(tmp_path)
finally:
Path(tmp_path).unlink(missing_ok=True)
return {
"source": tel.source, # "xmp", "exif", "xmp+exif", "none"
"viewpoint": tel.viewpoint, # "nadir" | "oblique" | None
"has_geometry": tel.to_camera() is not None,
"missing": tel.missing(),
"altitude_m": tel.altitude_m,
"gimbal_pitch_deg": tel.gimbal_pitch_deg,
"cam_pitch_deg": tel.cam_pitch_deg,
"gimbal_yaw_deg": tel.gimbal_yaw_deg,
"hfov_deg": tel.hfov_deg,
"focal_35mm": tel.focal_35mm,
"gps_lat": tel.gps_lat,
"gps_lon": tel.gps_lon,
"image_width": tel.image_width,
"image_height": tel.image_height,
}