Last active
April 7, 2022 08:17
-
-
Save leodutra/d9802ae7b1de2e31fe46b1a078d1cc6b to your computer and use it in GitHub Desktop.
useDistance - Hook to simplify distance measurement (Geo)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useMemo } from 'react' | |
type GeoLocation = { | |
latitude: number | |
longitude: number | |
} | |
export const useDistance = (pointA?: GeoLocation, pointB?: GeoLocation) => | |
useMemo(() => { | |
const isValid = x => x != null && isFinite(x) | |
if ( | |
!( | |
isValid(pointA?.latitude) && | |
isValid(pointA?.longitude) && | |
isValid(pointB?.latitude) && | |
isValid(pointB?.longitude) | |
) | |
) { | |
return null | |
} | |
const deg2rad = (deg: number) => deg * (Math.PI / 180) | |
const kmToMiles = (km: number) => km / 1.609344 | |
const latA = pointA?.latitude ?? 0 | |
const lonA = pointA?.longitude ?? 0 | |
const latB = pointB?.latitude ?? 0 | |
const lonB = pointB?.longitude ?? 0 | |
const equatorialRadius = 6371 // Radius of the earth in km | |
const dLat = deg2rad(latB - latA) // deg2rad below | |
const dLon = deg2rad(lonB - lonA) | |
const a = | |
Math.sin(dLat / 2) * Math.sin(dLat / 2) + | |
Math.cos(deg2rad(latA)) * Math.cos(deg2rad(latB)) * Math.sin(dLon / 2) * Math.sin(dLon / 2) | |
const angle = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) | |
const distanceKm = equatorialRadius * angle // Distance in km | |
return kmToMiles(distanceKm) | |
}, [pointA?.latitude, pointA?.longitude, pointB?.latitude, pointB?.longitude]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment