Skip to main content

rtree-geodetic

Python bindings for rstar_geodetic, a geodetic (longitude/latitude) R-tree with great-circle and WGS84 nearest-neighbour and radius queries over point, linestring, and polygon geometries.

Each (lon, lat) is mapped to a unit vector on the sphere and indexed in an R-tree, so the antimeridian and the poles are ordinary interior points: no wrapping or special cases. Coordinates are longitude first, latitude second, in degrees; distances are returned in metres. Queries return integer input positions (the shapely STRtree convention).

Install

pip install rtree-geodetic

Wheels are built for CPython 3.10 and newer (a single abi3 wheel per platform).

Quick start

A tree is built from any iterable of geometry-likes: (lon, lat) pairs, GeoJSON mappings, objects exposing __geo_interface__ (shapely geometries), or a single object whose __geo_interface__ is a collection (a geopandas GeoSeries, a shapely Multi*, a GeometryCollection, or a FeatureCollection).

from rtree_geodetic import GeodeticPointTree

tree = GeodeticPointTree([
    (-0.1278, 51.5074),  # 0 London
    (2.3522, 48.8566),   # 1 Paris
    (13.4050, 52.5200),  # 2 Berlin
])

tree.nearest((4.9041, 52.3676))                 # 0 (London)
tree.nearest_with_distance((4.9041, 52.3676))   # (0, 357888.0)  metres
tree.within_distance((4.9041, 52.3676), 400_000.0)                      # [0, 1]
tree.within_distance((4.9041, 52.3676), 400_000.0, return_distance=True)
# [(0, 357888.0), (1, 430123.5)]

tree.geometry(0).__geo_interface__
# {'type': 'Point', 'coordinates': (-0.1278, 51.5074)}

Point trees also offer a longitude/latitude rectangle query. Order the corners west-then-east to cross the antimeridian (the GeoJSON RFC 7946 convention):

tree = GeodeticPointTree([(179.0, 0.0), (-178.0, 1.0), (0.0, 0.0)])
tree.in_rectangle((170.0, -10.0), (-170.0, 10.0))   # [0, 1] (the two near the seam)

Linestring and polygon trees measure the minimum great-circle distance to the geometry (zero for a query inside a polygon):

from rtree_geodetic import GeodeticLineStringTree, GeodeticPolygonTree

lines = GeodeticLineStringTree([[(0, 0), (1, 1), (2, 0)], [(10, 10), (11, 11)]])
lines.nearest((1.0, 0.5))                       # 0

square = [[(0, 0), (10, 0), (10, 10), (0, 10), (0, 0)]]
polys = GeodeticPolygonTree([square])
polys.nearest_with_distance((5.0, 5.0))         # (0, 0.0) -- inside

shapely and geopandas

The geometry views expose __geo_interface__, so shapely.geometry.shape reconstructs them, and trees accept shapely geometries and geopandas GeoSeries directly:

import geopandas as gpd
from shapely.geometry import Point, shape
from rtree_geodetic import GeodeticPointTree

series = gpd.GeoSeries([Point(-0.1278, 51.5074), Point(2.3522, 48.8566)])
tree = GeodeticPointTree(series)

index = tree.nearest(Point(2.0, 49.0))          # 1 (Paris)
geom = shape(tree.geometry(index).__geo_interface__)   # a shapely Point

Distance semantics

Distances are great-circle metres. By default they use a spherical Earth (the GRS80 mean radius, 6 371 008.8 m); against an ellipsoid the error is at most about 0.5%.

