Distance Calculations
The rapidgeo.distance module provides fast geographic and planar distance calculations with multiple algorithms optimized for different use cases.
Core Types
- class rapidgeo.distance.LngLat(lng, lat)
Geographic coordinate representing longitude and latitude in decimal degrees.
Coordinates use longitude, latitude ordering (x, y convention). All functions expect coordinates in decimal degrees.
Examples
>>> from rapidgeo import LngLat >>> sf = LngLat(-122.4194, 37.7749) # San Francisco >>> print(sf.lng, sf.lat) -122.4194 37.7749
- lat
Latitude in decimal degrees.
- Returns:
Latitude coordinate (-90 to +90)
- Return type:
- lng
Longitude in decimal degrees.
- Returns:
Longitude coordinate (-180 to +180)
- Return type:
The LngLat type represents a coordinate pair in longitude, latitude order. All rapidgeo functions use this consistent ordering.
Example:
from rapidgeo.distance import LngLat
# Create coordinates (longitude first, latitude second)
sf = LngLat.new_deg(-122.4194, 37.7749) # San Francisco
nyc = LngLat.new_deg(-74.0060, 40.7128) # New York City
print(f"San Francisco: {sf}")
print(f"New York City: {nyc}")
Geographic Distance
Geographic distances calculate the actual distance between points on Earth’s surface.
Geographic distance functions
- rapidgeo.distance.geo.haversine(a, b)
Calculate the great-circle distance between two points using the Haversine formula.
Uses spherical Earth approximation for fast distance calculations. Accurate to within 0.5% for distances under 1000km.
- Parameters:
- Returns:
Distance in meters
- Return type:
Examples
>>> from rapidgeo import LngLat >>> from rapidgeo.distance.geo import haversine >>> sf = LngLat(-122.4194, 37.7749) >>> nyc = LngLat(-74.0060, 40.7128) >>> distance = haversine(sf, nyc) >>> print(f"Distance: {distance/1000:.0f} km") Distance: 4135 km
- rapidgeo.distance.geo.haversine_km(a, b)
Calculate distance in kilometers using the Haversine formula.
Convenient wrapper that returns distance in kilometers instead of meters. Fast spherical approximation accurate to within 0.5% for distances under 1000km.
- Parameters:
- Returns:
Distance in kilometers
- Return type:
Examples
>>> from rapidgeo import LngLat >>> from rapidgeo.distance.geo import haversine_km >>> sf = LngLat(-122.4194, 37.7749) >>> nyc = LngLat(-74.0060, 40.7128) >>> distance = haversine_km(sf, nyc) >>> print(f"Distance: {distance:.0f} km") Distance: 4135 km
- rapidgeo.distance.geo.haversine_miles(a, b)
Calculate distance in statute miles using the Haversine formula.
Convenient wrapper that returns distance in statute miles. Fast spherical approximation accurate to within 0.5% for distances under 1000km.
- Parameters:
- Returns:
Distance in statute miles
- Return type:
Examples
>>> from rapidgeo import LngLat >>> from rapidgeo.distance.geo import haversine_miles >>> sf = LngLat(-122.4194, 37.7749) >>> nyc = LngLat(-74.0060, 40.7128) >>> distance = haversine_miles(sf, nyc) >>> print(f"Distance: {distance:.0f} miles") Distance: 2570 miles
- rapidgeo.distance.geo.haversine_nautical(a, b)
Calculate distance in nautical miles using the Haversine formula.
Convenient wrapper that returns distance in nautical miles. Fast spherical approximation accurate to within 0.5% for distances under 1000km.
- Parameters:
- Returns:
Distance in nautical miles
- Return type:
Examples
>>> from rapidgeo import LngLat >>> from rapidgeo.distance.geo import haversine_nautical >>> sf = LngLat(-122.4194, 37.7749) >>> nyc = LngLat(-74.0060, 40.7128) >>> distance = haversine_nautical(sf, nyc) >>> print(f"Distance: {distance:.0f} nm") Distance: 2232 nm
- rapidgeo.distance.geo.bearing(from_point, to_point)
Calculate the initial bearing from one point to another.
Returns the compass bearing (azimuth) in degrees from the first point to the second point along the great circle path.
- Parameters:
- Returns:
Initial bearing in degrees (0-360°, where 0° is North)
- Return type:
Examples
>>> from rapidgeo import LngLat >>> from rapidgeo.distance.geo import bearing >>> sf = LngLat(-122.4194, 37.7749) >>> nyc = LngLat(-74.0060, 40.7128) >>> bearing_deg = bearing(sf, nyc) >>> print(f"Bearing: {bearing_deg:.1f}°") Bearing: 65.4°
- rapidgeo.distance.geo.destination(origin, distance_m, bearing_deg)
Calculate the destination point given origin, distance, and bearing.
Uses spherical trigonometry to find the point that is at the specified distance and bearing from the origin point.
- Parameters:
- Returns:
Destination coordinate
- Return type:
Examples
>>> from rapidgeo import LngLat >>> from rapidgeo.distance.geo import destination >>> london = LngLat(-0.1278, 51.5074) >>> dest = destination(london, 100000, 90) # 100km due east >>> print(f"Destination: {dest.lng:.4f}, {dest.lat:.4f}") Destination: 1.2644, 51.5074
- rapidgeo.distance.geo.vincenty_distance(a, b)
Calculate high-precision distance using Vincenty’s formulae for the WGS84 ellipsoid.
Provides millimeter accuracy for geodesic distances but slower than Haversine. May fail for nearly antipodal points (opposite sides of Earth).
- Parameters:
- Returns:
Distance in meters with millimeter precision
- Return type:
- Raises:
ValueError – If the algorithm fails to converge for antipodal points
Examples
>>> from rapidgeo import LngLat >>> from rapidgeo.distance.geo import vincenty_distance >>> sf = LngLat(-122.4194, 37.7749) >>> nyc = LngLat(-74.0060, 40.7128) >>> distance = vincenty_distance(sf, nyc) >>> print(f"Precise distance: {distance:.1f} m") Precise distance: 4134785.2 m
Algorithm Selection:
Haversine: Good for most applications. Assumes spherical Earth.
Vincenty: Higher precision using ellipsoidal Earth model. More computation required.
Example:
from rapidgeo.distance import LngLat
from rapidgeo.distance.geo import haversine, vincenty_distance
sf = LngLat.new_deg(-122.4194, 37.7749)
nyc = LngLat.new_deg(-74.0060, 40.7128)
# Fast, good accuracy for most use cases
distance = haversine(sf, nyc)
print(f"Haversine: {distance / 1000:.1f} km")
# High precision, slower
precise = vincenty_distance(sf, nyc)
print(f"Vincenty: {precise / 1000:.3f} km")
Planar Distance
Planar distances treat coordinates as points on a flat plane, ignoring Earth’s curvature.
Euclidean distance functions
- rapidgeo.distance.euclid.euclid(a, b)
Calculate Euclidean distance between coordinates treating them as points on a flat plane.
Uses the Pythagorean theorem: d = √[(x₂-x₁)² + (y₂-y₁)²] Fast but only accurate for small geographic areas or projected coordinates.
- Parameters:
- Returns:
Euclidean distance in decimal degrees
- Return type:
Examples
>>> from rapidgeo import LngLat >>> from rapidgeo.distance.euclid import euclid >>> p1 = LngLat(0.0, 0.0) >>> p2 = LngLat(1.0, 1.0) >>> distance = euclid(p1, p2) >>> print(f"Distance: {distance:.4f} degrees") Distance: 1.4142 degrees
- rapidgeo.distance.euclid.squared(a, b)
Calculate squared Euclidean distance (avoids expensive square root).
Useful for distance comparisons where you don’t need the actual distance value. Faster than euclid() when you only need to compare relative distances.
- Parameters:
- Returns:
Squared distance in decimal degrees²
- Return type:
Examples
>>> from rapidgeo.distance.euclid import squared >>> from rapidgeo import LngLat >>> p1 = LngLat(0.0, 0.0) >>> p2 = LngLat(3.0, 4.0) >>> dist_sq = squared(p1, p2) >>> print(f"Squared distance: {dist_sq}") Squared distance: 25.0
- rapidgeo.distance.euclid.point_to_segment(point, seg_start, seg_end)
Calculate the minimum Euclidean distance from a point to a line segment.
Projects the point onto the line segment and returns the shortest distance. Uses flat-plane geometry - not suitable for long geographic distances.
- Parameters:
- Returns:
Minimum distance in decimal degrees
- Return type:
Examples
>>> from rapidgeo.distance.euclid import point_to_segment >>> from rapidgeo import LngLat >>> point = LngLat(1.0, 1.0) >>> seg_start = LngLat(0.0, 0.0) >>> seg_end = LngLat(2.0, 0.0) >>> dist = point_to_segment(point, seg_start, seg_end) >>> print(f"Distance to segment: {dist:.1f}") Distance to segment: 1.0
- rapidgeo.distance.euclid.point_to_segment_squared(point, seg_start, seg_end)
Calculate squared distance from point to line segment (avoids square root).
Faster version of point_to_segment() when you only need relative distances. Useful for finding the closest segment among many options.
- Parameters:
- Returns:
Squared minimum distance in decimal degrees²
- Return type:
Examples
>>> from rapidgeo.distance.euclid import point_to_segment_squared >>> from rapidgeo import LngLat >>> point = LngLat(0.0, 1.0) >>> seg_start = LngLat(0.0, 0.0) >>> seg_end = LngLat(1.0, 0.0) >>> dist_sq = point_to_segment_squared(point, seg_start, seg_end) >>> print(f"Squared distance: {dist_sq}") Squared distance: 1.0
Use Cases:
Comparing distances when you only need relative ordering
Small geographic areas where Earth’s curvature doesn’t matter
Point-to-line segment calculations
Example:
from rapidgeo.distance import LngLat
from rapidgeo.distance.euclid import euclid, squared, point_to_segment
p1 = LngLat.new_deg(-122.0, 37.0)
p2 = LngLat.new_deg(-121.0, 37.0)
# Euclidean distance in degrees
distance = euclid(p1, p2)
print(f"Euclidean: {distance:.6f} degrees")
# Squared distance (faster, avoid sqrt)
distance_sq = squared(p1, p2)
print(f"Squared: {distance_sq:.6f} degrees²")
# Distance from point to line segment
point = LngLat.new_deg(-121.5, 37.1)
seg_distance = point_to_segment(point, p1, p2)
print(f"Point to segment: {seg_distance:.6f} degrees")
Batch Operations
Batch operations process multiple coordinates efficiently.
Batch distance and bearing functions
- rapidgeo.distance.batch.pairwise_haversine(points)
Calculate haversine distances between consecutive points in a path.
Computes the great-circle distance between each pair of consecutive points using the Haversine formula. Returns a list of distances with length
len(points) - 1.- Parameters:
points (list[LngLat]) – List of coordinates representing a path
- Returns:
Distances in meters between consecutive points. Length is
len(points) - 1.- Return type:
Examples
>>> from rapidgeo import LngLat >>> from rapidgeo.distance.batch import pairwise_haversine >>> path = [ ... LngLat(-122.4194, 37.7749), # San Francisco ... LngLat(-87.6298, 41.8781), # Chicago ... LngLat(-74.0060, 40.7128), # New York ... ] >>> distances = pairwise_haversine(path) >>> [f"{d/1000:.0f} km" for d in distances] ['2984 km', '1145 km']
Notes
Uses spherical Earth approximation (accurate to ±0.5% for distances <1000km)
Releases GIL during computation
For high precision, use Vincenty-based functions
See also
path_length_haversineSum of all consecutive distances
pairwise_bearingsBearings between consecutive points
- rapidgeo.distance.batch.path_length_haversine(points)
Calculate the total haversine distance along a path.
Computes the sum of great-circle distances between all consecutive points using the Haversine formula.
- Parameters:
points (list[LngLat]) – List of coordinates representing a path (minimum 2 points)
- Returns:
Total path length in meters
- Return type:
Examples
>>> from rapidgeo import LngLat >>> from rapidgeo.distance.batch import path_length_haversine >>> route = [ ... LngLat(-122.4194, 37.7749), # San Francisco ... LngLat(-87.6298, 41.8781), # Chicago ... LngLat(-74.0060, 40.7128), # New York ... ] >>> total_km = path_length_haversine(route) / 1000 >>> print(f"Total route: {total_km:.0f} km") Total route: 4129 km
Notes
Uses spherical Earth approximation (accurate to ±0.5% for distances <1000km)
Releases Python GIL during computation
Returns 0.0 for paths with fewer than 2 points
For millimeter precision, use
path_length_vincenty()
See also
pairwise_haversineGet individual segment distances
pairwise_bearingsGet bearings between consecutive points
- rapidgeo.distance.batch.path_length_haversine_batch(paths)
- rapidgeo.distance.batch.pairwise_bearings(points)
Calculate initial bearings between consecutive points in a path.
Computes the compass bearing (azimuth) from each point to the next point along the great circle path. Returns a list of bearings with length
len(points) - 1.Bearings are measured in degrees (0-360°) clockwise from North: 0° = North, 90° = East, 180° = South, 270° = West
- Parameters:
points (list[LngLat]) – List of coordinates representing a path
- Returns:
Initial bearings in degrees (0-360°). Length is
len(points) - 1.- Return type:
Examples
>>> from rapidgeo import LngLat >>> from rapidgeo.distance.batch import pairwise_bearings >>> path = [ ... LngLat(0.0, 0.0), # Origin ... LngLat(1.0, 0.0), # East ... LngLat(1.0, 1.0), # North ... ] >>> bearings = pairwise_bearings(path) >>> [f"{b:.1f}°" for b in bearings] ['90.0°', '0.0°']
Notes
Returns initial bearing at each point (bearing changes along great circles)
Releases Python GIL during computation
Returns empty list for paths with fewer than 2 points
Handles antimeridian crossing correctly
See also
pairwise_haversineDistances between consecutive points
bearingSingle bearing calculation
Example:
from rapidgeo.distance import LngLat
from rapidgeo.distance.batch import pairwise_haversine, path_length_haversine
# Define a path
path = [
LngLat.new_deg(-122.4194, 37.7749), # San Francisco
LngLat.new_deg(-87.6298, 41.8781), # Chicago
LngLat.new_deg(-74.0060, 40.7128), # New York City
]
# Calculate distances between consecutive points
distances = list(pairwise_haversine(path))
print(f"Segment distances: {[d/1000 for d in distances]} km")
# Calculate total path length
total_length = path_length_haversine(path)
print(f"Total path length: {total_length / 1000:.1f} km")
NumPy Integration
When rapidgeo is compiled with NumPy support, additional functions are available for processing NumPy arrays efficiently.
# Check if NumPy support is available
try:
from rapidgeo.distance import numpy as rgeo_numpy
print("NumPy support available")
except ImportError:
print("NumPy support not available")
Performance Notes
Algorithm Speed:
Euclidean is fastest
Haversine is moderate speed
Vincenty takes the most computation
Batch Operations:
Process multiple items at once for better efficiency
Iterator-based results to manage memory
Memory:
Each
LngLatuses 16 bytes (two 64-bit floats)Batch operations don’t duplicate input data unnecessarily