Skip to content

Instantly share code, notes, and snippets.

@leodutra
Last active April 7, 2022 08:17
Show Gist options
  • Save leodutra/d9802ae7b1de2e31fe46b1a078d1cc6b to your computer and use it in GitHub Desktop.
Save leodutra/d9802ae7b1de2e31fe46b1a078d1cc6b to your computer and use it in GitHub Desktop.
useDistance - Hook to simplify distance measurement (Geo)
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