Examining the Haversine formula - Michael Sanders 2016
SYNOPSIS
Looking for a way to calculate distance, I discovered the Haversine formula
which as it turns out, is indeed a good way to measure 'straight line'
distances. And because awk is an interpreted rather than compiled language,
I was able to test this formula quickly before deploying its use in other
languages, reducing write/compile/debug times...
So far, I've measured the accuracy of the equation against a single
source[i], but the results are close enough that I consider the awk
function as 'ready to use'. Most of my reading on the subject is based on
an article at NYU titled 'Computing Distances'[ii].
BACKGROUND
The Haversine formula is an equation important in navigation, giving great-
circle distances between two points on a sphere from their longitudes and
latitudes. It is a special case of a more general formula in spherical
trigonometry, the law of haversines, relating the sides and angles of
spherical triangles. The first table of haversines in English was published
by James Andrew in 1805[iii].
HAVERSINE FORMULA
Here's the formula as published by R.W. Sinnott in 1984[iv]...
dlon = lon2 - lon1
dlat = lat2 - lat1
a = (sin(dlat / 2)) ^ 2 + cos(lat1) * cos(lat2) * (sin(dlon / 2)) ^ 2
c = 2 * arcsin(min(1, sqrt(a)))
d = R * c
where R is the radius of the Earth
CAVEAT
What the equation can not account for is variation in terrain such as a
mountain or valley...
For instance: Driving a car from point A to point B along the planet's
surface, the distance traveled would be greater than flying a plane between
the same two points. This straight line method of reckoning, 'as the crow
flies' or 'a beeline', means the distance between two points will tend to
be somewhat shorter. In any event, the equation calculates approximate
values only.
Another item affecting accuracy is the input radius. Below, I've used
earth's radius at the equator for no other reason than being easy to
visualize.
AWK SCRIPT
# Haversine formula as implemented in awk
# v1.00 - Michael Sanders 2016 <
www.peanut-software.com>
# based on the equation by R.W. Sinnott
# invocation; awk -f haversine.awk
BEGIN{
# city | latitude | longitude
# nyc | 40.71278 | -74.00594
# la | 34.05223 | -118.24368
rkm = 6371; # avg. radius of earth at equator in kilometers
rmi = 3959; # avg. radius of earth at equator in miles
dkm = haversine(rkm, 34.05223, -118.24368, 40.71278, -74.00594);
dmi = haversine(rmi, 34.05223, -118.24368, 40.71278, -74.00594);
printf("%s%s\n", "distance in kilometers from la to nyc: ", dkm);
printf("%s%s\n", "distance in miles from la to nyc: ", dmi);
}
function haversine(radius, lat1, lon1, lat2, lon2) {
deglon = lon2 - lon1;
deglat = lat2 - lat1;
a = (sin(deglat/2))^2 + cos(lat1) * cos(lat2) * (sin(deglat/2))^2;
c = 2 * atan2(sqrt(a), sqrt(1-a));
return (radius * c);
}
# eof
NOTES
i. <
http://www.distancefromto.net/distance-from-new-york-to-los-angeles-us>
ii. <
http://www.cs.nyu.edu/visual/home/proj/tiger/gisfaq.html>
iii. <
https://en.wikipedia.org/wiki/Haversine_formula>
iv. Virtues of the Haversine: Sky and Telescope, vol. 68, no. 2,
1984 - R.W. Sinnott
LICENSE
[c]2016 Michael Sanders. Reprint freely so long as nothing is modified.
--
Mike Sanders
www.peanut-software.com