You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,7 +17,7 @@ A Rust crate for packed, immutable, zero-copy spatial indexes.
17
17
18
18
-**An R-tree and k-d tree written in safe rust.**
19
19
-**Fast.** Because of optimizations available by using immutable indexes, tends to be faster than dynamic implementations like [`rstar`](https://github.com/georust/rstar).
20
-
-**Memory efficient.** The index is fully _packed_, meaning that all nodes are at full capacity (except for the last node at each tree level). This means the RTree and k-d tree use less memory. And because the index is backed by a single buffer, it exhibits excellent memory locality. For any number of input geometries, the peak memory required both to build the index and to store the index can be pre-computed.
20
+
-**Memory efficient.** The index is fully _packed_, meaning that all nodes are at full capacity (except for the last node at each tree level). This means the RTree and k-d tree use less memory. And because the index is backed by a single buffer, it exhibits excellent memory locality.
21
21
-**Bounded memory**. For any given number of items and node size, you can infer the total memory used by the RTree or KDTree.
22
22
-**Multiple R-tree sorting methods.** Currently, [hilbert](https://en.wikipedia.org/wiki/Hilbert_R-tree) and [sort-tile-recursive (STR)](https://ia600900.us.archive.org/27/items/nasa_techdoc_19970016975/19970016975.pdf) sorting methods are implemented, but it's extensible to other spatial sorting algorithms in the future, like [overlap-minimizing top-down (OMT)](https://ceur-ws.org/Vol-74/files/FORUM_18.pdf).
23
23
-**ABI-stable:** the index is contained in a single `Vec<u8>`, compatible with the [`flatbush`](https://github.com/mourner/flatbush) and [`kdbush`](https://github.com/mourner/kdbush) JavaScript libraries. Being ABI-stable means that the spatial index can be persisted for later use or shared zero-copy between Rust and another program like Python.
Copy file name to clipboardExpand all lines: python/CHANGELOG.md
+21-9Lines changed: 21 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,14 +1,26 @@
1
1
# Changelog
2
2
3
-
## Unreleased
4
-
5
-
- Raise runtime warning for debug builds by @kylebarron in https://github.com/kylebarron/geo-index/pull/63
6
-
- RTree Buffer protocol, python binding tests by @H-Plus-Time in https://github.com/kylebarron/geo-index/pull/55
7
-
- Python: Return boxes as arrow from RTree by @kylebarron in https://github.com/kylebarron/geo-index/pull/89
8
-
- Update Python API & implement RTree partitions, nearest neighbor search by @kylebarron in https://github.com/kylebarron/geo-index/pull/87
9
-
- Update python bindings by @kylebarron in https://github.com/kylebarron/geo-index/pull/78
10
-
- Add `__repr__` to Python classes by @kylebarron in https://github.com/kylebarron/geo-index/pull/84
11
-
- Python docs website & improved rtree & kdtree docs by @kylebarron in https://github.com/kylebarron/geo-index/pull/93
3
+
## [0.2.0] - 2025-01-06
4
+
5
+
### New Features
6
+
7
+
- Support for nearest neighbor searching on RTrees with [`neighbors`](https://kylebarron.dev/geo-index/v0.2.0/api/rtree/#geoindex_rs.rtree.neighbors).
8
+
- Join two RTrees together with [`tree_join`](https://kylebarron.dev/geo-index/v0.2.0/api/rtree/#geoindex_rs.rtree.tree_join), finding their overlapping elements. This is the first part of a spatial join: to find which elements from two different data sources potentially intersect.
9
+
- Extract partitioning structure from the underlying RTree with [`partitions`](https://kylebarron.dev/geo-index/v0.2.0/api/rtree/#geoindex_rs.rtree.partitions) and see the partition geometries with [`partition_boxes`](https://kylebarron.dev/geo-index/v0.2.0/api/rtree/#geoindex_rs.rtree.partition_boxes).
10
+
- Expose [`RTreeMetadata`](https://kylebarron.dev/geo-index/v0.2.0/api/rtree/#geoindex_rs.rtree.RTreeMetadata) and [`KDTreeMetadata`](https://kylebarron.dev/geo-index/v0.2.0/api/kdtree/#geoindex_rs.kdtree.KDTreeMetadata). These allow you to infer the memory usage a tree would incur.
11
+
- Access the internal boxes within the RTree for inspecting the tree internals with `boxes_at_level`.
12
+
- Implement the buffer protocol on `RTree` and `KDTree`. This means you can copy the underlying buffer to Python with `bytes(tree)`.
13
+
14
+
### Breaking
15
+
16
+
-**Move RTree and KDTree query functions to standalone global functions**. This
17
+
makes it easier to persist index buffers and reuse them later, because the
18
+
query functions work on any object supporting the buffer protocol.
19
+
-**Create "builder" classes**: `RTreeBuilder` and `KDTreeBuilder`. Having these as separate classes allows for iteratively adding the coordinates for an RTree or KDTree. This is useful when the source geometries are larger than fits in memory.
Fast, memory-efficient 2D spatial indexes for Python.
8
+
Fast, memory-efficient, zero-copy spatial indexes for Python.
9
9
10
10
This documentation is for the Python bindings. [Refer here for the Rust crate documentation](https://docs.rs/geo-index).
11
11
12
+
## Features
13
+
14
+
-**An R-tree and k-d tree written in Rust, compiled for Python.**
15
+
-**Fast.** The Rust core and immutability lends the spatial indexes to be very fast. Additionally, building the indexes accepts vectorized Numpy or [Arrow](https://arrow.apache.org/) input.
16
+
-**Memory efficient.** The index is fully _packed_, meaning that all nodes are at full capacity (except for the last node at each tree level). This means the RTree and k-d tree use less memory.
17
+
-**Bounded memory**. For any given number of items and node size, you can infer the total memory used by the RTree or KDTree.
18
+
-**Multiple R-tree sorting methods.** Currently, [hilbert](https://en.wikipedia.org/wiki/Hilbert_R-tree) and [sort-tile-recursive (STR)](https://ia600900.us.archive.org/27/items/nasa_techdoc_19970016975/19970016975.pdf) sorting methods are implemented.
19
+
-**ABI-stable:** the index is contained in a single buffer, compatible with the [`flatbush`](https://github.com/mourner/flatbush) and [`kdbush`](https://github.com/mourner/kdbush) JavaScript libraries. Being ABI-stable means that the spatial index can be persisted for later use or shared zero-copy between Rust and Python.
20
+
-**Supports float64 or float32 coordinates:** for 2x memory savings, use float32 coordinates in the spatial index.
21
+
12
22
## Install
13
23
14
24
```
@@ -20,3 +30,97 @@ or with Conda:
20
30
```
21
31
conda install geoindex-rs
22
32
```
33
+
34
+
## Examples
35
+
36
+
Building an RTree and searching for nearest neighbors.
37
+
38
+
```py
39
+
import numpy as np
40
+
from geoindex_rs import rtree as rt
41
+
42
+
# Three bounding boxes
43
+
min_x = np.arange(0, 3)
44
+
min_y = np.arange(0, 3)
45
+
max_x = np.arange(2, 5)
46
+
max_y = np.arange(2, 5)
47
+
48
+
# When creating the builder, the total number of items must be passed
49
+
builder = rt.RTreeBuilder(num_items=3)
50
+
51
+
# Add the bounding boxes to the builder
52
+
builder.add(min_x, min_y, max_x, max_y)
53
+
54
+
# Consume the builder (sorting the index) and create the RTree.
55
+
tree = builder.finish()
56
+
57
+
# Find the nearest neighbors in the RTree to the point (5, 5)
58
+
results = rt.neighbors(tree, 5, 5)
59
+
60
+
# For performance, results are returned as an Arrow array.
61
+
assert results.to_pylist() == [2, 1, 0]
62
+
```
63
+
64
+
Building a KDTree and searching within a bounding box.
65
+
66
+
```py
67
+
import numpy as np
68
+
from geoindex_rs import kdtree as kd
69
+
70
+
# Three points: (0, 2), (1, 3), (2, 4)
71
+
x = np.arange(0, 3)
72
+
y = np.arange(2, 5)
73
+
74
+
# When creating the builder, the total number of items must be passed
75
+
builder = kd.KDTreeBuilder(3)
76
+
77
+
# Add the points to the builder
78
+
builder.add(x, y)
79
+
80
+
# Consume the builder (sorting the index) and create the KDTree.
81
+
tree = builder.finish()
82
+
83
+
# Search within this bounding box:
84
+
results = kd.range(tree, 2, 4, 7, 9)
85
+
86
+
# For performance, results are returned as an Arrow array.
87
+
assert results.to_pylist() == [2]
88
+
```
89
+
90
+
## Persisting the spatial index
91
+
92
+
The `RTree` and `KDTree` classes implement the Python buffer protocol, so you
93
+
can pass an instance of the index directly to `bytes` to copy the underlying
94
+
spatial index into a buffer. Then you can save that buffer somewhere, load it
95
+
again, and use it directly for queries!
96
+
97
+
```py
98
+
import numpy as np
99
+
from geoindex_rs import rtree as rt
100
+
101
+
min_x = np.arange(0, 3)
102
+
min_y = np.arange(0, 3)
103
+
max_x = np.arange(2, 5)
104
+
max_y = np.arange(2, 5)
105
+
106
+
builder = rt.RTreeBuilder(num_items=3)
107
+
builder.add(min_x, min_y, max_x, max_y)
108
+
tree = builder.finish()
109
+
110
+
# Copy to a Python bytes object
111
+
copied_tree =bytes(tree)
112
+
113
+
# The entire RTree is contained within this 144 byte buffer
114
+
assertlen(copied_tree) ==144
115
+
116
+
# We can use the bytes object (or anything else implementing the Python buffer
117
+
# protocol) directly in searches
118
+
results = rt.neighbors(copied_tree, 5, 5)
119
+
assert results.to_pylist() == [2, 1, 0]
120
+
```
121
+
122
+
## Drawbacks
123
+
124
+
- Trees are _immutable_. After creating the index, items can no longer be added or removed.
125
+
- Only two-dimensional indexes is supported. This can still be used with higher-dimensional input data as long as it's fine to only index two of the dimensions.
126
+
- Queries return insertion indexes into the input set, so you must manage your own collections.
0 commit comments