Skip to main content

Rust-accelerated quadtree for Python with fast inserts, range queries, and k-NN search.

Project description

fastquadtree

Interactive Screenshot

Rust-optimized quadtree with a clean Python API

👉 Check out the Docs: https://elan456.github.io/fastquadtree/

PyPI Python versions Downloads Build No runtime deps

PyO3 maturin Ruff

Docs Wheels Coverage License: MIT


Why use fastquadtree

  • Just pip install: prebuilt wheels for Windows, macOS, and Linux (no Rust or compiler needed)
  • The fastest quadtree Python package (>10x faster than pyqtree)
  • Clean Python API with no external dependencies and modern typing hints
  • Support for inserting bounding boxes or points
  • Fast KNN and range queries
  • Optional object tracking for id ↔ object mapping
  • Fast serialization to/from bytes
  • Support for multiple data types (f32, f64, i32, i64) for coordinates
  • 100% test coverage and CI on GitHub Actions
  • Offers a drop-in pyqtree shim that is ~6.5x faster while keeping the same API

Install

pip install fastquadtree
from fastquadtree import QuadTree  # Point handling
from fastquadtree import RectQuadTree  # Bounding box handling
from fastquadtree import QuadTreeObjects  # Point handling with object tracking
from fastquadtree import RectQuadTreeObjects  # Bounding box handling with object tracking
from fastquadtree.pyqtree import Index  # Drop-in pyqtree shim (~6.5x faster while keeping the same API)

Quickstart

from fastquadtree import QuadTree

qt = QuadTree((0, 0, 1000, 1000), 16)  # bounds and capacity
qt.insert((100, 200), id_=1)  # insert point with ID 1
print(qt.query((0, 0, 500, 500)))  # gets all points in that area: [(1, 100.0, 200.0)]

See the quickstart guide or the interactive demos for more details.

Benchmarks

fastquadtree outperforms all other quadtree Python packages, including the Rtree spatial index.

Library comparison

Total time Throughput

Summary (PyQtree baseline, sorted by total time)

  • Points: 500,000, Queries: 500
Library Build (s) Query (s) Total (s) Speed vs PyQtree
fastquadtree (np)[^fqtnp] 0.057 0.021 0.078 54.45×
fastquadtree[^fqt] 0.060 0.189 0.249 17.04×
Shapely STRtree[^npreturn] 0.321 0.196 0.517 8.21×
fastquadtree (obj tracking)[^fqto] 0.437 0.239 0.675 6.28×
Rtree 1.796 0.561 2.357 1.80×
nontree-QuadTree 1.275 1.272 2.547 1.67×
e-pyquadtree 2.144 1.507 3.650 1.16×
quads 3.001 1.171 4.172 1.02×
PyQtree 3.677 0.565 4.242 1.00×

[^fqtnp]: Uses query_np for Numpy array return values rather than Python lists.
[^fqt]: Uses standard query method returning Python lists.
[^npreturn]: Uses Shapely STRtree with Numpy array points and returns.
[^fqto]: Uses QuadTreeObjects with object association.

See the benchmark section for details, including configurations, system info, and native vs shim benchmarks.

API

See the full API

QuadTree(bounds, capacity, max_depth=None, dtype="f32")

  • bounds — tuple (min_x, min_y, max_x, max_y) defines the 2D area covered by the quadtree
  • capacity — max number of points kept in a leaf before splitting
  • max_depth — optional depth cap. If omitted, the tree can keep splitting as needed
  • dtype — data type for coordinates, e.g., "f32", "f64", "i32", "i64"

Key Methods

  • insert(xy, id_=None) -> int

  • query(rect) -> list[tuple[int, float, float]]

  • nearest_neighbor(xy) -> tuple[int, float, float] | None

  • delete(id, x, y) -> bool

For object tracking, use QuadTreeObjects instead. See the docs for more methods.

Geometric conventions

  • Rectangles are (min_x, min_y, max_x, max_y).
  • Containment rule is closed on the min edge and open 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.

Performance tips

  • Choose capacity so that leaves keep a small batch of points. Typical values are 8 to 64.
  • If your data is very skewed, set a max_depth to prevent long chains.
  • For fastest local runs, use maturin develop --release.
  • Use QuadTree when you only need spatial indexing. Use QuadTreeObjects when you need to store Python objects with your points.
  • Refer to the Native vs Shim Benchmark for overhead details.

Pygame Ball Pit Demo

Ballpit_Demo_Screenshot

A simple demo of moving objects with collision detection using fastquadtree. You can toggle between fastquadtree, pyqtree, and brute-force mode to see the performance difference. I typically see an FPS of ~70 with fastquadtree, ~25 with pyqtree, and <1 FPS with brute-force on my machine with 1500 balls.

See the runnables guide for setup instructions.

FAQ

Can I delete items from the quadtree? Yes! Use delete(id, x, y) to remove specific items. You must provide both the ID and exact location for precise deletion. This handles cases where multiple items exist at the same location. If you're using QuadTreeObjects, you can also use delete_by_object(obj) for convenient object-based deletion with O(1) lookup. The tree automatically merges nodes when item counts drop below capacity.

Can I store rectangles or circles? Yes, you can store rectangles using the RectQuadTree class. Circles can be approximated with bounding boxes. See the RectQuadTree docs for details.

Do I need NumPy installed? No, NumPy is a fully optional dependency. If you do have NumPy installed, you can use methods such as query_np and insert_many_np for better performance. Note that insert_many raises TypeError on NumPy input—you must use insert_many_np explicitly for NumPy arrays. The Rust core is able to handle NumPy arrays faster than Python lists, so there's a lot of time savings in utilizing the NumPy functions. See the Native vs Shim benchmark for details on how returing NumPy arrays can speed up queries.

# Using Python lists
qt.insert_many([(10, 20), (30, 40), (50, 60)])

# Using NumPy arrays (requires NumPy)
import numpy as np
points = np.array([[10, 20], [30, 40], [50, 60]])
qt.insert_many_np(points)  # Use insert_many_np for NumPy arrays

Does fastquadtree support multiprocessing? Yes, fastquadtree objects can be serialized to bytes using the to_bytes() method and deserialized back using from_bytes(). This allows you to share quadtree data across processes and even cache prebuilt trees to disk. When using QuadTreeObjects or RectQuadTreeObjects, you must pass include_objects=True to to_bytes() to serialize Python objects, and allow_objects=True to from_bytes() when loading. By default, objects are skipped for safety, as deserializing untrusted Python objects can be unsafe. See the interactive v2 demo for an example of saving and loading a quadtree, and the QuadTreeObjects API docs for full details on the serialization methods.

License

MIT. See LICENSE.

Acknowledgments

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

fastquadtree-2.0.3.tar.gz (838.6 kB view details)

Uploaded Source

Built Distributions

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

fastquadtree-2.0.3-pp310-pypy310_pp73-manylinux_2_28_armv7l.whl (437.0 kB view details)

Uploaded PyPymanylinux: glibc 2.28+ ARMv7l

fastquadtree-2.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl (391.6 kB view details)

Uploaded PyPymanylinux: glibc 2.28+ ARM64

fastquadtree-2.0.3-pp39-pypy39_pp73-manylinux_2_28_armv7l.whl (436.1 kB view details)

Uploaded PyPymanylinux: glibc 2.28+ ARMv7l

fastquadtree-2.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl (390.6 kB view details)

Uploaded PyPymanylinux: glibc 2.28+ ARM64

fastquadtree-2.0.3-cp38-abi3-win_amd64.whl (304.3 kB view details)

Uploaded CPython 3.8+Windows x86-64

