For Manhattan and London, the manual formula and the haversine package both return 5,563.91 km. I’m intrigued that a same-point call returns 0.00 km.

You’ll turn two coordinate pairs into a Python function that returns kilometres. To make sense of its output, look at what distance the Haversine formula measures between two points on a sphere.

What the Haversine formula measures

The Haversine formula calculates the great-circle distance between two points on a sphere from their latitudes and longitudes. A great circle passes through the sphere’s centre, and its shorter arc gives the surface distance.

The haversine function of an angle θ is sin²(θ / 2). The equation uses radians for its trigonometric inputs, with φ and λ as latitude and longitude and r as the sphere’s radius in the returned unit.

The haversine function identity used in the distance formula
Haversine formula for great-circle distance between two latitude and longitude pairs
Great-circle distance from two coordinate pairs

What you need before calculating a distance

The manual function accepts decimal degrees in latitude-then-longitude order and converts them before calling Python’s trigonometric functions.

  • Python 3 and its standard library math module for the manual calculation.
  • The haversine package only if you prefer its ready-made function.
  • Valid coordinates, with latitude from -90 to 90 degrees and longitude from -180 to 180 degrees.

West longitudes use negative values. The sample below uses that sign for both Manhattan and London.

Step 1: Calculate a spherical distance with Python

This function takes four decimal-degree values and returns kilometres using the mean Earth radius documented by GeoPy.

python3 - <<'PY'
import math


def haversine_distance(lat1, lon1, lat2, lon2):
    if not (-90 <= lat1 <= 90 and -90 <= lat2 <= 90):
        raise ValueError("latitudes must be between -90 and 90 degrees")
    if not (-180 <= lon1 <= 180 and -180 <= lon2 <= 180):
        raise ValueError("longitudes must be between -180 and 180 degrees")

    earth_radius_km = 6371.0088
    latitude_1 = math.radians(lat1)
    latitude_2 = math.radians(lat2)
    delta_latitude = math.radians(lat2 - lat1)
    delta_longitude = math.radians(lon2 - lon1)
    a = (
        math.sin(delta_latitude / 2) ** 2
        + math.cos(latitude_1)
        * math.cos(latitude_2)
        * math.sin(delta_longitude / 2) ** 2
    )
    a = min(1.0, max(0.0, a))
    central_angle = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    return earth_radius_km * central_angle


manhattan = (40.7772, -73.9661)
london = (51.4847, -0.1279)
distance_km = haversine_distance(*manhattan, *london)
print(f"{distance_km:.2f} km")
PY

The function validates latitude and longitude separately, then converts the coordinate differences and both latitudes to radians. Python’s trigonometric functions expect radians, which is why the conversion happens before the formula.

I tested latitude 91 and longitude -181. Each raised ValueError before the formula ran, so the coordinate bounds stop invalid inputs early.

The value a is the haversine of the central angle, and atan2 with the square roots recovers that angle before the radius turns it into kilometres.

Floating-point rounding can put a just outside its mathematical interval, so the clamp keeps square-root inputs valid. Python’s math functions provide the radians conversion and trigonometric operations used here.

Step 2: Use the haversine package

If you do not need to maintain the formula yourself, the haversine package accepts coordinate tuples in latitude-longitude order and decimal degrees.

python3 -m venv .venv
source .venv/bin/activate
python -m pip install haversine

Pass the unit explicitly so the returned number has a visible meaning in the code.

from haversine import haversine, Unit

manhattan = (40.7772, -73.9661)
london = (51.4847, -0.1279)
distance_km = haversine(manhattan, london, unit=Unit.KILOMETERS)
print(f"{distance_km:.2f} km")
Unit value Returned measurement
Unit.KILOMETERS kilometres
Unit.MILES miles

The package accepts decimal-degree coordinate tuples and checks their ranges, according to its PyPI documentation. The manual function converts its degree inputs to radians before the trigonometric calculations.

To compare the Haversine formula with other Python methods, read our overview of calculating distance between two geo-locations.

Check both calculations against the same points

For the Manhattan and London coordinates above, I ran both implementations and got 5,563.91 km from each. A same-point call returned 0.00 km.

This command prints the package result from the same coordinate pair. The terminal capture shows 5563.91 km, which matches the math implementation.

source .venv/bin/activate && python -c 'from haversine import haversine, Unit; manhattan = (40.7772, -73.9661); london = (51.4847, -0.1279); print(f"{haversine(manhattan, london, unit=Unit.KILOMETERS):.2f} km")'
Terminal output showing the Haversine distance between Manhattan and London as 5,563.91 km
The package returns the distance in kilometres for the supplied coordinate pair.

Know when a spherical distance is not enough

Haversine distance follows a great-circle arc on a sphere. Choose an ellipsoidal geodesic when that Earth model affects your result, and a routing service for street distance.

Question Choose
How far apart are two points on a sphere? Haversine distance
Does ellipsoidal Earth modelling affect the result? An ellipsoidal geodesic, such as GeoPy’s geodesic distance
How far does a vehicle travel along streets? A route distance from a routing service

GeoPy’s distance documentation identifies its great-circle calculation as spherical and its geodesic calculation as ellipsoidal, so select the model that matches your measurement.

Keep the coordinate order beside the call

Keep each point in latitude-then-longitude order, then request the measurement unit you need before rounding the result.

from haversine import haversine, Unit

manhattan = (40.7772, -73.9661)
london = (51.4847, -0.1279)
distance_miles = haversine(manhattan, london, unit=Unit.MILES)
print(f"{distance_miles:.2f} miles")

Haversine function FAQs

Do latitude and longitude need to be in radians?

The manual Python formula converts decimal degrees with math.radians before using trigonometric functions. The haversine package accepts coordinate tuples in decimal degrees.

Does the haversine function return kilometres?

The manual implementation returns kilometres because its Earth radius is measured in kilometres. For the package, set unit=Unit.KILOMETERS explicitly when you want kilometres.

Can I use Haversine distance for a road journey?

Haversine returns the great-circle distance over a sphere. Use a routing service when you need street distance.

Share.
Leave A Reply