Skip to main content

Rust-powered drop-in replacement for geopy — geodesic, great-circle, polygon area, and more

Project description

geors

Rust-powered drop-in replacement for geopy.

Replaces every compute-bound function in geopy with a Rust implementation using Karney's geodesic algorithm via geographiclib-rs. I/O-bound operations (geocoding, rate limiting) forward transparently to geopy.

Performance

Operation geopy geors (Rust) Speedup
Geodesic distance (scalar) 62.5 us 0.5 us 125x
Great-circle distance 3.1 us 0.1 us 31x
Full inverse (azimuths, scales) 42.1 us 0.8 us 52x
Direct problem 10.8 us 0.6 us 18x
Batch geodesic (1K points) 59.2 ms 0.06 ms 1,063x
Batch geodesic (10K points) 589 ms 0.29 ms 2,078x
Batch geodesic (1M points) ~59 sec 23.8 ms ~2,500x

Batch throughput: 42 million point-pairs/sec (rayon-parallel).

Verification

Verified to sub-nanometer precision against geographiclib and geopy:

  • 10,000 Karney GeodTest cases -- max distance error: 7.5e-9 m (~7 nanometers), 0 cases >1mm
  • 15 real-world city pairs -- max error: 9.3e-10 m (<1 nanometer)
  • 13 edge cases -- identical points, poles, antipodal, antimeridian, near-antipodal (Vincenty failure cases) -- all exact match
  • 1,000 random direct/inverse roundtrips -- max error: 5.6e-9 m
  • 1,000 random cross-checks vs geopy -- max error: 5.6e-9 m
  • Batch vs scalar consistency -- exact match (0.0 m difference)
pytest tests/test_python_compat.py -v     # 57 tests
python tests/verify_accuracy.py           # 37/37 comprehensive checks
python tests/bench_distance.py            # full benchmark suite

Installation

pip install geors

Usage

Drop-in replacement

# Before
from geopy.distance import geodesic, great_circle

# After (same API, 125x faster)
from geors.distance import geodesic, great_circle

Distance calculations

from geors.distance import geodesic, great_circle

# Geodesic (ellipsoidal, Karney's algorithm)
d = geodesic((40.7128, -74.0060), (51.5074, -0.1278))
print(d.km)        # 5570.248...
print(d.miles)     # 3461.358...
print(d.meters)    # 5570248.4...
print(d.feet)      # 18274764.0...
print(d.nautical)  # 3007.6...

# Great circle (spherical, Haversine)
d = great_circle((40.7128, -74.0060), (51.5074, -0.1278))
print(d.km)        # 5564.847...

Low-level functions

from geors._geors import distance, geodesic

# Scalar
meters = distance.geodesic_distance(40.7128, -74.0060, 51.5074, -0.1278)

# Full inverse (returns dict with s12, azi1, azi2, a12, ...)
result = distance.geodesic_inverse(40.7128, -74.0060, 51.5074, -0.1278)

# Direct problem (start + bearing + distance -> endpoint)
result = geodesic.direct(40.7128, -74.0060, 51.37, 5_554_000.0)

# Destination
lat2, lon2 = distance.geodesic_destination(40.7128, -74.0060, 51.37, 5_554_000.0)

Batch operations (numpy arrays, rayon-parallel)

import numpy as np
from geors._geors import distance

lat1 = np.random.uniform(-90, 90, 1_000_000)
lon1 = np.random.uniform(-180, 180, 1_000_000)
lat2 = np.random.uniform(-90, 90, 1_000_000)
lon2 = np.random.uniform(-180, 180, 1_000_000)

# Returns numpy array, computed in parallel across all cores
distances = distance.geodesic_distance_batch(lat1, lon1, lat2, lon2)
distances_gc = distance.great_circle_distance_batch(lat1, lon1, lat2, lon2)

Geocoding (forwards to geopy)

# Geocoding is I/O-bound, so we forward to geopy transparently
from geors.geocoders import Nominatim

geolocator = Nominatim(user_agent="my-app")
location = geolocator.geocode("New York City")
print(location.latitude, location.longitude)

What's Rust, what's forwarded

Component Implementation Why
geors.distance.geodesic Rust (geographiclib-rs) CPU-bound: Karney's iterative algorithm
geors.distance.great_circle Rust CPU-bound: Haversine trig
geodesic_distance_batch Rust + rayon Parallel array processing
geors.geocoders.* Forwards to geopy I/O-bound: HTTP API calls
geors.extra.rate_limiter Forwards to geopy I/O-bound: sleep/retry logic
Unit conversions Rust Simple arithmetic, zero overhead

Architecture

geors/
  crates/
    geo-math/     # High-precision math (trig in degrees, error-free sums, Accumulator)
    geors/        # Core library (geodesic, great-circle, polygon area, constants)
  src/            # PyO3 bindings (py_distance, py_geodesic, py_units)
  python/geors/   # Drop-in Python wrapper (Distance class, geocoder forwarding)

Built with PyO3 + maturin. Wheels for Linux, macOS, and Windows.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

