## Calculate the GPS Distance with the Haversine Formula

* Dan Couture [@MathYourLife](https://twitter.com/MathYourLife), [github](https://github.com/MathYourLife)
* 2015-03-05

### Problem

I've got the start and end gps location from an excursion across town and need to determine the travel distance

    start: 43.059535, -71.013171
    end:   43.083620, -70.892085

You could always use [google maps](https://www.google.com/maps/dir/43.059535,+-71.013171/%2743.08361,-70.89202%27/), but that would just be cheating.

### Haversine Formula

The goal for this formula is to calculate the shortest great circle distance between two points on the globe designated by latitude and longitudes.  The added benefit of the Haversine equation is that it calculates the central angle as well where $s = r\theta$.


source: https://software.intel.com/sites/default/files/great%20circle.png

The Haversine formula is mainly based on calculation of the central angle, $\theta$, between two gps coordinates.  Using the formula for arc length on a sphere

$$
s = r \theta
$$

where $r$ is the Earth's radius, and $\theta$ is the central angle calculated as

$$
\theta = 2 \arcsin\left( \sqrt{\sin^2 \left(\frac{\phi_2-\phi_1}{2}\right) + \cos(\phi_1)\cos(\phi_2)\sin^2 \left( \frac{\lambda_2-\lambda_1}{2} \right) } \right)
$$

with:

$$
\begin{align}
\phi &= \text{latitude}\\
\lambda &= \text{longitude}\\
\end{align}
$$


```python
import numpy as np
import math

# Mean radius of the earth
EARTH_RADIUS = 6371.009

def haversine(lat1, lon1, lat2, lon2):
    """
    Calculate the great circle distance between two points
    on the earth (specified in decimal degrees)
    
    Return (central angle, distance between points in km)
    """
    # convert decimal degrees to radians
    lat1, lon1, lat2, lon2 = [math.radians(x) for x in [lat1, lon1, lat2, lon2]]

    # haversine formula
    dlon = lon2 - lon1
    dlat = lat2 - lat1
    
    a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2
    central_angle = 2 * math.asin(math.sqrt(a))

    # s = r * theta
    km = EARTH_RADIUS * central_angle
    return (central_angle, km)
```

### Calculate Excursion Distance


```python
start = (43.059535, -71.013171)
end = (43.083620, -70.892085)

central_angle, km = haversine(*(start + end))

print("Central Angle of %g radians" % central_angle)
print("Arc length distance of %g km" % km)
```

    Central Angle of 0.00160001 radians
    Arc length distance of 10.1937 km


### Earth is not a sphere

The Haversine is a straight forward formula that provides an approximation for the distance between gps coordinates.  The Earth of course is not spherical, and elevation changes including terrain profiles will increase actual distance traveled.

## References:

* http://www.gcmap.com/faq/gccalc#ellipsoid
* http://stackoverflow.com/questions/4913349/haversine-formula-in-python-bearing-and-distance-between-two-gps-points/4913653#4913653
* http://www.gcmap.com/mapui?P=DXB-SFO%2CBINP&PM=b%3Adisc7%2B%25U%2Cp%3Adisc7%2B%25N&MS=wls&PW=2&DU=km

23ed8de7779ba3f012e8bfdad8f2a7c2a4e52e4e
ipynb
Jupyter Notebook
Haversine/Haversine.ipynb
MathYourLife/spouting-jibberish
d90aa1da0cc0e5dd463e3ec8ec43878f1e810079
MIT
2015-01-02T20:38:32.000Z
2015-01-02T20:38:32.000Z
Haversine/Haversine.ipynb
MathYourLife/spouting-jibberish
d90aa1da0cc0e5dd463e3ec8ec43878f1e810079
MIT
Haversine/Haversine.ipynb
MathYourLife/spouting-jibberish
d90aa1da0cc0e5dd463e3ec8ec43878f1e810079
MIT
Qwen/Qwen-72B
1. YES
2. YES