fastquadtree 1.2.1__cp38-abi3-win_amd64.whl → 1.3.0__cp38-abi3-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of fastquadtree might be problematic. Click here for more details.
- fastquadtree/_base_quadtree.py +21 -3
- fastquadtree/_native.pyd +0 -0
- fastquadtree/point_quadtree.py +21 -18
- fastquadtree/rect_quadtree.py +26 -19
- {fastquadtree-1.2.1.dist-info → fastquadtree-1.3.0.dist-info}/METADATA +7 -4
- fastquadtree-1.3.0.dist-info/RECORD +13 -0
- fastquadtree-1.2.1.dist-info/RECORD +0 -13
- {fastquadtree-1.2.1.dist-info → fastquadtree-1.3.0.dist-info}/WHEEL +0 -0
- {fastquadtree-1.2.1.dist-info → fastquadtree-1.3.0.dist-info}/licenses/LICENSE +0 -0
fastquadtree/_base_quadtree.py
CHANGED
|
@@ -18,6 +18,8 @@ from ._item import Item # base class for PointItem and RectItem
|
|
|
18
18
|
from ._obj_store import ObjStore
|
|
19
19
|
|
|
20
20
|
if TYPE_CHECKING:
|
|
21
|
+
from typing import Self # Only in Python 3.11+
|
|
22
|
+
|
|
21
23
|
from numpy.typing import NDArray
|
|
22
24
|
|
|
23
25
|
Bounds = Tuple[float, float, float, float]
|
|
@@ -46,6 +48,7 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
|
|
|
46
48
|
"_bounds",
|
|
47
49
|
"_capacity",
|
|
48
50
|
"_count",
|
|
51
|
+
"_dtype",
|
|
49
52
|
"_max_depth",
|
|
50
53
|
"_native",
|
|
51
54
|
"_next_id",
|
|
@@ -59,6 +62,10 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
|
|
|
59
62
|
def _new_native(self, bounds: Bounds, capacity: int, max_depth: int | None) -> Any:
|
|
60
63
|
"""Create the native engine instance."""
|
|
61
64
|
|
|
65
|
+
@classmethod
|
|
66
|
+
def _new_native_from_bytes(cls, data: bytes, dtype: str) -> Any:
|
|
67
|
+
"""Create the native engine instance from serialized bytes."""
|
|
68
|
+
|
|
62
69
|
@staticmethod
|
|
63
70
|
@abstractmethod
|
|
64
71
|
def _make_item(id_: int, geom: G, obj: Any | None) -> ItemType:
|
|
@@ -73,10 +80,12 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
|
|
|
73
80
|
*,
|
|
74
81
|
max_depth: int | None = None,
|
|
75
82
|
track_objects: bool = False,
|
|
83
|
+
dtype: str = "f32",
|
|
76
84
|
):
|
|
77
85
|
self._bounds = bounds
|
|
78
86
|
self._max_depth = max_depth
|
|
79
87
|
self._capacity = capacity
|
|
88
|
+
self._dtype = dtype
|
|
80
89
|
self._native = self._new_native(bounds, capacity, max_depth)
|
|
81
90
|
|
|
82
91
|
self._track_objects = bool(track_objects)
|
|
@@ -132,12 +141,13 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
|
|
|
132
141
|
return pickle.dumps(self.to_dict())
|
|
133
142
|
|
|
134
143
|
@classmethod
|
|
135
|
-
def from_bytes(cls, data: bytes) ->
|
|
144
|
+
def from_bytes(cls, data: bytes, dtype: str = "f32") -> Self:
|
|
136
145
|
"""
|
|
137
|
-
Deserialize a quadtree from bytes.
|
|
146
|
+
Deserialize a quadtree from bytes. Specifiy the dtype if the original tree that was serialized used a non-default dtype.
|
|
138
147
|
|
|
139
148
|
Args:
|
|
140
149
|
data: Bytes representing the serialized quadtree from `to_bytes()`.
|
|
150
|
+
dtype: The data type used in the native engine ('f32', 'f64', 'i32', 'i64') when saved to bytes.
|
|
141
151
|
|
|
142
152
|
Returns:
|
|
143
153
|
A new quadtree instance with the same state as when serialized.
|
|
@@ -154,7 +164,15 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
|
|
|
154
164
|
store_dict = in_dict["store"]
|
|
155
165
|
|
|
156
166
|
qt = cls.__new__(cls) # type: ignore[call-arg]
|
|
157
|
-
|
|
167
|
+
try:
|
|
168
|
+
qt._native = cls._new_native_from_bytes(core_bytes, dtype=dtype)
|
|
169
|
+
except ValueError as ve:
|
|
170
|
+
raise ValueError(
|
|
171
|
+
"Failed to deserialize quadtree native core. "
|
|
172
|
+
"This may be due to a dtype mismatch. "
|
|
173
|
+
"Ensure the dtype used in from_bytes() matches the original tree. "
|
|
174
|
+
"Error details: " + str(ve)
|
|
175
|
+
) from ve
|
|
158
176
|
|
|
159
177
|
if store_dict is not None:
|
|
160
178
|
qt._store = ObjStore.from_dict(store_dict, qt._make_item)
|
fastquadtree/_native.pyd
CHANGED
|
Binary file
|
fastquadtree/point_quadtree.py
CHANGED
|
@@ -5,10 +5,17 @@ from typing import Any, Literal, Tuple, overload
|
|
|
5
5
|
|
|
6
6
|
from ._base_quadtree import Bounds, _BaseQuadTree
|
|
7
7
|
from ._item import Point, PointItem
|
|
8
|
-
from ._native import QuadTree as
|
|
8
|
+
from ._native import QuadTree as QuadTreeF32, QuadTreeF64, QuadTreeI32, QuadTreeI64
|
|
9
9
|
|
|
10
10
|
_IdCoord = Tuple[int, float, float]
|
|
11
11
|
|
|
12
|
+
DTYPE_MAP = {
|
|
13
|
+
"f32": QuadTreeF32,
|
|
14
|
+
"f64": QuadTreeF64,
|
|
15
|
+
"i32": QuadTreeI32,
|
|
16
|
+
"i64": QuadTreeI64,
|
|
17
|
+
}
|
|
18
|
+
|
|
12
19
|
|
|
13
20
|
class QuadTree(_BaseQuadTree[Point, _IdCoord, PointItem]):
|
|
14
21
|
"""
|
|
@@ -29,6 +36,7 @@ class QuadTree(_BaseQuadTree[Point, _IdCoord, PointItem]):
|
|
|
29
36
|
capacity: Max number of points per node before splitting.
|
|
30
37
|
max_depth: Optional max tree depth. If omitted, engine decides.
|
|
31
38
|
track_objects: Enable id <-> object mapping inside Python.
|
|
39
|
+
dtype: Data type for coordinates and ids in the native engine. Default is 'f32'. Options are 'f32', 'f64', 'i32', 'i64'.
|
|
32
40
|
|
|
33
41
|
Raises:
|
|
34
42
|
ValueError: If parameters are invalid or inserts are out of bounds.
|
|
@@ -41,26 +49,16 @@ class QuadTree(_BaseQuadTree[Point, _IdCoord, PointItem]):
|
|
|
41
49
|
*,
|
|
42
50
|
max_depth: int | None = None,
|
|
43
51
|
track_objects: bool = False,
|
|
52
|
+
dtype: str = "f32",
|
|
44
53
|
):
|
|
45
54
|
super().__init__(
|
|
46
55
|
bounds,
|
|
47
56
|
capacity,
|
|
48
57
|
max_depth=max_depth,
|
|
49
58
|
track_objects=track_objects,
|
|
59
|
+
dtype=dtype,
|
|
50
60
|
)
|
|
51
61
|
|
|
52
|
-
@classmethod
|
|
53
|
-
def from_bytes(cls, data: bytes) -> QuadTree:
|
|
54
|
-
"""
|
|
55
|
-
Create a QuadTree instance from serialized bytes.
|
|
56
|
-
|
|
57
|
-
Args:
|
|
58
|
-
data: Serialized byte data from `to_bytes()`.
|
|
59
|
-
Returns:
|
|
60
|
-
A QuadTree instance.
|
|
61
|
-
"""
|
|
62
|
-
return super().from_bytes(data)
|
|
63
|
-
|
|
64
62
|
@overload
|
|
65
63
|
def query(
|
|
66
64
|
self, rect: Bounds, *, as_items: Literal[False] = ...
|
|
@@ -160,14 +158,19 @@ class QuadTree(_BaseQuadTree[Point, _IdCoord, PointItem]):
|
|
|
160
158
|
return out
|
|
161
159
|
|
|
162
160
|
def _new_native(self, bounds: Bounds, capacity: int, max_depth: int | None) -> Any:
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
161
|
+
"""Create the native engine instance."""
|
|
162
|
+
rust_cls = DTYPE_MAP.get(self._dtype)
|
|
163
|
+
if rust_cls is None:
|
|
164
|
+
raise ValueError(f"Unsupported dtype: {self._dtype}")
|
|
165
|
+
return rust_cls(bounds, capacity, max_depth)
|
|
166
166
|
|
|
167
167
|
@classmethod
|
|
168
|
-
def _new_native_from_bytes(cls, data: bytes) -> Any:
|
|
168
|
+
def _new_native_from_bytes(cls, data: bytes, dtype: str = "f32") -> Any:
|
|
169
169
|
"""Create a new native engine instance from serialized bytes."""
|
|
170
|
-
|
|
170
|
+
rust_cls = DTYPE_MAP.get(dtype)
|
|
171
|
+
if rust_cls is None:
|
|
172
|
+
raise ValueError(f"Unsupported dtype: {dtype}")
|
|
173
|
+
return rust_cls.from_bytes(data)
|
|
171
174
|
|
|
172
175
|
@staticmethod
|
|
173
176
|
def _make_item(id_: int, geom: Point, obj: Any | None) -> PointItem:
|
fastquadtree/rect_quadtree.py
CHANGED
|
@@ -5,10 +5,21 @@ from typing import Any, Literal, Tuple, overload
|
|
|
5
5
|
|
|
6
6
|
from ._base_quadtree import Bounds, _BaseQuadTree
|
|
7
7
|
from ._item import RectItem
|
|
8
|
-
from ._native import
|
|
8
|
+
from ._native import (
|
|
9
|
+
RectQuadTree as RectQuadTreeF32,
|
|
10
|
+
RectQuadTreeF64,
|
|
11
|
+
RectQuadTreeI32,
|
|
12
|
+
RectQuadTreeI64,
|
|
13
|
+
)
|
|
9
14
|
|
|
10
15
|
_IdRect = Tuple[int, float, float, float, float]
|
|
11
|
-
|
|
16
|
+
|
|
17
|
+
DTYPE_MAP = {
|
|
18
|
+
"f32": RectQuadTreeF32,
|
|
19
|
+
"f64": RectQuadTreeF64,
|
|
20
|
+
"i32": RectQuadTreeI32,
|
|
21
|
+
"i64": RectQuadTreeI64,
|
|
22
|
+
}
|
|
12
23
|
|
|
13
24
|
|
|
14
25
|
class RectQuadTree(_BaseQuadTree[Bounds, _IdRect, RectItem]):
|
|
@@ -30,6 +41,7 @@ class RectQuadTree(_BaseQuadTree[Bounds, _IdRect, RectItem]):
|
|
|
30
41
|
capacity: Max number of points per node before splitting.
|
|
31
42
|
max_depth: Optional max tree depth. If omitted, engine decides.
|
|
32
43
|
track_objects: Enable id <-> object mapping inside Python.
|
|
44
|
+
dtype: Data type for coordinates and ids in the native engine. Default is 'f32'. Options are 'f32', 'f64', 'i32', 'i64'.
|
|
33
45
|
|
|
34
46
|
Raises:
|
|
35
47
|
ValueError: If parameters are invalid or inserts are out of bounds.
|
|
@@ -42,26 +54,16 @@ class RectQuadTree(_BaseQuadTree[Bounds, _IdRect, RectItem]):
|
|
|
42
54
|
*,
|
|
43
55
|
max_depth: int | None = None,
|
|
44
56
|
track_objects: bool = False,
|
|
57
|
+
dtype: str = "f32",
|
|
45
58
|
):
|
|
46
59
|
super().__init__(
|
|
47
60
|
bounds,
|
|
48
61
|
capacity,
|
|
49
62
|
max_depth=max_depth,
|
|
50
63
|
track_objects=track_objects,
|
|
64
|
+
dtype=dtype,
|
|
51
65
|
)
|
|
52
66
|
|
|
53
|
-
@classmethod
|
|
54
|
-
def from_bytes(cls, data: bytes) -> RectQuadTree:
|
|
55
|
-
"""
|
|
56
|
-
Create a RectQuadTree instance from serialized bytes.
|
|
57
|
-
|
|
58
|
-
Args:
|
|
59
|
-
data: Serialized byte data from `to_bytes()`.
|
|
60
|
-
Returns:
|
|
61
|
-
A RectQuadTree instance.
|
|
62
|
-
"""
|
|
63
|
-
return super().from_bytes(data)
|
|
64
|
-
|
|
65
67
|
@overload
|
|
66
68
|
def query(
|
|
67
69
|
self, rect: Bounds, *, as_items: Literal[False] = ...
|
|
@@ -96,14 +98,19 @@ class RectQuadTree(_BaseQuadTree[Bounds, _IdRect, RectItem]):
|
|
|
96
98
|
return self._store.get_many_by_ids(self._native.query_ids(rect))
|
|
97
99
|
|
|
98
100
|
def _new_native(self, bounds: Bounds, capacity: int, max_depth: int | None) -> Any:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
"""Create the native engine instance."""
|
|
102
|
+
rust_cls = DTYPE_MAP.get(self._dtype)
|
|
103
|
+
if rust_cls is None:
|
|
104
|
+
raise ValueError(f"Unsupported dtype: {self._dtype}")
|
|
105
|
+
return rust_cls(bounds, capacity, max_depth)
|
|
102
106
|
|
|
103
107
|
@classmethod
|
|
104
|
-
def _new_native_from_bytes(cls, data: bytes) -> Any:
|
|
108
|
+
def _new_native_from_bytes(cls, data: bytes, dtype: str = "f32") -> Any:
|
|
105
109
|
"""Create a new native engine instance from serialized bytes."""
|
|
106
|
-
|
|
110
|
+
rust_cls = DTYPE_MAP.get(dtype)
|
|
111
|
+
if rust_cls is None:
|
|
112
|
+
raise ValueError(f"Unsupported dtype: {dtype}")
|
|
113
|
+
return rust_cls.from_bytes(data)
|
|
107
114
|
|
|
108
115
|
@staticmethod
|
|
109
116
|
def _make_item(id_: int, geom: Bounds, obj: Any | None) -> RectItem:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastquadtree
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Classifier: Programming Language :: Python :: 3
|
|
5
5
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
6
6
|
Classifier: Programming Language :: Rust
|
|
@@ -26,12 +26,13 @@ Requires-Dist: mkdocs-minify-plugin ; extra == 'dev'
|
|
|
26
26
|
Requires-Dist: maturin>=1.5 ; extra == 'dev'
|
|
27
27
|
Requires-Dist: pyqtree==1.0.0 ; extra == 'dev'
|
|
28
28
|
Requires-Dist: numpy ; extra == 'dev'
|
|
29
|
+
Requires-Dist: pre-commit ; extra == 'dev'
|
|
29
30
|
Provides-Extra: dev
|
|
30
31
|
License-File: LICENSE
|
|
31
32
|
Summary: Rust-accelerated quadtree for Python with fast inserts, range queries, and k-NN search.
|
|
32
33
|
Keywords: quadtree,spatial-index,geometry,rust,pyo3,nearest-neighbor,k-nn
|
|
33
34
|
Author: Ethan Anderson
|
|
34
|
-
Requires-Python: >=3.
|
|
35
|
+
Requires-Python: >=3.9
|
|
35
36
|
Description-Content-Type: text/markdown
|
|
36
37
|
Project-URL: Homepage, https://github.com/Elan456/fastquadtree
|
|
37
38
|
Project-URL: Repository, https://github.com/Elan456/fastquadtree
|
|
@@ -45,6 +46,8 @@ Project-URL: Issues, https://github.com/Elan456/fastquadtree/issues
|
|
|
45
46
|
|
|
46
47
|
Rust-optimized quadtree with a clean Python API
|
|
47
48
|
|
|
49
|
+
👉 **Check out the Docs:** https://elan456.github.io/fastquadtree/
|
|
50
|
+
|
|
48
51
|
[](https://pypi.org/project/fastquadtree/)
|
|
49
52
|
[](https://pypi.org/project/fastquadtree/)
|
|
50
53
|
[](https://pepy.tech/projects/fastquadtree)
|
|
@@ -64,19 +67,19 @@ Rust-optimized quadtree with a clean Python API
|
|
|
64
67
|
|
|
65
68
|
## Why use fastquadtree
|
|
66
69
|
|
|
67
|
-
- Clean [Python API](https://elan456.github.io/fastquadtree/api/quadtree/) with no external dependencies and modern typing hints
|
|
70
|
+
- Clean [Python API](https://elan456.github.io/fastquadtree/api/quadtree/) with **no external dependencies** and modern typing hints
|
|
68
71
|
- The fastest quadtree Python package ([>10x faster](https://elan456.github.io/fastquadtree/benchmark/) than pyqtree)
|
|
69
72
|
- Prebuilt wheels for Windows, macOS, and Linux
|
|
70
73
|
- Support for [inserting bounding boxes](https://elan456.github.io/fastquadtree/api/rect_quadtree/) or points
|
|
71
74
|
- Fast KNN and range queries
|
|
72
75
|
- Optional object tracking for id ↔ object mapping
|
|
73
76
|
- Fast [serialization](https://elan456.github.io/fastquadtree/benchmark/#serialization-vs-rebuild) to/from bytes
|
|
77
|
+
- Support for multiple data types (f32, f64, i32, i64) for coordinates
|
|
74
78
|
- [100% test coverage](https://codecov.io/gh/Elan456/fastquadtree) and CI on GitHub Actions
|
|
75
79
|
- Offers a drop-in [pyqtree shim](https://elan456.github.io/fastquadtree/benchmark/#pyqtree-drop-in-shim-performance-gains) that is 6.567x faster while keeping the same API
|
|
76
80
|
|
|
77
81
|
----
|
|
78
82
|
|
|
79
|
-
👉 **Docs:** https://elan456.github.io/fastquadtree/
|
|
80
83
|
|
|
81
84
|
## Examples
|
|
82
85
|
See examples of how fastquadtree can be used in the [runnables](https://elan456.github.io/fastquadtree/runnables/) section.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
fastquadtree-1.3.0.dist-info/METADATA,sha256=_I1G4rPdB-3ZjizUq7MhU9WKQKoquKoNOS_mTPvYeeM,9908
|
|
2
|
+
fastquadtree-1.3.0.dist-info/WHEEL,sha256=CG8OzNtm0LMpJ2zhrjswlO8N-965OeMLklsQAG-nMvQ,94
|
|
3
|
+
fastquadtree-1.3.0.dist-info/licenses/LICENSE,sha256=46IVFhoCIwMo-ocq4olyEB1eBvvtaKic5yGLeKXnDuc,1092
|
|
4
|
+
fastquadtree/__init__.py,sha256=jy7uimnd7QDllmNOgnRByKom1aONIKOWhCvCJxndsnM,200
|
|
5
|
+
fastquadtree/_base_quadtree.py,sha256=GCFn8YR-ViB0n1n8vYzcy15iDUR7D2HzRqp1uPHn9NE,16426
|
|
6
|
+
fastquadtree/_item.py,sha256=hlA71tvmLUQey42VokaZ7AmorIA8yZoGlvZWW9G4l4k,2496
|
|
7
|
+
fastquadtree/_native.pyd,sha256=kPC2Er1AMbJohtS9S4nq5738BxmSead-2szXN96Svlk,548352
|
|
8
|
+
fastquadtree/_obj_store.py,sha256=e164LT01nU5KqPX0udMzcJtpONAohDMEw-c9zEqh7uo,6723
|
|
9
|
+
fastquadtree/point_quadtree.py,sha256=8BDH4RNspH4Y-Vz9PSQH3y_Z4z5Oq5Cmcq9xnwVV6nk,6358
|
|
10
|
+
fastquadtree/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
fastquadtree/pyqtree.py,sha256=Evu-MKHKrs_xNVWChukD4hJLyIc-u7iuQ4hA_zvJtu4,6246
|
|
12
|
+
fastquadtree/rect_quadtree.py,sha256=-R0eLbjnGsPPfj5v2vDjdSIzGcmNcX9tVFDkd6J8Iqo,4121
|
|
13
|
+
fastquadtree-1.3.0.dist-info/RECORD,,
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
fastquadtree-1.2.1.dist-info/METADATA,sha256=1xRs6uTPeGao894dhIxehGbwiviqdEeS6Wzg2LDdP1A,9773
|
|
2
|
-
fastquadtree-1.2.1.dist-info/WHEEL,sha256=CG8OzNtm0LMpJ2zhrjswlO8N-965OeMLklsQAG-nMvQ,94
|
|
3
|
-
fastquadtree-1.2.1.dist-info/licenses/LICENSE,sha256=46IVFhoCIwMo-ocq4olyEB1eBvvtaKic5yGLeKXnDuc,1092
|
|
4
|
-
fastquadtree/__init__.py,sha256=jy7uimnd7QDllmNOgnRByKom1aONIKOWhCvCJxndsnM,200
|
|
5
|
-
fastquadtree/_base_quadtree.py,sha256=rBcoZjVg3mi-dFnyJ3GZBW9hn38P5gqgUceQrDatdZg,15574
|
|
6
|
-
fastquadtree/_item.py,sha256=hlA71tvmLUQey42VokaZ7AmorIA8yZoGlvZWW9G4l4k,2496
|
|
7
|
-
fastquadtree/_native.pyd,sha256=TODf58qjWedkKE38aKaf-SL2Q0aMapKmIIHEtkwmIjk,338944
|
|
8
|
-
fastquadtree/_obj_store.py,sha256=e164LT01nU5KqPX0udMzcJtpONAohDMEw-c9zEqh7uo,6723
|
|
9
|
-
fastquadtree/point_quadtree.py,sha256=phwiT6jVpdAnGf0dQ8_d2VW5DERDzCrOfqkSDzO39LI,6119
|
|
10
|
-
fastquadtree/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
fastquadtree/pyqtree.py,sha256=Evu-MKHKrs_xNVWChukD4hJLyIc-u7iuQ4hA_zvJtu4,6246
|
|
12
|
-
fastquadtree/rect_quadtree.py,sha256=EH1h1OlLt3K2GNxD9QwtlHyVFOmu8wTw-TeSnNDGmBU,3917
|
|
13
|
-
fastquadtree-1.2.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|