diff --git a/static/js/history.js b/static/js/history.js index e319ce2..fc1697b 100644 --- a/static/js/history.js +++ b/static/js/history.js @@ -36,10 +36,17 @@ let _geoCache = {}; // key → label, pre-populated on trip load function _geoKey(lat, lon) { - return `${lat.toFixed(3)},${lon.toFixed(3)}`; + const la = typeof lat === 'number' ? lat : parseFloat(lat); + const lo = typeof lon === 'number' ? lon : parseFloat(lon); + if (isNaN(la) || isNaN(lo)) return null; + return `${la.toFixed(3)},${lo.toFixed(3)}`; } function preloadGeocodes(points) { + // Pre-fetch geocode labels for all unique coordinates with a small + // concurrency cap so the server (which uses slow Nominatim) doesn't + // get overwhelmed. The Pi's reverse_geocoder is instant, so this + // still works fast there. _geoCache = {}; const seen = new Set(); const queue = []; @@ -51,30 +58,27 @@ } if (!queue.length) return; - // Try batch endpoint first (server has it, Pi falls back to 404) - const coords = queue.map(q => ({lat: q.lat, lon: q.lon})); - const ctrl = new AbortController(); - const t = setTimeout(() => ctrl.abort(), 15000); - fetch('/api/geocode/batch', { - method: 'POST', - headers: {'Content-Type': 'application/json'}, - body: JSON.stringify({coords: coords}), - signal: ctrl.signal, - }) - .then(r => { clearTimeout(t); return r.ok ? r.json() : null; }) - .then(data => { - if (data) { - for (const q of queue) { - if (data[q.key]) _geoCache[q.key] = data[q.key]; - } - } - }) - .catch(() => { clearTimeout(t); }); + const CONCURRENCY = 2; + let idx = 0; + function next() { + if (idx >= queue.length) return; + const item = queue[idx++]; + const ctrl = new AbortController(); + const t = setTimeout(() => ctrl.abort(), 3000); + fetch(`/api/geocode?lat=${item.lat}&lon=${item.lon}`, { signal: ctrl.signal }) + .then(r => { clearTimeout(t); return r.ok ? r.json() : null; }) + .then(data => { + _geoCache[item.key] = (data && data.label) || null; + }) + .catch(() => { clearTimeout(t); }) + .finally(() => next()); + } + for (let i = 0; i < CONCURRENCY && i < queue.length; i++) next(); } function geocodePoint(lat, lon) { const key = _geoKey(lat, lon); - if (key === _lastGeoKey) return; + if (!key || key === _lastGeoKey) return; _lastGeoKey = key; const fallback = `${lat.toFixed(5)}, ${lon.toFixed(5)}`;