feat: routes /map /nav — Leaflet GPS/USBL + Chart.js depth viewer

This commit is contained in:
Ubuntu
2026-04-25 16:02:01 +00:00
parent 8ef1c3d8a6
commit 276c850893
5 changed files with 253 additions and 0 deletions

50
viz/static/js/map.js Normal file
View File

@@ -0,0 +1,50 @@
const map = L.map('map').setView([43.17, 5.70], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OSM contributors', maxZoom: 19
}).addTo(map);
const status = document.getElementById('status');
let trackLayer = null;
async function loadJobs() {
const res = await fetch('/nav/api/jobs');
const jobs = await res.json();
const sel = document.getElementById('job-select');
jobs.forEach(j => {
const opt = document.createElement('option');
opt.value = j.id;
opt.textContent = 'job_' + j.id;
sel.appendChild(opt);
});
const urlJob = new URLSearchParams(window.location.search).get('job');
const target = urlJob ? parseInt(urlJob) : (jobs.length > 0 ? jobs[0].id : null);
if (target) {
sel.value = target;
loadJob(target);
} else {
status.textContent = 'Aucun job disponible';
}
}
async function loadJob(jobId) {
status.textContent = 'Chargement job_' + jobId + '...';
const res = await fetch('/nav/api/job/' + jobId + '/nav');
const d = await res.json();
if (trackLayer) map.removeLayer(trackLayer);
if (!d.track || !d.track.x.length) {
status.textContent = 'Pas de données track pour job_' + jobId;
return;
}
const cx = d.track.x.reduce((a,b)=>a+b,0)/d.track.x.length;
const cy = d.track.y.reduce((a,b)=>a+b,0)/d.track.y.length;
const pts = d.track.x.map((x,i) => [43.17 + (d.track.y[i]-cy)*0.000009, 5.70 + (x-cx)*0.000009]);
trackLayer = L.polyline(pts, { color: '#4ade80', weight: 2 }).addTo(map);
map.fitBounds(trackLayer.getBounds());
status.textContent = 'job_' + jobId + ' — ' + d.n_poses + ' poses | PLY: ' + (d.ply_ready ? 'prêt' : 'non dispo');
}
document.getElementById('job-select').addEventListener('change', e => {
if (e.target.value) loadJob(parseInt(e.target.value));
});
loadJobs();