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.

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")'

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.

