feat: routes /map /nav Leaflet GPS/USBL + Chart.js depth viewer
This commit is contained in:
@@ -162,5 +162,76 @@ def _main():
|
||||
_PLY_PATH = args.ply
|
||||
app.run(host="0.0.0.0", port=args.port, debug=False)
|
||||
|
||||
# ── COSMA QC Platform additions ──────────────────────────
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
_DATA_DIR = Path(os.environ.get("COSMA_DATA_DIR", "/data/cosma"))
|
||||
|
||||
|
||||
def _load_nav_data(job_id: int) -> dict:
|
||||
out = {"job_id": job_id}
|
||||
poses_path = _DATA_DIR / f"job_{job_id}_poses.npz"
|
||||
ply_path = _DATA_DIR / f"job_{job_id}_decimated.ply"
|
||||
if poses_path.exists():
|
||||
d = np.load(str(poses_path))
|
||||
poses = d["poses"] # (N, 3, 4)
|
||||
xyz = poses[:, :3, 3]
|
||||
out["track"] = {
|
||||
"x": xyz[:, 0].tolist(),
|
||||
"y": xyz[:, 1].tolist(),
|
||||
"z": xyz[:, 2].tolist(),
|
||||
}
|
||||
out["n_poses"] = int(len(poses))
|
||||
out["ply_ready"] = ply_path.exists()
|
||||
out["ply_path"] = str(ply_path) if ply_path.exists() else None
|
||||
return out
|
||||
|
||||
|
||||
@app.route("/map")
|
||||
def map_view():
|
||||
from flask import render_template
|
||||
return render_template("map.html")
|
||||
|
||||
|
||||
@app.route("/nav")
|
||||
def nav_view():
|
||||
from flask import render_template
|
||||
return render_template("nav.html")
|
||||
|
||||
|
||||
@app.route("/api/jobs")
|
||||
def api_jobs():
|
||||
jobs = []
|
||||
for p in sorted(_DATA_DIR.glob("job_*_decimated.ply")):
|
||||
parts = p.stem.split("_")
|
||||
jid = int(parts[1])
|
||||
jobs.append({
|
||||
"id": jid,
|
||||
"ply": str(p),
|
||||
"poses": str(_DATA_DIR / f"job_{jid}_poses.npz"),
|
||||
})
|
||||
return jsonify(jobs)
|
||||
|
||||
|
||||
@app.route("/api/job/<int:job_id>/nav")
|
||||
def api_job_nav(job_id: int):
|
||||
return jsonify(_load_nav_data(job_id))
|
||||
|
||||
|
||||
@app.route("/api/job/<int:job_id>/ply")
|
||||
def api_job_ply(job_id: int):
|
||||
ply_path = _DATA_DIR / f"job_{job_id}_decimated.ply"
|
||||
if not ply_path.exists():
|
||||
return jsonify({"error": "PLY non disponible"}), 404
|
||||
try:
|
||||
import open3d as o3d
|
||||
pcd = o3d.io.read_point_cloud(str(ply_path))
|
||||
pts = np.asarray(pcd.points)
|
||||
return jsonify({"x": pts[:, 0].tolist(), "y": pts[:, 1].tolist(),
|
||||
"z": pts[:, 2].tolist(), "n": int(len(pts))})
|
||||
except ImportError:
|
||||
return jsonify({"error": "open3d not installed"}), 503
|
||||
|
||||
if __name__ == "__main__":
|
||||
_main()
|
||||
|
||||
Reference in New Issue
Block a user