geors-0.1.0.tar.gz (23.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

geors-0.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (395.8 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

geors-0.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (383.5 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

geors-0.1.0-cp312-cp312-win_amd64.whl (221.0 kB view details)

Uploaded CPython 3.12Windows x86-64

geors-0.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (396.6 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

geors-0.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (383.9 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

geors-0.1.0-cp312-cp312-macosx_11_0_arm64.whl (333.4 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

geors-0.1.0-cp312-cp312-macosx_10_12_x86_64.whl (340.1 kB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

geors-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (396.3 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

geors-0.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (383.7 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

geors-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (396.3 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

geors-0.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (383.8 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64

File details

Details for the file geors-0.1.0.tar.gz.

File metadata

  • Download URL: geors-0.1.0.tar.gz
  • Upload date:
  • Size: 23.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.12.6

File hashes

Hashes for geors-0.1.0.tar.gz
Algorithm Hash digest
SHA256 fae3039bd755ea3805a1cb49ca861267c552a116bd2664f1d6c857eb96843d80
MD5 bf7cf08b2f4724d0357bff8eb882cb72
BLAKE2b-256 0fa27928d0d657163e5de27a9cd54e5036c4190705e7fa27f08687a5a25a5106

See more details on using hashes here.

File details

Details for the file geors-0.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for geors-0.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 76994b49fc1071979a3065c7d46ab7c8335e5dc9f62cb5a86240c060bec22eeb
MD5 71135dff6dce51fb1c535c7c6ef59b63
BLAKE2b-256 740ce4046062dd0ab6a5a2225a5116ab503f6fc5dc1bf40817319ebe7cf66e70

See more details on using hashes here.

File details

Details for the file geors-0.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for geors-0.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e5b91f02138db295715a183ef5cbe29ec5c3afe7aacc8f25eded0170ad6892bd
MD5 b7978a516829ff72fdee662fb80a315f
BLAKE2b-256 07164a4810c3d563ae6dc11b4024aaa90fa796155c6dab671ab73bcbb9a4c878

See more details on using hashes here.

File details

Details for the file geors-0.1.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: geors-0.1.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 221.0 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.12.6

File hashes

Hashes for geors-0.1.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 1bde8f27f212bf7ba5a6682bfe329e93823113ae858a24bf2809ff58d3531f65
MD5 a060c80a08098f580de632269ca62441
BLAKE2b-256 774528098f55b79a399fb3b75f3a7457a1ca7c4fff86c27b215c54bbaa33b181

See more details on using hashes here.

File details

Details for the file geors-0.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for geors-0.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 30a0aedc867138d84ba9e18af99d25cf7032052a060c18ccb8cdc252be3d3c1b
MD5 dec28e30ca24f876139c39938d4e50b7
BLAKE2b-256 b574c8b78ba191a8839bce7383c5320ad721814eaa2529e61fe62c7b3a84092f

See more details on using hashes here.

File details

Details for the file geors-0.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for geors-0.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 98896db1da98485a6566f3cbd80f9755e595fc5abb7bcae21703e631ccda7e81
MD5 c42d325dd2748fac1ab9e3f6b01f26c2
BLAKE2b-256 b715a79c9d2d9c2c89776d4ebca9e81c8a1eadc3ddbedd54284d27c70f40b1e0

See more details on using hashes here.

File details

Details for the file geors-0.1.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for geors-0.1.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 489cde477c577c24b93312230a8602aba245c27b542492750d9af2568ea10045
MD5 1e944846494275b20893a35cfbc03f68
BLAKE2b-256 060fcf112ff54865776797ccba347fcc35182f391f2dde117de8d47bf5f16330

See more details on using hashes here.

File details

Details for the file geors-0.1.0-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for geors-0.1.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 e045fa4c00cb1ae5e609b9f8a966b1ef623855e71e4b2240821a6fffdea46e8b
MD5 60f6ac0d281bc1ae785fd8d4da59e93a
BLAKE2b-256 7d33c5f77e7f2b972fc51d7b002f7399c0524ff22e7a025e481a8e8cd02260cf

See more details on using hashes here.

File details

Details for the file geors-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for geors-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7d7e92ff34edd44d0b29bf95eacbc67a432123ae1b64e5ee7f31a9fcf745e531
MD5 4efd5e7cd6b2ef424fe0533aa0dcde6f
BLAKE2b-256 240e06f51d3ed148d79a9588bf0625335c81debbee9775fedaa90e5ae997c2cf

See more details on using hashes here.

File details

Details for the file geors-0.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for geors-0.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 cfcf05997cb8be571f9d50179e4eb9009fb0e18e5a2d7a5b49908664f98eb6e6
MD5 05f2216d4324b17a47c6c8eb0c6afa32
BLAKE2b-256 22ace0d0086d3d546a9b0aaeb656ea6f1d85c8b688d5dae0eb8cbcae3c34270c

See more details on using hashes here.

File details

Details for the file geors-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for geors-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e720ba5160b14f37a7ba667994e512f75fd77b5b4e3be9a50e7c26b02c0b56df
MD5 931ab387e9335218234f40d0dd7cdfaa
BLAKE2b-256 2be41948c5a247fa3d95e2033e00e60adbba00920285e6b4622a9f1626769ad1

See more details on using hashes here.

File details

Details for the file geors-0.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for geors-0.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 dd3fa6986bcb1ed1168e19e5ff805e94f1e5f0fc3067d013992f3ef4a848050b
MD5 78ac8b29dae490d4823aef471f76c66d
BLAKE2b-256 d26fb9625da192f4d0e3721c420cbc8dc887db299743f80f0aeaf93730ff0a23

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page