Sort bank branches by distance from the user's location using the Geolocation API and the Haversine formula, with no libraries.
Every location directory eventually needs a "find the nearest one" feature. You do not need Google Maps or a heavy library for it. The Geolocation API and one small formula are enough.
I used this approach on a Chase Bank branch directory I maintain, where each branch has coordinates and users want the closest one first.
The data
const branches = [
{ name: "Chase Bank, Dallas", lat: 32.9, lng: -96.77 },
{ name: "Chase Bank, Katy", lat: 29.79, lng: -95.82 },
{ name: "Chase Bank, Chicago", lat: 41.97, lng: -87.72 },
];
The Haversine formula
It calculates the distance between two points on a sphere.
const EARTH_RADIUS_MILES = 3958.8;
const toRad = (deg) => (deg * Math.PI) / 180;
function distanceMiles(a, b) {
const dLat = toRad(b.lat - a.lat);
const dLng = toRad(b.lng - a.lng);
const h =
Math.sin(dLat / 2) ** 2 +
Math.cos(toRad(a.lat)) * Math.cos(toRad(b.lat)) * Math.sin(dLng / 2) ** 2;
return 2 * EARTH_RADIUS_MILES * Math.asin(Math.sqrt(h));
}
Sort by distance
function sortByDistance(userPos, items) {
return items
.map((item) => ({ ...item, distance: distanceMiles(userPos, item) }))
.sort((a, b) => a.distance - b.distance);
}
Get the user's location
navigator.geolocation.getCurrentPosition(
(pos) => {
const user = { lat: pos.coords.latitude, lng: pos.coords.longitude };
const nearest = sortByDistance(user, branches).slice(0, 5);
console.table(nearest);
},
(err) => console.warn("Location denied:", err.message),
{ enableHighAccuracy: false, timeout: 8000 }
);
Tips
- Always handle the denied-permission case and fall back to a city search.
- Geolocation only works on HTTPS.
- Haversine is accurate enough for straight-line distance. For driving distance you need a routing API.
- With thousands of points, filter by a bounding box first, then run Haversine on the survivors.
That is all it takes. Happy building!
Top comments (0)