GeodeticPointTree also offers exact WGS84-ellipsoid geodesic distances (Karney's method) through nearest_wgs84, nearest_with_distance_wgs84, and within_distance_wgs84:

tree.nearest_with_distance_wgs84((4.9041, 52.3676))   # (0, 358968.7) geodesic metres

Invalid coordinates or geometry (an out-of-range longitude or latitude, a non-finite value, too few vertices, an edge spanning half the sphere, or an unclosed ring) raise GeodeticError, a subclass of ValueError.

Performance

Measured with benchmarks/bench.py (seeded synthetic data; run it with uv run --group bench python benchmarks/bench.py) on an Apple M2 Pro, Python 3.14, shapely 2.1.2 (GEOS STRtree), rtree 1.4.1 (libspatialindex), release build. Datasets: one million points distributed uniformly on the sphere, and one hundred thousand small linestrings and polygons, queried per call from Python.

One million points, 10,000 queries:

Operation rtree-geodetic shapely STRtree Rtree
Build 0.79 s 0.23 s 1.63 s
Nearest neighbour, per call 3.5 us 7.9 us 21.4 us
Nearest neighbour, WGS84 geodesic 2.6 us not offered not offered
Within 50 km (radius query, ~16 hits) 10.5 us 10.3 us* not offered

100,000 extent geometries, 2,000 queries:

Operation rtree-geodetic shapely STRtree
Linestring build 0.66 s 0.02 s
Linestring nearest, per call 4.4 us 11.1 us
Polygon build 2.44 s 0.02 s
Polygon nearest, per call 7.8 us 12.6 us

[!NOTE] First, the planar libraries answer a different question: they index raw lon/lat degrees, so their distances are in degrees and their answers degrade as meridians converge. On the uniform global dataset above, the STRtree planar nearest neighbour differs from the true geodesic nearest neighbour for 10.9% of queries; rtree-geodetic returns the geodesically correct answer with the distance already in metres (this is the correctness you would otherwise get from the PostGIS geography type, without a database round trip). The starred STRtree radius query uses an equator-equivalent degree radius, which returns the wrong set away from the equator. Second, shapely's batch API (query_nearest with an array of geometries) amortises the Python boundary to 5.7 us per query at 1M points; rtree-geodetic currently offers per-call queries only.

Build times for rtree-geodetic include validating every coordinate and, for extent geometries, precomputing per-edge great-circle envelopes; construction currently traverses Python objects (__geo_interface__ or sequences): a numpy / GeoArrow fast path is future work.

Licence

Licensed under either of Apache License, Version 2.0 or MIT licence at your option.

Download files

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

Source Distribution

rtree_geodetic-0.2.0.tar.gz (189.1 kB view details)

Uploaded Source

Built Distributions

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

rtree_geodetic-0.2.0-cp310-abi3-win_amd64.whl (246.3 kB view details)

Uploaded CPython 3.10+Windows x86-64

rtree_geodetic-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (408.9 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

rtree_geodetic-0.2.0-cp310-abi3-macosx_11_0_arm64.whl (357.4 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file rtree_geodetic-0.2.0.tar.gz.

File metadata

  • Download URL: rtree_geodetic-0.2.0.tar.gz
  • Upload date:
  • Size: 189.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for rtree_geodetic-0.2.0.tar.gz
Algorithm Hash digest
SHA256 47a20a0b03b004e9ce1ec9373642cf7b9690992d08c26194be1b764b77768846
MD5 0f7f724dc46499d4a90dff440f4db972
BLAKE2b-256 1d1309be10e2a5193602672758826f173d871eba06a261fa606ce1d7be06df99

See more details on using hashes here.

Provenance

The following attestation bundles were made for rtree_geodetic-0.2.0.tar.gz:

Publisher: wheels.yml on urschrei/rstar_geodetic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rtree_geodetic-0.2.0-cp310-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for rtree_geodetic-0.2.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 2120059a21da659b111dea0047d131928dc161ad3a135da9a166d9907aefd2bf
MD5 cfade09ca8542e156958499bf35df32a
BLAKE2b-256 7ac032fbd920e6ac9c99b9289913b5bb765392fbfa870853a0230dd4d642520a

See more details on using hashes here.

Provenance

The following attestation bundles were made for rtree_geodetic-0.2.0-cp310-abi3-win_amd64.whl:

Publisher: wheels.yml on urschrei/rstar_geodetic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rtree_geodetic-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rtree_geodetic-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 56c39375dc758f2b61a002422dd94529ed2c65cdad7dd28c1da977d3110ac309
MD5 ec9d176e8aa8f6392a31bebcf00a35fa
BLAKE2b-256 5340bce78030baac6920ffb8f2082138e00f7550c98984ae65f79e99bd8b3177

See more details on using hashes here.

Provenance

The following attestation bundles were made for rtree_geodetic-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: wheels.yml on urschrei/rstar_geodetic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rtree_geodetic-0.2.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rtree_geodetic-0.2.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 43924817d708089a124cf0b1dc502bb4ab7e6f3b04ff2a9b4bb9500fd5e74d8d
MD5 ca26131373b7f0bbca4ad5479e1d595f
BLAKE2b-256 a8538afc6ebefc22372b645da6580cdce86771696116999b5502eed437a752f6

See more details on using hashes here.

Provenance

The following attestation bundles were made for rtree_geodetic-0.2.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: wheels.yml on urschrei/rstar_geodetic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.2.1

4 files

This release

0.2.0 This release

4 files

0.1.0

4 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page