calculate great circle distance between two points in a sphere given longitudes and latitudes https en wikipedia orgwikihaversineformula we know that the globe is sort of spherical so a path between two points isn t exactly a straight line we need to account for the earth s curvature when calculating distance from point a to b this effect is negligible for small distances but adds up as distance increases the haversine method treats the earth as a sphere which allows us to project the two points a and b onto the surface of that sphere and approximate the spherical distance between them since the earth is not a perfect sphere other methods which model the earth s ellipsoidal nature are more accurate but a quick and modifiable computation like haversine can be handy for shorter range distances args lat1 lon1 latitude and longitude of coordinate 1 lat2 lon2 latitude and longitude of coordinate 2 returns geographical distance between two points in metres from collections import namedtuple point2d namedtuplepoint2d lat lon sanfrancisco point2d37 774856 122 424227 yosemite point2d37 864742 119 537521 fhaversinedistancesanfrancisco yosemite 0 0f meters 254 352 meters constants per wgs84 https en wikipedia orgwikiworldgeodeticsystem distance in metresm equation parameters equation https en wikipedia orgwikihaversineformulaformulation equation square both values calculate great circle distance between two points in a sphere given longitudes and latitudes https en wikipedia org wiki haversine_formula we know that the globe is sort of spherical so a path between two points isn t exactly a straight line we need to account for the earth s curvature when calculating distance from point a to b this effect is negligible for small distances but adds up as distance increases the haversine method treats the earth as a sphere which allows us to project the two points a and b onto the surface of that sphere and approximate the spherical distance between them since the earth is not a perfect sphere other methods which model the earth s ellipsoidal nature are more accurate but a quick and modifiable computation like haversine can be handy for shorter range distances args lat1 lon1 latitude and longitude of coordinate 1 lat2 lon2 latitude and longitude of coordinate 2 returns geographical distance between two points in metres from collections import namedtuple point_2d namedtuple point_2d lat lon san_francisco point_2d 37 774856 122 424227 yosemite point_2d 37 864742 119 537521 f haversine_distance san_francisco yosemite 0 0f meters 254 352 meters constants per wgs84 https en wikipedia org wiki world_geodetic_system distance in metres m equation parameters equation https en wikipedia org wiki haversine_formula formulation equation square both values
from math import asin, atan, cos, radians, sin, sqrt, tan

AXIS_A = 6378137.0
AXIS_B = 6356752.314245
RADIUS = 6378137


def haversine_distance(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
    
    
    
    
    
    flattening = (AXIS_A - AXIS_B) / AXIS_A
    phi_1 = atan((1 - flattening) * tan(radians(lat1)))
    phi_2 = atan((1 - flattening) * tan(radians(lat2)))
    lambda_1 = radians(lon1)
    lambda_2 = radians(lon2)
    
    sin_sq_phi = sin((phi_2 - phi_1) / 2)
    sin_sq_lambda = sin((lambda_2 - lambda_1) / 2)
    
    sin_sq_phi *= sin_sq_phi
    sin_sq_lambda *= sin_sq_lambda
    h_value = sqrt(sin_sq_phi + (cos(phi_1) * cos(phi_2) * sin_sq_lambda))
    return 2 * RADIUS * asin(h_value)


if __name__ == "__main__":
    import doctest

    doctest.testmod()