HOME ARCHIVE TAGS ABOUT RSS

Calculating the Distance Between Two GPS Coordinates with Python (Haversine Formula)

A lot of my posts recently have focused on the analysis of spacial data coming from either the GPS on my phone (collected through Strava) or geo-tagged tweets. Because of this I ended up writing my own Python module for calculating the distance between two latitude/longitude pairs. This is accomplished using the Haversine formula. While more accurate methods exist for calculating the distance between two points on earths surface, the Haversine formula and Python implementation couldn’t be any simpler. Below is a breakdown of the Haversine formula.

Haversine:

$$ a=\sin^2\left(\frac{\Delta\phi}{2}\right) +\cos(\phi_1)\cdot\cos(\phi_2)\cdot\sin^2\left(\frac{\Delta\lambda}{2}\right)$$

With:

$$ c=2\cdot arctan2\left(\sqrt{a},\sqrt{1-a}\right) $$

and:

$$ d=R\cdot c $$

Where:

\( \phi \) = latitude
\( \lambda \) = longitude
\( R \) = 6371 (Earth’s mean radius in km)

Much of Haverines’ simplicity comes from the underlying assumption that Earth is a perfect sphere (which it isn’t…). This can lead to errors of up to 0.5%. But for the type of work I have been doing recently, that’s just fine. More accurate methods exist. Below is the Python implementation:

#------------------------------------------------------------------------------+
#
#   Nathan A. Rooy
#   Haversine Formula
#   June, 2016
#
#------------------------------------------------------------------------------+

import math

class Haversine:
    '''
    use the haversine class to calculate the distance between
    two lon/lat coordnate pairs.
    output distance available in kilometers, meters, miles, and feet.
    example usage: Haversine([lon1,lat1],[lon2,lat2]).feet
    
    '''
    def __init__(self,coord1,coord2):
        lon1,lat1=coord1
        lon2,lat2=coord2
        
        R=6371000                               # radius of Earth in meters
        phi_1=math.radians(lat1)
        phi_2=math.radians(lat2)

        delta_phi=math.radians(lat2-lat1)
        delta_lambda=math.radians(lon2-lon1)

        a=math.sin(delta_phi/2.0)**2+\
           math.cos(phi_1)*math.cos(phi_2)*\
           math.sin(delta_lambda/2.0)**2
        c=2*math.atan2(math.sqrt(a),math.sqrt(1-a))
        
        self.meters=R*c                         # output distance in meters
        self.km=self.meters/1000.0              # output distance in kilometers
        self.miles=self.meters*0.000621371      # output distance in miles
        self.feet=self.miles*5280               # output distance in feet

if __name__ == "__Haversine__":
    main()

Example usage:

>>> import haversine
>>> Haversine([-84.412977,39.152501],[-84.412946,39.152505]).feet 
8.890493621837097

>>> Haversine((-84.412977,39.152501),(-84.412946,39.152505)).feet 
8.890493621837097

>>> Haversine((-84.412977,39.152501),(-84.412946,39.152505)).km 
0.0027098232942902385

>>> Haversine((-84.412977,39.152501),(-84.412946,39.152505)).miles 
0.00168380561019642

Note haversine script accepts the coordinates in both tuple “()” and list “[]” form. Additionally, the script can be downloaded from my GitHub located (here).