UNPKG

s-haversine

Version:

Get distance between any two latitute/longitude coordinates

72 lines (55 loc) 1.72 kB
/** * [Latitude, Longitude] */ export type Coords = [number, number]; /** * Convert degrees to radians */ export function degreesToRadians(deg: number) { return deg * (Math.PI / 180); } /** * Convert dms (degrees/minutes/seconds) string to decimal degrees * toDecimal(`40 20 50W`) => -40.34722 * toDecimal(`40°20'50" S`) => -40.34722 */ export function dmsToDecimal(str: string) { const lastChar = str.slice(-1).toLowerCase(); let negative = false; // south and west => negative if (lastChar === 'w' || lastChar === 's') negative = true; // convert strings to numbers const values = str .split(/[^0-9.]/) .filter((x) => x !== '') // remove empty values .map((x) => parseFloat(x)); // make sure array has length 3 for (let i = 0; i < 3; i++) { values[i] = values[i] || 0; } const result = values[0] + (values[1] / 60) + (values[2] / 3600); return negative ? -result : result; } const haversine = { /** * Configurable earthRadius (in meters) */ earthRadius: 6371000, /** * Get distance between two points */ distance(coords1: Coords, coords2: Coords) { const [lat1, lon1] = coords1; const [lat2, lon2] = coords2; const latitudeDifference = degreesToRadians(lat2 - lat1); const logitudeDifference = degreesToRadians(lon2 - lon1); const n = Math.sin(latitudeDifference / 2) * Math.sin(latitudeDifference / 2) + Math.cos(degreesToRadians(lat1)) * Math.cos(degreesToRadians(lat2)) * Math.sin(logitudeDifference / 2) * Math.sin(logitudeDifference / 2); const distance = 2 * Math.atan2(Math.sqrt(n), Math.sqrt(1 - n)); return this.earthRadius * distance; }, dmsToDecimal }; export default haversine;