AABB - Hilbert R-tree Spatial Index
A Rust library providing a simple and efficient Hilbert R-tree implementation for spatial queries on axis-aligned bounding boxes (AABBs).
Features
- Hilbert Curve Ordering: Uses Hilbert space-filling curve for improved spatial locality (inspired by Flatbush algorithm)
- AABB Intersection Queries: Fast rectangular bounding box intersection testing
- Zero-Copy: Single contiguous buffer layout - safe for parallel queries with no allocations per query
- Simple API: Easy to use with minimal setup
- Static Optimization: Efficient for static or infrequently-modified spatial data
Usage
Add this to your Cargo.toml:
[]
= "0.6"
Basic Example
use *;
How it Works
The Hilbert R-tree stores bounding boxes in a flat array and sorts them by their Hilbert curve index (computed from box centers). This provides good spatial locality for most spatial queries while maintaining a simple, cache-friendly data structure.
API Reference
Construction
HilbertRTree::new()orAABB::new()- Create a new empty treeHilbertRTree::with_capacity(capacity)orAABB::with_capacity(capacity)- Create a new tree with preallocated capacityHilbertRTreeI32::new()orAABBI32::new()- Create a new empty treeHilbertRTreeI32::with_capacity(capacity)orAABBI32::with_capacity(capacity)- Create a new tree with preallocated capacityadd(min_x, min_y, max_x, max_y)- (f64, i32) Add a bounding boxbuild()- (f64, i32) the spatial index (required before querying)
Queries
Basic Spatial Queries
query_intersecting(min_x, min_y, max_x, max_y, results)(f64, i32)- Find boxes that intersect a rectanglequery_intersecting_k(min_x, min_y, max_x, max_y, k, results)(f64, i32)- Find first K intersecting boxesquery_point(x, y, results)(f64, i32)- Find boxes that contain a pointquery_contain(min_x, min_y, max_x, max_y, results)(f64, i32)- Find boxes that contain a rectanglequery_contained_within(min_x, min_y, max_x, max_y, results)(f64, i32)- Find boxes contained within a rectangle
Distance-Based Queries
query_nearest_k(x, y, k, results)(f64)- Find K nearest boxes to a pointquery_circle(center_x, center_y, radius, results)(f64)- Find boxes intersecting a circular region
Directional Queries
query_in_direction(rect_min_x, rect_min_y, rect_max_x, rect_max_y, direction_x, direction_y, distance, results)(f64)- Find boxes intersecting a rectangle's movement pathquery_in_direction_k(rect_min_x, rect_min_y, rect_max_x, rect_max_y, direction_x, direction_y, k, distance, results)(f64)- Find K nearest boxes intersecting a rectangle's movement path
Examples
Minimal examples for each query method are available in the examples/ directory:
query_intersecting- Find boxes intersecting a rectanglequery_intersecting_k- Find K first intersecting boxesquery_point- Find boxes containing a pointquery_contain- Find boxes containing a rectanglequery_contained_within- Find boxes inside a rectanglequery_nearest- Find the single nearest boxquery_nearest_k- Find K nearest boxesquery_circle- Find boxes in a circular regionquery_in_direction- Find boxes in a movement pathquery_in_direction_k- Find K nearest in a movement path
Run any example with:
Performance
- Cache-Friendly: Flat array storage with Hilbert curve ordering for good spatial locality
- Static Optimization: Optimized for static or infrequently-modified spatial data
Environment:
- OS: Ubuntu 24.04.3 LTS
- Processor: Intel Core i5-1240P
- Kernel: Linux 6.8.0-86-generic
- CPU Frequency: ~1773-3500 MHz
Building index with 1000000 items...
Index built in 116.58ms (f64)
Index built in 88.07ms (i32)
Running query benchmarks:
-----------------------
HilbertRTree::query_intersecting(f64)
1000 searches 10%: 246ms
1000 searches 1%: 19ms
1000 searches 0.01%: 2ms
-----------------------
HilbertRTreeI32::query_intersecting(i32)
1000 searches 10%: 169ms
1000 searches 1%: 10ms
1000 searches 0.01%: 0ms
Running neighbor benchmarks:
-----------------------
query_nearest_k(f64)
1000 searches of 100 neighbors: 21ms
1 searches of 1000000 neighbors: 123ms
100000 searches of 1 neighbors: 888ms
License
This project is licensed under the MIT License.