From da7a0aa5d6602e49645819db7286cf74cfae702e Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Wed, 2 Oct 2019 19:23:45 +0100 Subject: [PATCH] Update distanceBetweenCoordinates --- src/util.js | 36 +++++++++++++++++++++--------------- tests/util.test.js | 6 +++--- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/util.js b/src/util.js index c9b0747..d934cf1 100644 --- a/src/util.js +++ b/src/util.js @@ -35,27 +35,33 @@ export const isIsoDate = s => ISO_DATE_REGEXP.test(s); export const degreesToRadians = degrees => (degrees * Math.PI) / 180; /** - * Calculate the distance between two coordinates. - * https://stackoverflow.com/a/365853/5952681 + * Calculate the distance between two coordinates. Uses the haversine formula, + * which is not 100% accurate - but that's not the goal here. + * + * https://en.wikipedia.org/wiki/Haversine_formula * * @param {Coordinate} c1 First coordinate * @param {Coordinate} c2 Second coordinate * @return {Number} Distance in meters */ export const distanceBetweenCoordinates = (c1, c2) => { - const latDistanceInRad = degreesToRadians(c1.lat - c2.lat); - const lngDistanceInRad = degreesToRadians(c1.lng - c2.lng); - const lat1InRad = degreesToRadians(c1.lat); - const lat2InRad = degreesToRadians(c2.lat); - const a = - Math.sin(latDistanceInRad / 2) * Math.sin(latDistanceInRad / 2) + - Math.sin(lngDistanceInRad / 2) * - Math.sin(lngDistanceInRad / 2) * - Math.cos(lat1InRad) * - Math.cos(lat2InRad); - const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - // Return distance in meters - return EARTH_RADIUS_IN_KM * c * 1000; + const r = EARTH_RADIUS_IN_KM * 1000; + const phi1 = degreesToRadians(c1.lat); + const phi2 = degreesToRadians(c2.lat); + const lambda1 = degreesToRadians(c1.lng); + const lambda2 = degreesToRadians(c2.lng); + const d = + 2 * + r * + Math.asin( + Math.sqrt( + Math.sin((phi2 - phi1) / 2) ** 2 + + Math.cos(phi1) * + Math.cos(phi2) * + Math.sin((lambda2 - lambda1) / 2) ** 2 + ) + ); + return d; }; /** diff --git a/tests/util.test.js b/tests/util.test.js index f897052..3fbf571 100644 --- a/tests/util.test.js +++ b/tests/util.test.js @@ -71,7 +71,7 @@ describe("distanceBetweenCoordinates", () => { { lat: 51.501752, lng: -0.1408258 } ) // 3.74km according to Google Maps - ).toBe(3734.363267904623); + ).toBe(3734.3632679046705); // Gatwick Airport - Heathrow Airport expect( @@ -80,7 +80,7 @@ describe("distanceBetweenCoordinates", () => { { lat: 51.4720694, lng: -0.4499871 } ) // 40km according to Google Maps - ).toBe(40321.45758693094); + ).toBe(40321.457586930104); // Berlin - San Francisco expect( @@ -89,6 +89,6 @@ describe("distanceBetweenCoordinates", () => { { lat: 37.7576948, lng: -122.4726193 } ) // 9,102.73km according to Google Maps - ).toBe(9105627.810109459); + ).toBe(9105627.810109457); }); });