Decide what “nearby” means

Before adding “nearest first” to a directory, decide which distance it means. A spherical distance can compare nearby places, but it does not follow streets, crossings, or building entrances. A store across a river can look close while requiring a long walk.

The local BAKUO source contains a Haversine function in demo/src/utils/haversine.ts. This independent teaching example uses that approach and adds input validation and a numeric clamp. It does not reproduce the deployed service or establish its performance.

Give coordinate values names

Latitude and longitude are angles. Applying a flat right-triangle formula directly to their differences ignores how east–west spacing changes with latitude. Convert degrees to radians before applying the spherical formula.

Check coordinate order at each boundary: a GeoJSON position is longitude first, while Leaflet LatLng accepts latitude first. Named { lat, lng } fields make the example easier to review. Zero is a valid coordinate and must not be treated as missing.

Run the calculation

Paste the complete block into a current browser console or Node.js. The points are synthetic inputs, not store locations. The model assumes a sphere of radius 6,371km and returns kilometres.

function distanceKm(a, b) {
  for (const point of [a, b]) {
    if (!point || !Number.isFinite(point.lat) || !Number.isFinite(point.lng)) {
      throw new TypeError('Expected numeric lat and lng');
    }
    if (Math.abs(point.lat) > 90 || Math.abs(point.lng) > 180) {
      throw new RangeError('Coordinates outside latitude/longitude range');
    }
  }
  const rad = degrees => degrees * Math.PI / 180;
  const dLat = rad(b.lat - a.lat);
  const dLng = rad(b.lng - a.lng);
  const raw = Math.sin(dLat / 2) ** 2
    + Math.cos(rad(a.lat)) * Math.cos(rad(b.lat))
    * Math.sin(dLng / 2) ** 2;
  const h = Math.min(1, Math.max(0, raw));
  return 6371 * 2 * Math.atan2(Math.sqrt(h), Math.sqrt(1 - h));
}

const a = { lat: 0, lng: 0 };
const b = { lat: 0, lng: 1 };
console.log(distanceKm(a, a)); // 0
console.log(distanceKm(a, b).toFixed(3)); // 111.195

The outputs are 0 and 111.195. The latter is this model’s result for two points one degree apart along the equator, not a verified ellipsoidal or walking distance.

Check valid and invalid inputs

  1. Identical points should produce zero.
  2. Reversing the arguments should preserve the distance.
  3. { lat: "0", lng: 1 } should throw TypeError because the latitude is a string.
  4. { lat: 127, lng: 37 } should throw RangeError because latitude is outside its range.

Valid numeric ranges do not establish that a coordinate belongs to the intended store. Some reversed pairs still fit the ranges. Format checks cannot replace checking the source location.

Use a map for the journey

Label the list value as a straight-line distance and let a mapping service provide the journey. Multiplying it by an arbitrary factor does not produce a reliable walking distance or arrival time. Routing needs transport mode and a road network.

A missing coordinate should produce “distance unavailable,” not zero kilometres. A genuine point at the origin may legitimately have zero distance. Continue with building external map links to pass a destination to a mapping service.

BAKUO · How to use →