fastquadtree-2.0.3-cp38-abi3-manylinux_2_28_x86_64.whl (415.4 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.28+ x86-64

fastquadtree-2.0.3-cp38-abi3-manylinux_2_28_armv7l.whl (437.2 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.28+ ARMv7l

fastquadtree-2.0.3-cp38-abi3-manylinux_2_28_aarch64.whl (390.7 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.28+ ARM64

fastquadtree-2.0.3-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (719.0 kB view details)

Uploaded CPython 3.8+macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file fastquadtree-2.0.3.tar.gz.

File metadata

  • Download URL: fastquadtree-2.0.3.tar.gz
  • Upload date:
  • Size: 838.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.11.2

File hashes

Hashes for fastquadtree-2.0.3.tar.gz
Algorithm Hash digest
SHA256 51d2515254762aec67f1bb425fc89e7545ab30c8ee341159f9b0a2c778b17d88
MD5 9a25420016d9da23e5df7511f2efa303
BLAKE2b-256 b921b8fd98545abeaac86deab610e03066d9703e47ac76c59ce15022b604927b

See more details on using hashes here.

File details

Details for the file fastquadtree-2.0.3-pp310-pypy310_pp73-manylinux_2_28_armv7l.whl.

File metadata

File hashes

Hashes for fastquadtree-2.0.3-pp310-pypy310_pp73-manylinux_2_28_armv7l.whl
Algorithm Hash digest
SHA256 c774db0aede0e4bb9967608234186b60c39102120bf61f4630b9ea3ad36ab05b
MD5 ba37bab89d5e83aae059f8ee148f056f
BLAKE2b-256 dbf66b748e0b70ab6dc05e8cf113ee6f48187f317064a8634ac1bc080f86e4dd

See more details on using hashes here.

File details

Details for the file fastquadtree-2.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for fastquadtree-2.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3f689a47f8c74949f17e2cfc219d07f888e980e8850b734aad5de1085485cb01
MD5 b06d25e4bb1858e5b9ab4804b9411d1f
BLAKE2b-256 e77c3a141808d42172b18b17212fbee5a502d6a072c750b2fa95acba21e354bb

See more details on using hashes here.

File details

Details for the file fastquadtree-2.0.3-pp39-pypy39_pp73-manylinux_2_28_armv7l.whl.

File metadata

File hashes

Hashes for fastquadtree-2.0.3-pp39-pypy39_pp73-manylinux_2_28_armv7l.whl
Algorithm Hash digest
SHA256 ec5aea0ba2b1fe8b5e26ac4c33c6ef57b024fa74b122b82a90a9b842cbfd94ce
MD5 4de0bbc79e3c49cffe0f20acc584922a
BLAKE2b-256 33dcbda234e5df9d9d880209dd8e7a59c9375692ddaf0ab77894c3d5d4bdebca

See more details on using hashes here.

File details

Details for the file fastquadtree-2.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for fastquadtree-2.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3bf1845f724307a0a3ff6057e5c6c58f771804e106c6aae5cca7786678912207
MD5 a0914bd2192bdd7c8ed4c9239f2b8dbb
BLAKE2b-256 a0ff5c90571c4afd221bf8fce8facb89d39189b89d89e6b9cd288756d2f9ccc1

See more details on using hashes here.

File details

Details for the file fastquadtree-2.0.3-cp38-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for fastquadtree-2.0.3-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 a99979a652beaa2a4cfc9b43bfc8532a64c3cdb39d729aa51a1cd8de391963b7
MD5 04f204873fa703c32263c8669882cb8d
BLAKE2b-256 7bf9d31f6c21ec25bb5d810cbec5a54ac8dbdf28f3b9a84f39a4a6b5f716a635

See more details on using hashes here.

File details

Details for the file fastquadtree-2.0.3-cp38-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for fastquadtree-2.0.3-cp38-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 8721eb13f57ef77f8d093d9f47602080d448801a4e89efa8b857b901b83f533d
MD5 217f8c79222218649ee09f2075b1c3bf
BLAKE2b-256 aa15ca242e1e4ad46ed175cbf05956dc7cd8ba3a88a1ea42e732380b309b59b1

See more details on using hashes here.

File details

Details for the file fastquadtree-2.0.3-cp38-abi3-manylinux_2_28_armv7l.whl.

File metadata

File hashes

Hashes for fastquadtree-2.0.3-cp38-abi3-manylinux_2_28_armv7l.whl
Algorithm Hash digest
SHA256 4abda6750c29ed809af9e79968b8413688b02e84af07af19b321b0d211aaafe0
MD5 8fb5a719aa39e52a0c47fada9566351c
BLAKE2b-256 b6244d729184f9dab82713a92b28e0a3c9b83d78054d6a181698e0db2d503173

See more details on using hashes here.

File details

Details for the file fastquadtree-2.0.3-cp38-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for fastquadtree-2.0.3-cp38-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 12d7a54e37603b379018bf300076e23e49ef07b88228f1fa75fd35dbb2c6b490
MD5 51c3fad72d33f9c6b5207c30dc633495
BLAKE2b-256 f82c3b19357350dc0fa957bcab65d742f57f62036ac85c406f86d65a93ddc817

See more details on using hashes here.

File details

Details for the file fastquadtree-2.0.3-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for fastquadtree-2.0.3-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 adf2f701abca5db3b1e6806a91f19d2356a4225615bf022a8d92228e2431a004
MD5 01b38af69bc0550837ef576f4826813b
BLAKE2b-256 12545fc5b9578a913f8dfe4ea0c0d6a2d9490d666a9ca8644aa717f9ff131992

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