fix(geocode): accurate street name + always shows on dashboard
- Cache key uses 4 decimal places (~11m) instead of 3 (~111m) for correct street - Dashboard geocodes on first GPS fix, then again every >50m moved (throttled 15s) - Removed stale console.log Co-authored-by: Copilot <[email protected]>
This commit is contained in:
@@ -93,10 +93,10 @@ import functools
|
|||||||
import urllib.request
|
import urllib.request
|
||||||
|
|
||||||
@functools.lru_cache(maxsize=512)
|
@functools.lru_cache(maxsize=512)
|
||||||
def _geocode_cached(lat3, lon3):
|
def _geocode_cached(lat4, lon4):
|
||||||
"""Try Nominatim first (street-level), fall back to reverse_geocoder (city)."""
|
"""Try Nominatim first (street-level), fall back to reverse_geocoder (city)."""
|
||||||
lat = lat3 / 1000.0
|
lat = lat4 / 10000.0
|
||||||
lon = lon3 / 1000.0
|
lon = lon4 / 10000.0
|
||||||
try:
|
try:
|
||||||
url = f"https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat={lat}&lon={lon}&accept-language=en"
|
url = f"https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat={lat}&lon={lon}&accept-language=en"
|
||||||
req = urllib.request.Request(url, headers={"User-Agent": "yaris-obd/1.0"})
|
req = urllib.request.Request(url, headers={"User-Agent": "yaris-obd/1.0"})
|
||||||
@@ -126,7 +126,7 @@ def geocode_route():
|
|||||||
except (KeyError, ValueError):
|
except (KeyError, ValueError):
|
||||||
return jsonify(error="lat and lon required"), 400
|
return jsonify(error="lat and lon required"), 400
|
||||||
# Round to 3 decimals (~111m precision) for cache key
|
# Round to 3 decimals (~111m precision) for cache key
|
||||||
label = _geocode_cached(round(lat, 3) * 1000 // 1, round(lon, 3) * 1000 // 1)
|
label = _geocode_cached(int(round(lat, 4) * 10000), int(round(lon, 4) * 10000))
|
||||||
return jsonify(label=label)
|
return jsonify(label=label)
|
||||||
|
|
||||||
@app.route('/api/dash/devices')
|
@app.route('/api/dash/devices')
|
||||||
|
|||||||
+13
-5
@@ -186,6 +186,7 @@ socket.on('obd_error', function (data) {
|
|||||||
|
|
||||||
let mapCentered = false;
|
let mapCentered = false;
|
||||||
let _lastLat = null, _lastLon = null;
|
let _lastLat = null, _lastLon = null;
|
||||||
|
let _lastGeoLat = null, _lastGeoLon = null;
|
||||||
let _geocodeTimer = null;
|
let _geocodeTimer = null;
|
||||||
|
|
||||||
const _recenterBtn = document.getElementById('btn-recenter');
|
const _recenterBtn = document.getElementById('btn-recenter');
|
||||||
@@ -198,14 +199,19 @@ _recenterBtn.addEventListener('click', function () {
|
|||||||
function reverseGeocode(lat, lon) {
|
function reverseGeocode(lat, lon) {
|
||||||
const el = document.getElementById('gps-location-name');
|
const el = document.getElementById('gps-location-name');
|
||||||
const fallback = `${lat.toFixed(5)}, ${lon.toFixed(5)}`;
|
const fallback = `${lat.toFixed(5)}, ${lon.toFixed(5)}`;
|
||||||
fetch(`/api/geocode?lat=${lat}&lon=${lon}`, { signal: AbortSignal.timeout(4000) })
|
fetch(`/api/geocode?lat=${lat}&lon=${lon}`, { signal: AbortSignal.timeout(6000) })
|
||||||
.then(r => r.ok ? r.json() : null)
|
.then(r => r.ok ? r.json() : null)
|
||||||
.then(data => { el.textContent = (data && data.label) ? data.label : fallback; })
|
.then(data => { el.textContent = (data && data.label) ? data.label : fallback; })
|
||||||
.catch(() => { el.textContent = fallback; });
|
.catch(() => { el.textContent = fallback; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _movedEnough(lat, lon) {
|
||||||
|
if (_lastGeoLat === null) return true;
|
||||||
|
// ~0.0005 deg ≈ 50m
|
||||||
|
return Math.abs(lat - _lastGeoLat) > 0.0005 || Math.abs(lon - _lastGeoLon) > 0.0005;
|
||||||
|
}
|
||||||
|
|
||||||
socket.on('gps_location', function(data) {
|
socket.on('gps_location', function(data) {
|
||||||
console.log("location received")
|
|
||||||
const LocationX = document.getElementById('gpsLocationX');
|
const LocationX = document.getElementById('gpsLocationX');
|
||||||
const LocationY = document.getElementById('gpsLocationY');
|
const LocationY = document.getElementById('gpsLocationY');
|
||||||
LocationX.innerHTML = data[0];
|
LocationX.innerHTML = data[0];
|
||||||
@@ -225,10 +231,12 @@ socket.on('gps_location', function(data) {
|
|||||||
_lastLat = lat;
|
_lastLat = lat;
|
||||||
_lastLon = lon;
|
_lastLon = lon;
|
||||||
_recenterBtn.hidden = false;
|
_recenterBtn.hidden = false;
|
||||||
// Throttle geocode to at most once every 30s
|
// Geocode when moved >50m, throttled to at most once every 15s
|
||||||
if (!_geocodeTimer) {
|
if (!_geocodeTimer && _movedEnough(lat, lon)) {
|
||||||
|
_lastGeoLat = lat;
|
||||||
|
_lastGeoLon = lon;
|
||||||
reverseGeocode(lat, lon);
|
reverseGeocode(lat, lon);
|
||||||
_geocodeTimer = setTimeout(() => { _geocodeTimer = null; }, 30000);
|
_geocodeTimer = setTimeout(() => { _geocodeTimer = null; }, 15000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user