fixed and consolidated location querys
This commit is contained in:
1 parent
1701eb5070
commit
739a1eee28
4 files changed
+158
-141
No files matched your search
@@ -0,0 +1,80 @@
|
|||||||
|
// Single source of truth for "where is the user" across the home hero map,
|
||||||
|
// /map, and Browse Events' location filter — storage, place search, and
|
||||||
|
// GPS lookup used to be copy-pasted across all three, which is exactly how
|
||||||
|
// one of them (a Nominatim result not being saved) silently drifted out of
|
||||||
|
// sync with the other two. Each page still owns what happens once a
|
||||||
|
// location resolves (recenter a map vs. navigate to a new URL) — that part
|
||||||
|
// genuinely differs per page — but the operations themselves live here once.
|
||||||
|
(function (window) {
|
||||||
|
var LAST_LOCATION_KEY = 'vindn:lastLocation';
|
||||||
|
|
||||||
|
function load() {
|
||||||
|
try {
|
||||||
|
var raw = window.localStorage && localStorage.getItem(LAST_LOCATION_KEY);
|
||||||
|
if (!raw) return null;
|
||||||
|
var parsed = JSON.parse(raw);
|
||||||
|
if (typeof parsed.lat === 'number' && typeof parsed.lon === 'number' && isFinite(parsed.lat) && isFinite(parsed.lon)) {
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
} catch (e) { /* localStorage disabled/unavailable, or corrupt value — just skip it */ }
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function save(lat, lon, name) {
|
||||||
|
try {
|
||||||
|
if (window.localStorage) localStorage.setItem(LAST_LOCATION_KEY, JSON.stringify({ lat: lat, lon: lon, name: name || null }));
|
||||||
|
} catch (e) { /* localStorage disabled/unavailable — nothing to persist to */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
try {
|
||||||
|
if (window.localStorage) localStorage.removeItem(LAST_LOCATION_KEY);
|
||||||
|
} catch (e) { /* localStorage disabled/unavailable */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nominatim: explicit submit only, never as-you-type — required by its
|
||||||
|
// usage policy (max ~1 req/s, no autocomplete-style querying). Every
|
||||||
|
// "search a place" form on the site should call this instead of its own
|
||||||
|
// fetch, so they all behave identically (and a fix here fixes all three).
|
||||||
|
function searchPlace(query, callbacks) {
|
||||||
|
callbacks = callbacks || {};
|
||||||
|
if (callbacks.onStart) callbacks.onStart(query);
|
||||||
|
fetch('https://nominatim.openstreetmap.org/search?format=json&limit=1&q=' + encodeURIComponent(query))
|
||||||
|
.then(function (res) { return res.json(); })
|
||||||
|
.then(function (results) {
|
||||||
|
if (!results || !results.length) {
|
||||||
|
if (callbacks.onNotFound) callbacks.onNotFound(query);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (callbacks.onFound) callbacks.onFound(parseFloat(results[0].lat), parseFloat(results[0].lon), results[0].display_name);
|
||||||
|
})
|
||||||
|
.catch(function () {
|
||||||
|
if (callbacks.onError) callbacks.onError();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Use my location" — shared so every page reports the same fixed label
|
||||||
|
// for a GPS-derived point (no reverse geocoding happens) and the same
|
||||||
|
// error/unsupported messaging.
|
||||||
|
function useMyLocation(callbacks) {
|
||||||
|
callbacks = callbacks || {};
|
||||||
|
if (!navigator.geolocation) {
|
||||||
|
if (callbacks.onUnsupported) callbacks.onUnsupported();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (callbacks.onStart) callbacks.onStart();
|
||||||
|
navigator.geolocation.getCurrentPosition(function (pos) {
|
||||||
|
if (callbacks.onFound) callbacks.onFound(pos.coords.latitude, pos.coords.longitude, 'Your location');
|
||||||
|
}, function () {
|
||||||
|
if (callbacks.onError) callbacks.onError();
|
||||||
|
}, { timeout: 8000 });
|
||||||
|
}
|
||||||
|
|
||||||
|
window.VindnLocation = {
|
||||||
|
load: load,
|
||||||
|
save: save,
|
||||||
|
clear: clear,
|
||||||
|
searchPlace: searchPlace,
|
||||||
|
useMyLocation: useMyLocation
|
||||||
|
};
|
||||||
|
})(window);
|
||||||
+58
-90
@@ -12,28 +12,9 @@
|
|||||||
// so this only matters if that ever gets forgotten.
|
// so this only matters if that ever gets forgotten.
|
||||||
var DEFAULT_CENTER = [50.9375, 6.9603];
|
var DEFAULT_CENTER = [50.9375, 6.9603];
|
||||||
|
|
||||||
// Remembers the last place a user searched/geolocated to, shared between
|
// Storage/search/GPS lookups live in window.VindnLocation (location.js,
|
||||||
// the home hero map and /map, so switching between them (or coming back
|
// loaded globally in base.html.twig) — shared with Browse Events' own
|
||||||
// later) doesn't reset to Köln and make them search again.
|
// location filter too, so all three stay in sync by construction.
|
||||||
var LAST_LOCATION_KEY = 'vindn:lastLocation';
|
|
||||||
|
|
||||||
function loadLastLocation() {
|
|
||||||
try {
|
|
||||||
var raw = window.localStorage && localStorage.getItem(LAST_LOCATION_KEY);
|
|
||||||
if (!raw) return null;
|
|
||||||
var parsed = JSON.parse(raw);
|
|
||||||
if (typeof parsed.lat === 'number' && typeof parsed.lon === 'number' && isFinite(parsed.lat) && isFinite(parsed.lon)) {
|
|
||||||
return parsed;
|
|
||||||
}
|
|
||||||
} catch (e) { /* localStorage disabled/unavailable, or corrupt value — just skip it */ }
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveLastLocation(lat, lon, name) {
|
|
||||||
try {
|
|
||||||
if (window.localStorage) localStorage.setItem(LAST_LOCATION_KEY, JSON.stringify({ lat: lat, lon: lon, name: name || null }));
|
|
||||||
} catch (e) { /* localStorage disabled/unavailable — nothing to persist to */ }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mirrors whatever setUserLocation/setSource just resolved (a searched
|
// Mirrors whatever setUserLocation/setSource just resolved (a searched
|
||||||
// place name, or nothing for GPS/a map click) into the location search
|
// place name, or nothing for GPS/a map click) into the location search
|
||||||
@@ -490,9 +471,13 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function statusForLimit() {
|
||||||
|
return limit ? ('Showing the ' + limit + ' nearest events') : 'Showing events near you';
|
||||||
|
}
|
||||||
|
|
||||||
function setUserLocation(lat, lon, statusText, placeName) {
|
function setUserLocation(lat, lon, statusText, placeName) {
|
||||||
state.userLoc = [lat, lon];
|
state.userLoc = [lat, lon];
|
||||||
saveLastLocation(lat, lon, placeName);
|
window.VindnLocation.save(lat, lon, placeName);
|
||||||
setLocationInputValue(placeName);
|
setLocationInputValue(placeName);
|
||||||
|
|
||||||
if (limit) rebuildMarkers(nearest([lat, lon], allEvents.slice(), limit));
|
if (limit) rebuildMarkers(nearest([lat, lon], allEvents.slice(), limit));
|
||||||
@@ -512,26 +497,22 @@
|
|||||||
|
|
||||||
function requestLocation(isAutoCheck) {
|
function requestLocation(isAutoCheck) {
|
||||||
var statusEl = document.getElementById('locateStatus');
|
var statusEl = document.getElementById('locateStatus');
|
||||||
if (!navigator.geolocation) {
|
window.VindnLocation.useMyLocation({
|
||||||
setLocateStatus(statusEl, 'Location not supported by your browser', true);
|
onUnsupported: function () { setLocateStatus(statusEl, 'Location not supported by your browser', true); },
|
||||||
return;
|
onStart: function () { setLocateStatus(statusEl, 'Finding you…', false); },
|
||||||
}
|
onFound: function (lat, lon, name) {
|
||||||
setLocateStatus(statusEl, 'Finding you…', false);
|
// A manual search/click may have already happened while this
|
||||||
navigator.geolocation.getCurrentPosition(function (pos) {
|
// (silent, permission-check-triggered) lookup was still resolving.
|
||||||
// A manual search/click may have already happened while this
|
if (isAutoCheck && manualLocationSet) return;
|
||||||
// (silent, permission-check-triggered) lookup was still resolving.
|
setUserLocation(lat, lon, statusForLimit(), name);
|
||||||
if (isAutoCheck && manualLocationSet) return;
|
},
|
||||||
setUserLocation(pos.coords.latitude, pos.coords.longitude, limit ? ('Showing the ' + limit + ' nearest events') : 'Showing events near you', 'Your location');
|
onError: function () { setLocateStatus(statusEl, "Couldn't get your location", true); }
|
||||||
}, function () {
|
});
|
||||||
setLocateStatus(statusEl, "Couldn't get your location", true);
|
|
||||||
}, { timeout: 8000 });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var locateBtn = document.getElementById('locateBtn');
|
var locateBtn = document.getElementById('locateBtn');
|
||||||
if (locateBtn) locateBtn.addEventListener('click', function () { manualLocationSet = true; requestLocation(false); });
|
if (locateBtn) locateBtn.addEventListener('click', function () { manualLocationSet = true; requestLocation(false); });
|
||||||
|
|
||||||
// Nominatim: explicit submit only, never as-you-type — required by its
|
|
||||||
// usage policy (max ~1 req/s, no autocomplete-style querying).
|
|
||||||
var locationForm = document.getElementById('locationSearchForm');
|
var locationForm = document.getElementById('locationSearchForm');
|
||||||
if (locationForm) {
|
if (locationForm) {
|
||||||
locationForm.addEventListener('submit', function (e) {
|
locationForm.addEventListener('submit', function (e) {
|
||||||
@@ -541,29 +522,22 @@
|
|||||||
if (!query) return;
|
if (!query) return;
|
||||||
manualLocationSet = true;
|
manualLocationSet = true;
|
||||||
var statusEl = document.getElementById('locateStatus');
|
var statusEl = document.getElementById('locateStatus');
|
||||||
setLocateStatus(statusEl, 'Looking up "' + query + '"…', false);
|
window.VindnLocation.searchPlace(query, {
|
||||||
fetch('https://nominatim.openstreetmap.org/search?format=json&limit=1&q=' + encodeURIComponent(query))
|
onStart: function () { setLocateStatus(statusEl, 'Looking up "' + query + '"…', false); },
|
||||||
.then(function (res) { return res.json(); })
|
onNotFound: function () { setLocateStatus(statusEl, 'Could not find "' + query + '"', true); },
|
||||||
.then(function (results) {
|
onFound: function (lat, lon, name) { setUserLocation(lat, lon, statusForLimit(), name); },
|
||||||
if (!results || !results.length) {
|
onError: function () { setLocateStatus(statusEl, 'Location search failed', true); }
|
||||||
setLocateStatus(statusEl, 'Could not find "' + query + '"', true);
|
});
|
||||||
return;
|
|
||||||
}
|
|
||||||
setUserLocation(parseFloat(results[0].lat), parseFloat(results[0].lon), limit ? ('Showing the ' + limit + ' nearest events') : 'Showing events near you', results[0].display_name);
|
|
||||||
})
|
|
||||||
.catch(function () {
|
|
||||||
setLocateStatus(statusEl, 'Location search failed', true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// A remembered search/geolocation takes priority over asking the
|
// A remembered search/geolocation takes priority over asking the
|
||||||
// browser again — restoring it counts as the user's own manual choice,
|
// browser again — restoring it counts as the user's own manual choice,
|
||||||
// so a slower-to-resolve auto-geolocation check below can't clobber it.
|
// so a slower-to-resolve auto-geolocation check below can't clobber it.
|
||||||
var lastLocation = loadLastLocation();
|
var lastLocation = window.VindnLocation.load();
|
||||||
if (lastLocation) {
|
if (lastLocation) {
|
||||||
manualLocationSet = true;
|
manualLocationSet = true;
|
||||||
setUserLocation(lastLocation.lat, lastLocation.lon, limit ? ('Showing the ' + limit + ' nearest events') : 'Showing events near you', lastLocation.name);
|
setUserLocation(lastLocation.lat, lastLocation.lon, statusForLimit(), lastLocation.name);
|
||||||
} else if (navigator.permissions && navigator.permissions.query) {
|
} else if (navigator.permissions && navigator.permissions.query) {
|
||||||
// If the user already granted location access (on this or an earlier
|
// If the user already granted location access (on this or an earlier
|
||||||
// visit), center on it automatically — this only *reads* the current
|
// visit), center on it automatically — this only *reads* the current
|
||||||
@@ -730,7 +704,7 @@
|
|||||||
// conservative: reload whenever full coverage isn't guaranteed,
|
// conservative: reload whenever full coverage isn't guaranteed,
|
||||||
// rather than risk silently showing an incomplete result.
|
// rather than risk silently showing an incomplete result.
|
||||||
function setSource(lat, lon, placeName) {
|
function setSource(lat, lon, placeName) {
|
||||||
saveLastLocation(lat, lon, placeName);
|
window.VindnLocation.save(lat, lon, placeName);
|
||||||
setLocationInputValue(placeName);
|
setLocationInputValue(placeName);
|
||||||
var distFromOriginal = distanceKm(originalCenter[0], originalCenter[1], lat, lon);
|
var distFromOriginal = distanceKm(originalCenter[0], originalCenter[1], lat, lon);
|
||||||
if (distFromOriginal + state.rangeKm > maxRangeKm) {
|
if (distFromOriginal + state.rangeKm > maxRangeKm) {
|
||||||
@@ -781,8 +755,6 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nominatim: explicit submit only, never as-you-type — required by
|
|
||||||
// its usage policy (max ~1 req/s, no autocomplete-style querying).
|
|
||||||
var locationForm = document.getElementById('locationSearchForm');
|
var locationForm = document.getElementById('locationSearchForm');
|
||||||
if (locationForm) {
|
if (locationForm) {
|
||||||
locationForm.addEventListener('submit', function (e) {
|
locationForm.addEventListener('submit', function (e) {
|
||||||
@@ -792,37 +764,28 @@
|
|||||||
if (!query) return;
|
if (!query) return;
|
||||||
manualLocationSet = true;
|
manualLocationSet = true;
|
||||||
var statusEl = document.getElementById('locateStatus');
|
var statusEl = document.getElementById('locateStatus');
|
||||||
setLocateStatus(statusEl, 'Looking up "' + query + '"…', false);
|
window.VindnLocation.searchPlace(query, {
|
||||||
fetch('https://nominatim.openstreetmap.org/search?format=json&limit=1&q=' + encodeURIComponent(query))
|
onStart: function () { setLocateStatus(statusEl, 'Looking up "' + query + '"…', false); },
|
||||||
.then(function (res) { return res.json(); })
|
onNotFound: function () { setLocateStatus(statusEl, 'Could not find "' + query + '"', true); },
|
||||||
.then(function (results) {
|
onFound: function (lat, lon, name) { setSource(lat, lon, name); },
|
||||||
if (!results || !results.length) {
|
onError: function () { setLocateStatus(statusEl, 'Location search failed', true); }
|
||||||
setLocateStatus(statusEl, 'Could not find "' + query + '"', true);
|
});
|
||||||
return;
|
|
||||||
}
|
|
||||||
setSource(parseFloat(results[0].lat), parseFloat(results[0].lon), results[0].display_name);
|
|
||||||
})
|
|
||||||
.catch(function () {
|
|
||||||
setLocateStatus(statusEl, 'Location search failed', true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function requestLocation(isAutoCheck) {
|
function requestLocation(isAutoCheck) {
|
||||||
var statusEl = document.getElementById('locateStatus');
|
var statusEl = document.getElementById('locateStatus');
|
||||||
if (!navigator.geolocation) {
|
window.VindnLocation.useMyLocation({
|
||||||
setLocateStatus(statusEl, 'Location not supported by your browser', true);
|
onUnsupported: function () { setLocateStatus(statusEl, 'Location not supported by your browser', true); },
|
||||||
return;
|
onStart: function () { setLocateStatus(statusEl, 'Finding you…', false); },
|
||||||
}
|
onFound: function (lat, lon, name) {
|
||||||
setLocateStatus(statusEl, 'Finding you…', false);
|
// A manual search/click/drag may have already happened while this
|
||||||
navigator.geolocation.getCurrentPosition(function (pos) {
|
// (silent, permission-check-triggered) lookup was still resolving.
|
||||||
// A manual search/click/drag may have already happened while this
|
if (isAutoCheck && manualLocationSet) return;
|
||||||
// (silent, permission-check-triggered) lookup was still resolving.
|
setSource(lat, lon, name);
|
||||||
if (isAutoCheck && manualLocationSet) return;
|
},
|
||||||
setSource(pos.coords.latitude, pos.coords.longitude, 'Your location');
|
onError: function () { setLocateStatus(statusEl, "Couldn't get your location", true); }
|
||||||
}, function () {
|
});
|
||||||
setLocateStatus(statusEl, "Couldn't get your location", true);
|
|
||||||
}, { timeout: 8000 });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var locateBtn = document.getElementById('locateBtn');
|
var locateBtn = document.getElementById('locateBtn');
|
||||||
@@ -832,21 +795,26 @@
|
|||||||
// own reload-threshold redirect, or a shared link) can't carry the
|
// own reload-threshold redirect, or a shared link) can't carry the
|
||||||
// place name in the URL — fill the field back in from localStorage
|
// place name in the URL — fill the field back in from localStorage
|
||||||
// regardless of whether that load also needs the redirect below.
|
// regardless of whether that load also needs the redirect below.
|
||||||
var savedForName = loadLastLocation();
|
var savedForName = window.VindnLocation.load();
|
||||||
if (savedForName && savedForName.name) setLocationInputValue(savedForName.name);
|
if (savedForName && savedForName.name) setLocationInputValue(savedForName.name);
|
||||||
|
|
||||||
// An explicit ?lat=/&lon= in the URL (e.g. a shared link) always wins.
|
// An explicit ?lat=/&lon= in the URL (e.g. a shared link, or this same
|
||||||
// Otherwise, a remembered search/geolocation takes priority over asking
|
// page reloading itself after setSource's own redirect) always wins —
|
||||||
// the browser again — restoring it counts as the user's own manual
|
// and, crucially, also skips the auto-geolocation check below entirely.
|
||||||
// choice, so a slower-to-resolve auto-geolocation check below can't
|
// That check used to run on *every* fresh page load regardless of the
|
||||||
// clobber it. If it's far enough from this page's own server-resolved
|
// URL, which meant searching for a place far enough to trigger the
|
||||||
// center, setSource's own reload-threshold logic kicks in as usual.
|
// redirect immediately got overwritten by GPS again the moment the
|
||||||
|
// reloaded page re-ran this same check with a clean (unset)
|
||||||
|
// manualLocationSet. Otherwise, a remembered search/geolocation takes
|
||||||
|
// priority over asking the browser again — restoring it counts as the
|
||||||
|
// user's own manual choice, so a slower-to-resolve auto-geolocation
|
||||||
|
// check can't clobber it.
|
||||||
var urlHasExplicitLocation = /[?&]lat=/.test(window.location.search);
|
var urlHasExplicitLocation = /[?&]lat=/.test(window.location.search);
|
||||||
var lastLocation = urlHasExplicitLocation ? null : savedForName;
|
var lastLocation = urlHasExplicitLocation ? null : savedForName;
|
||||||
if (lastLocation) {
|
if (lastLocation) {
|
||||||
manualLocationSet = true;
|
manualLocationSet = true;
|
||||||
setSource(lastLocation.lat, lastLocation.lon, lastLocation.name);
|
setSource(lastLocation.lat, lastLocation.lon, lastLocation.name);
|
||||||
} else if (navigator.permissions && navigator.permissions.query) {
|
} else if (!urlHasExplicitLocation && navigator.permissions && navigator.permissions.query) {
|
||||||
navigator.permissions.query({ name: 'geolocation' }).then(function (status) {
|
navigator.permissions.query({ name: 'geolocation' }).then(function (status) {
|
||||||
if (status.state === 'granted') requestLocation(true);
|
if (status.state === 'granted') requestLocation(true);
|
||||||
}).catch(function () {});
|
}).catch(function () {});
|
||||||
|
|||||||
@@ -59,6 +59,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<script src="{{ asset('js/location.js') }}"></script>
|
||||||
<script src="{{ asset('js/nav.js') }}"></script>
|
<script src="{{ asset('js/nav.js') }}"></script>
|
||||||
{% block scripts %}{% endblock %}
|
{% block scripts %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -133,27 +133,10 @@
|
|||||||
var currentLon = {{ hasLocation ? lon : 'null' }};
|
var currentLon = {{ hasLocation ? lon : 'null' }};
|
||||||
var rangeSelect = document.getElementById('rangeSelect');
|
var rangeSelect = document.getElementById('rangeSelect');
|
||||||
|
|
||||||
// Shared with the home hero map and /map (see map.js) so a search/
|
// Storage/search/GPS lookups live in window.VindnLocation (location.js,
|
||||||
// geolocation made on any of the three sticks when moving between them.
|
// loaded globally in base.html.twig) — shared with the home hero map and
|
||||||
var LAST_LOCATION_KEY = 'vindn:lastLocation';
|
// /map, so a search/geolocation made on any of the three sticks when
|
||||||
|
// moving between them.
|
||||||
function loadLastLocation() {
|
|
||||||
try {
|
|
||||||
var raw = window.localStorage && localStorage.getItem(LAST_LOCATION_KEY);
|
|
||||||
if (!raw) return null;
|
|
||||||
var parsed = JSON.parse(raw);
|
|
||||||
if (typeof parsed.lat === 'number' && typeof parsed.lon === 'number' && isFinite(parsed.lat) && isFinite(parsed.lon)) {
|
|
||||||
return parsed;
|
|
||||||
}
|
|
||||||
} catch (e) { /* localStorage disabled/unavailable, or corrupt value — just skip it */ }
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveLastLocation(lat, lon, name) {
|
|
||||||
try {
|
|
||||||
if (window.localStorage) localStorage.setItem(LAST_LOCATION_KEY, JSON.stringify({ lat: lat, lon: lon, name: name || null }));
|
|
||||||
} catch (e) { /* localStorage disabled/unavailable — nothing to persist to */ }
|
|
||||||
}
|
|
||||||
|
|
||||||
function currentRangeKm() {
|
function currentRangeKm() {
|
||||||
return rangeSelect ? parseInt(rangeSelect.value, 10) : {{ rangeKm }};
|
return rangeSelect ? parseInt(rangeSelect.value, 10) : {{ rangeKm }};
|
||||||
@@ -170,7 +153,7 @@
|
|||||||
var locInput = document.getElementById('locationSearchInput');
|
var locInput = document.getElementById('locationSearchInput');
|
||||||
name = locInput ? locInput.value : null;
|
name = locInput ? locInput.value : null;
|
||||||
}
|
}
|
||||||
saveLastLocation(lat, lon, name);
|
window.VindnLocation.save(lat, lon, name);
|
||||||
var url = new URL(window.location.href);
|
var url = new URL(window.location.href);
|
||||||
url.searchParams.set('lat', lat.toFixed(5));
|
url.searchParams.set('lat', lat.toFixed(5));
|
||||||
url.searchParams.set('lon', lon.toFixed(5));
|
url.searchParams.set('lon', lon.toFixed(5));
|
||||||
@@ -186,8 +169,6 @@
|
|||||||
el.classList.toggle('is-error', !!isError);
|
el.classList.toggle('is-error', !!isError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nominatim: explicit submit only, never as-you-type — required by its
|
|
||||||
// usage policy (max ~1 req/s, no autocomplete-style querying).
|
|
||||||
var locationForm = document.getElementById('locationSearchForm');
|
var locationForm = document.getElementById('locationSearchForm');
|
||||||
if (locationForm) {
|
if (locationForm) {
|
||||||
locationForm.addEventListener('submit', function (e) {
|
locationForm.addEventListener('submit', function (e) {
|
||||||
@@ -195,35 +176,24 @@
|
|||||||
var input = document.getElementById('locationSearchInput');
|
var input = document.getElementById('locationSearchInput');
|
||||||
var query = (input.value || '').trim();
|
var query = (input.value || '').trim();
|
||||||
if (!query) return;
|
if (!query) return;
|
||||||
setStatus('Looking up "' + query + '"…', false);
|
window.VindnLocation.searchPlace(query, {
|
||||||
fetch('https://nominatim.openstreetmap.org/search?format=json&limit=1&q=' + encodeURIComponent(query))
|
onStart: function () { setStatus('Looking up "' + query + '"…', false); },
|
||||||
.then(function (res) { return res.json(); })
|
onNotFound: function () { setStatus('Could not find "' + query + '"', true); },
|
||||||
.then(function (results) {
|
onFound: function (lat, lon, name) { navigateWithLocation(lat, lon, currentRangeKm(), name); },
|
||||||
if (!results || !results.length) {
|
onError: function () { setStatus('Location search failed', true); }
|
||||||
setStatus('Could not find "' + query + '"', true);
|
});
|
||||||
return;
|
|
||||||
}
|
|
||||||
navigateWithLocation(parseFloat(results[0].lat), parseFloat(results[0].lon), currentRangeKm(), results[0].display_name);
|
|
||||||
})
|
|
||||||
.catch(function () {
|
|
||||||
setStatus('Location search failed', true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var useMyLocationBtn = document.getElementById('useMyLocationBtn');
|
var useMyLocationBtn = document.getElementById('useMyLocationBtn');
|
||||||
if (useMyLocationBtn) {
|
if (useMyLocationBtn) {
|
||||||
useMyLocationBtn.addEventListener('click', function () {
|
useMyLocationBtn.addEventListener('click', function () {
|
||||||
if (!navigator.geolocation) {
|
window.VindnLocation.useMyLocation({
|
||||||
setStatus('Location not supported by your browser', true);
|
onUnsupported: function () { setStatus('Location not supported by your browser', true); },
|
||||||
return;
|
onStart: function () { setStatus('Finding you…', false); },
|
||||||
}
|
onFound: function (lat, lon, name) { navigateWithLocation(lat, lon, currentRangeKm(), name); },
|
||||||
setStatus('Finding you…', false);
|
onError: function () { setStatus("Couldn't get your location", true); }
|
||||||
navigator.geolocation.getCurrentPosition(function (pos) {
|
});
|
||||||
navigateWithLocation(pos.coords.latitude, pos.coords.longitude, currentRangeKm(), 'Your location');
|
|
||||||
}, function () {
|
|
||||||
setStatus("Couldn't get your location", true);
|
|
||||||
}, { timeout: 8000 });
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,9 +210,7 @@
|
|||||||
if (clearLocationLink) {
|
if (clearLocationLink) {
|
||||||
// Otherwise the restore-on-load check below would immediately undo
|
// Otherwise the restore-on-load check below would immediately undo
|
||||||
// the clear on the very next visit.
|
// the clear on the very next visit.
|
||||||
clearLocationLink.addEventListener('click', function () {
|
clearLocationLink.addEventListener('click', function () { window.VindnLocation.clear(); });
|
||||||
try { window.localStorage && localStorage.removeItem(LAST_LOCATION_KEY); } catch (e) {}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var sortSelect = document.getElementById('sortSelect');
|
var sortSelect = document.getElementById('sortSelect');
|
||||||
@@ -253,7 +221,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var saved = loadLastLocation();
|
var saved = window.VindnLocation.load();
|
||||||
|
|
||||||
// Every full reload here (search, geolocation, range change) already
|
// Every full reload here (search, geolocation, range change) already
|
||||||
// lands with an explicit ?lat=, so this doesn't overwrite it — it only
|
// lands with an explicit ?lat=, so this doesn't overwrite it — it only
|
||||||
|
|||||||
Reference in new issue
Block a user