When working with geographic data in Python, calculating the distance between two points on Earth is a common task. But not all methods are created equal!
Hereβs a quick guide to the most popular approaches and why geopy.geodesic is often the best choice β especially if you're working on Django, GIS, or logistics platforms.
π« 1. The Pitfall: Euclidean Distance
Some libraries (or naive code) use the Pythagorean theorem to compute distance between lat/lng pairs:
# β Not recommended for geographic coordinates!
from math import sqrt
def euclidean_distance(coord1, coord2):
return sqrt((coord1[0] - coord2[0])**2 + (coord1[1] - coord2[1])**2)
π Problem:
The Earth is not flat. This method ignores the planetβs curvature, so it becomes wildly inaccurate as distances grow.
π 2. The Spherical Law of Cosines & Haversine Formula
These formulas treat the Earth as a perfect sphere:
# β
Haversine example
from math import radians, sin, cos, sqrt, atan2
def haversine(coord1, coord2):
R = 6371000 # Earth radius in meters
lat1, lon1 = map(radians, coord1)
lat2, lon2 = map(radians, coord2)
dlat = lat2 - lat1
dlon = lon2 - lon1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * atan2(sqrt(a), sqrt(1-a))
return R * c
β Pros:
- Fast and easy to implement
- Useful for short distances or internal tools
β οΈ Cons:
- Assumes a spherical Earth β slight errors (~0.5%) creep in, especially on longer distances
π₯ 3. The Gold Standard: geopy.geodesic
from geopy.distance import geodesic
coord1 = (40.748817, -73.985428) # NYC
coord2 = (34.052235, -118.243683) # LA
distance = geodesic(coord1, coord2).meters
print(f"Distance: {distance:.2f} meters")
π Pros:
- Uses WGS-84 ellipsoid, same as GPS
- Very accurate, used in professional mapping tools
- Simple, human-friendly API
β οΈ Cons:
- Slightly slower than Haversine, but the difference is usually negligible
π§Ό 4. Cleaner Code with Point Objects (e.g. in Django)
If you're working with Django GIS or GEOS, youβll likely deal with Point objects:
from django.contrib.gis.geos import Point
from geopy.distance import geodesic
point1 = Point(-73.985428, 40.748817) # (lng, lat)
point2 = Point(-118.243683, 34.052235)
# geopy expects (lat, lng)
coord1 = (point1.y, point1.x)
coord2 = (point2.y, point2.x)
distance = geodesic(coord1, coord2).meters
β Tip: Always check coordinate order!
Pointstores as (longitude, latitude)
geopy.geodesicexpects (latitude, longitude)
β When Should You Use Each?
| Method | Earth Model | Accuracy | Use Case |
|---|---|---|---|
| Euclidean | Flat | β Poor | Never |
| Haversine/Cosines | Sphere | β Good | Quick estimates |
| geopy.geodesic | WGS-84 Ellipsoid | β β β Excellent | Logistics, GPS apps, GIS |
| Point + geopy | WGS-84 Ellipsoid | β β β Excellent | Django, cleaner code |
π TL;DR
- π Earth is not flat β ditch Euclidean!
- βοΈ Use Haversine for fast, rough estimates
- π§ Use
geopy.geodesicfor production-grade accuracy - π§Ό Combine it with
Pointobjects for cleaner, Django-friendly code
π¬ Have you used geopy or built a GPS-based feature?
π‘ Got a bug story or tip on coordinate quirks? Drop it in the comments!
Top comments (0)