geo
Geospatial capability pack: great-circle distance (haversine), initial bearing, destination point from bearing+distance, midpoint, a center+radius bounding box, geohash encode/decode, DMS<->decimal...
geo (adapter system)
Geospatial capability pack — pure spherical-earth (WGS-84 mean radius, 6371.0088 km) math with zero dependencies. Every tool takes ONE args object; lat/lon/bearing are degrees at the boundary.
Tools (adapters)
| tool | args | result |
|---|---|---|
haversine | { from:{lat,lon}, to:{lat,lon}, unit='km' } | { distance, distanceMeters, unit, ... } — great-circle distance |
bearing | { from, to } | { bearing, finalBearing } — initial (and final) bearing in degrees |
destination | { from, bearing, distance, unit='km' } | { lat, lon } at that bearing/distance |
midpoint | { from, to } | { lat, lon } — great-circle midpoint |
boundingBox | { center:{lat,lon}, radius, unit='km' } | { minLat, minLon, maxLat, maxLon } |
geohashEncode | { lat, lon, precision=9 } | { hash } |
geohashDecode | { hash } | { lat, lon, latError, lonError, bounds } |
dmsToDecimal | { dms } | { lat, lon } |
decimalToDms | { lat, lon } | { latDms, lonDms, formatted } |
pointInPolygon | { point:{lat,lon}, polygon:[[lat,lon],...] } | { inside } (boolean, ray casting) |
normalizeLon | { lon } | { lon } wrapped into (-180, 180] |
clampLat | { lat } | { lat } clamped to [-90, 90] |
Distance unit is one of km (default), mi, m, nmi.
Usage
import geo from './index.js';
geo.adapters.haversine({ from: { lat: 51.5074, lon: -0.1278 }, to: { lat: 48.8566, lon: 2.3522 } });
// → { distance: 343.55…, distanceMeters: 343556…, unit: 'km', ... } (London → Paris ≈ 343 km)
geo.adapters.pointInPolygon({ point: { lat: 5, lon: 5 }, polygon: [[0,0],[0,10],[10,10],[10,0]] });
// → { inside: true, vertices: 4 }
DRY boundary note
geo.boundingBox here is CENTER + RADIUS → box (the enclosing min/max lat/lon around a center point within a given radius). This is deliberately DIFFERENT from a-transformation's geo.bbox, which computes a bounding box FROM A SET OF POINTS (the tight envelope of a point cloud). Same word "bounding box", different inputs and different job — pick the right one and keep them separate. Coordinate formatting/conversion beyond DMS<->decimal is out of scope here.