Fast quadtree in Rust with a Python API
Project description
quadtree-rs
Rust-accelerated quadtree with a simple Python API.
- Python package:
quadtree_rs - Python ≥ 3.8
- Import path:
from quadtree_rs import QuadTree
Install
pip install quadtree_rs
If you are developing locally:
# optimized dev install
maturin develop --release
Quickstart
from quadtree_rs import QuadTree
# Bounds are (min_x, min_y, max_x, max_y)
qt = QuadTree(bounds=(0, 0, 1000, 1000), capacity=20) # max_depth is optional
# Insert points. You supply an integer id and a point (x, y)
for i, (x, y) in enumerate([(10, 10), (200, 300), (999, 500)]):
ok = qt.insert(i, (x, y))
assert ok # False means the point was outside the bounds
# Axis-aligned rectangle query
hits = qt.query((0, 0, 250, 350))
# hits is a list of tuples: (id, x, y)
print(hits) # e.g. [(0, 10.0, 10.0), (1, 200.0, 300.0)]
# Nearest neighbor
best = qt.nearest_neighbor((210, 310))
print(best) # e.g. (1, 200.0, 300.0)
# k-nearest neighbors
top3 = qt.nearest_neighbors((210, 310), 3)
print(top3) # list of up to 3 (id, x, y) tuples
Mapping your Python objects
The quadtree stores ids and points for speed. Keep a side map in Python:
from quadtree_rs import QuadTree
qt = QuadTree((0, 0, 1000, 1000), capacity=16)
objects = {} # id -> your object
def add(obj_id: int, obj):
objects[obj_id] = obj
qt.insert(obj_id, obj.position) # where obj.position is (x, y)
# Later, resolve ids back to objects
ids = [obj_id for (obj_id, x, y) in qt.query((100, 100, 300, 300))]
selected = [objects[i] for i in ids]
API
QuadTree(bounds, capacity, *, max_depth=None)
bounds– tuple(min_x, min_y, max_x, max_y)covering all points you will insertcapacity– max number of items kept in a leaf before a splitmax_depth– optional depth cap. If omitted, the tree can grow until data distribution stops forcing splits
Methods
-
insert(id: int, xy: tuple[float, float]) -> boolInserts a point with your integer id. ReturnsFalseif the point is outsidebounds. -
query(rect: tuple[float, float, float, float]) -> list[tuple[int, float, float]]Returns all items whose point lies inside the axis-aligned rectangle. Each item is(id, x, y). -
nearest_neighbor(xy: tuple[float, float]) -> tuple[int, float, float] | NoneReturns the closest point toxy, orNoneif the tree is empty. -
nearest_neighbors(xy: tuple[float, float], k: int) -> list[tuple[int, float, float]]Returns up toknearest points toxy.
Geometric conventions
- Rectangles are
(min_x, min_y, max_x, max_y). - Containment rule is open on the min edge and closed on the max edge
(x > min_x and x <= max_x and y > min_y and y <= max_y). This only matters for points exactly on edges. Decide your own tie-break if you care about boundaries.
Performance tips
- Choose
capacityso that leaves keep a small batch of points. Typical values are 8 to 64. - If your data is very skewed, set a
max_depthto prevent degenerate chains. - For best runtime on your local dev build install with
maturin develop --release.
Benchmarks
Generated with benchmarks/bench_plotly.py in this repo.
- 100k points, 500 queries, capacity 20, max depth 10
- Median over 3 runs per size
Example summary (PyQtree baseline) — numbers will vary by machine:
| Library | Build (s) | Query (s) | Total (s) |
|---|---|---|---|
| Brute force | - | 4.068 | 4.068 |
| e-pyquadtree | 0.447 | 1.951 | 2.398 |
| PyQtree | 0.686 | 0.685 | 1.371 |
| quadtree-rs | 0.038 | 0.285 | 0.323 |
FAQ
What happens if I insert the same id more than once? Allowed. For k-nearest, duplicates are de-duplicated by id. For range queries you will see every inserted point.
Can I store rectangles or circles? The core stores points. To index objects with extent, insert the representative point you choose. For rectangles, you can either insert their centers or build a separate AABB tree.
Threading
The Python wrapper is a single QuadTree object with interior mutability handled in Rust. Use one tree per thread if you do heavy parallel inserts from Python.
License
MIT. See LICENSE.
Acknowledgments
- Python libraries compared: PyQtree, e-pyquadtree
- Built with PyO3 and maturin
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quadtree_rs-0.1.0.tar.gz.
File metadata
- Download URL: quadtree_rs-0.1.0.tar.gz
- Upload date:
- Size: 461.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90293de540f6eed307b3250e67c5f894bdd66ae35f41b35087422c847b653c47
|
|
| MD5 |
0f2f9dcdbde84266ce3e1318f6ada383
|
|
| BLAKE2b-256 |
b6c9f7639038e65481a2ba15a2ebfddeb02f7e3c7c77f9819b2a6968b74d2331
|
File details
Details for the file quadtree_rs-0.1.0-cp38-abi3-win_amd64.whl.
File metadata
- Download URL: quadtree_rs-0.1.0-cp38-abi3-win_amd64.whl
- Upload date:
- Size: 140.1 kB
- Tags: CPython 3.8+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ffae92e7c07f5ff586741abb458b7f130a61f729df513da8c02b9309e4166f3d
|
|
| MD5 |
13be121b4a599e1a7b3cafa80f1afb6d
|
|
| BLAKE2b-256 |
e2556d8205fcf5c213f6f1ce22ac6c57fc22d79130bbcaab2c1d7059671719c9
|
File details
Details for the file quadtree_rs-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: quadtree_rs-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 235.8 kB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
441165de3e41c38041025b1e22657310c3e6e0b85e70e4ef1899ae687df226bd
|
|
| MD5 |
17dc3d0100bcf00b3c1069ab46c65c5c
|
|
| BLAKE2b-256 |
8e5d80e25c108cc8f2703823a74c824400b4ad2e21d90901e6eaf15ae42fae36
|
File details
Details for the file quadtree_rs-0.1.0-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.
File metadata
- Download URL: quadtree_rs-0.1.0-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
- Upload date:
- Size: 413.1 kB
- Tags: CPython 3.8+, macOS 10.12+ universal2 (ARM64, x86-64), macOS 10.12+ x86-64, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a8af28d1ea5c2d59c31e6cd4e684f32c50220dd92aead8de536a6b0524585a31
|
|
| MD5 |
db93d0bc1ebd90c2099c8ca0e50b6c57
|
|
| BLAKE2b-256 |
2a59b8113eddf06b549c22d0e0570e0def6a860eda331ec6aa2f15b429e4a441
|