fastquadtree 1.0.1__cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl → 1.1.0__cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.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.
- fastquadtree/_base_quadtree.py +51 -5
- fastquadtree/_item.py +15 -5
- fastquadtree/_native.abi3.so +0 -0
- {fastquadtree-1.0.1.dist-info → fastquadtree-1.1.0.dist-info}/METADATA +4 -2
- {fastquadtree-1.0.1.dist-info → fastquadtree-1.1.0.dist-info}/RECORD +7 -7
- {fastquadtree-1.0.1.dist-info → fastquadtree-1.1.0.dist-info}/WHEEL +0 -0
- {fastquadtree-1.0.1.dist-info → fastquadtree-1.1.0.dist-info}/licenses/LICENSE +0 -0
fastquadtree/_base_quadtree.py
CHANGED
@@ -2,11 +2,23 @@
|
|
2
2
|
from __future__ import annotations
|
3
3
|
|
4
4
|
from abc import ABC, abstractmethod
|
5
|
-
from typing import
|
5
|
+
from typing import (
|
6
|
+
TYPE_CHECKING,
|
7
|
+
Any,
|
8
|
+
Generic,
|
9
|
+
Iterable,
|
10
|
+
Sequence,
|
11
|
+
Tuple,
|
12
|
+
TypeVar,
|
13
|
+
overload,
|
14
|
+
)
|
6
15
|
|
7
16
|
from ._item import Item # base class for PointItem and RectItem
|
8
17
|
from ._obj_store import ObjStore
|
9
18
|
|
19
|
+
if TYPE_CHECKING:
|
20
|
+
from numpy.typing import NDArray
|
21
|
+
|
10
22
|
Bounds = Tuple[float, float, float, float]
|
11
23
|
|
12
24
|
# Generic parameters
|
@@ -15,6 +27,11 @@ HitT = TypeVar("HitT") # raw native tuple, e.g. (id,x,y) or (id,x0,y0,x1,y1)
|
|
15
27
|
ItemType = TypeVar("ItemType", bound=Item) # e.g. PointItem or RectItem
|
16
28
|
|
17
29
|
|
30
|
+
def _is_np_array(x: Any) -> bool:
|
31
|
+
mod = getattr(x.__class__, "__module__", "")
|
32
|
+
return mod.startswith("numpy") and hasattr(x, "ndim") and hasattr(x, "shape")
|
33
|
+
|
34
|
+
|
18
35
|
class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
|
19
36
|
"""
|
20
37
|
Shared logic for Python QuadTree wrappers over native Rust engines.
|
@@ -110,9 +127,18 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
|
|
110
127
|
self._count += 1
|
111
128
|
return rid
|
112
129
|
|
113
|
-
|
130
|
+
@overload
|
131
|
+
def insert_many(self, geoms: Sequence[G], objs: list[Any] | None = None) -> int: ...
|
132
|
+
@overload
|
133
|
+
def insert_many(
|
134
|
+
self, geoms: NDArray[Any], objs: list[Any] | None = None
|
135
|
+
) -> int: ...
|
136
|
+
def insert_many(
|
137
|
+
self, geoms: NDArray[Any] | Sequence[G], objs: list[Any] | None = None
|
138
|
+
) -> int:
|
114
139
|
"""
|
115
140
|
Bulk insert with auto-assigned contiguous ids. Faster than inserting one-by-one.<br>
|
141
|
+
Can accept either a Python sequence of geometries or a NumPy array of shape (N,2) or (N,4) with dtype float32.
|
116
142
|
|
117
143
|
If tracking is enabled, the objects will be bulk stored internally.
|
118
144
|
If no objects are provided, the items will have obj=None (if tracking).
|
@@ -127,13 +153,30 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
|
|
127
153
|
Raises:
|
128
154
|
ValueError: If any geometry is outside bounds.
|
129
155
|
"""
|
130
|
-
if
|
156
|
+
if type(geoms) is list and len(geoms) == 0:
|
131
157
|
return 0
|
132
158
|
|
159
|
+
if _is_np_array(geoms):
|
160
|
+
import numpy as _np
|
161
|
+
else:
|
162
|
+
_np = None
|
163
|
+
|
164
|
+
# Early return if the numpy array is empty
|
165
|
+
if _np is not None and isinstance(geoms, _np.ndarray):
|
166
|
+
if geoms.size == 0:
|
167
|
+
return 0
|
168
|
+
|
169
|
+
if geoms.dtype != _np.float32:
|
170
|
+
raise TypeError("Numpy array must use dtype float32")
|
171
|
+
|
133
172
|
if self._store is None:
|
134
173
|
# Simple contiguous path with native bulk insert
|
135
174
|
start_id = self._next_id
|
136
|
-
|
175
|
+
|
176
|
+
if _np is not None:
|
177
|
+
last_id = self._native.insert_many_np(start_id, geoms)
|
178
|
+
else:
|
179
|
+
last_id = self._native.insert_many(start_id, geoms)
|
137
180
|
num = last_id - start_id + 1
|
138
181
|
if num < len(geoms):
|
139
182
|
raise ValueError("One or more items are outside tree bounds")
|
@@ -143,7 +186,10 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
|
|
143
186
|
|
144
187
|
# With tracking enabled:
|
145
188
|
start_id = len(self._store._arr) # contiguous tail position
|
146
|
-
|
189
|
+
if _np is not None:
|
190
|
+
last_id = self._native.insert_many_np(start_id, geoms)
|
191
|
+
else:
|
192
|
+
last_id = self._native.insert_many(start_id, geoms)
|
147
193
|
num = last_id - start_id + 1
|
148
194
|
if num < len(geoms):
|
149
195
|
raise ValueError("One or more items are outside tree bounds")
|
fastquadtree/_item.py
CHANGED
@@ -23,17 +23,22 @@ class Item:
|
|
23
23
|
__slots__ = ("geom", "id_", "obj")
|
24
24
|
|
25
25
|
def __init__(self, id_: int, geom: Point | Bounds, obj: Any | None = None):
|
26
|
-
self.id_ = id_
|
27
|
-
self.geom = geom
|
28
|
-
self.obj = obj
|
26
|
+
self.id_: int = id_
|
27
|
+
self.geom: Point | Bounds = geom
|
28
|
+
self.obj: Any | None = obj
|
29
29
|
|
30
30
|
|
31
31
|
class PointItem(Item):
|
32
32
|
"""
|
33
33
|
Lightweight point item wrapper for tracking and as_items results.
|
34
|
+
|
35
|
+
Attributes:
|
36
|
+
id_: Integer identifier.
|
37
|
+
geom: The point geometry as (x, y).
|
38
|
+
obj: The attached Python object if available, else None.
|
34
39
|
"""
|
35
40
|
|
36
|
-
__slots__ = ("
|
41
|
+
__slots__ = ("x", "y")
|
37
42
|
|
38
43
|
def __init__(self, id_: int, geom: Point, obj: Any | None = None):
|
39
44
|
super().__init__(id_, geom, obj)
|
@@ -43,9 +48,14 @@ class PointItem(Item):
|
|
43
48
|
class RectItem(Item):
|
44
49
|
"""
|
45
50
|
Lightweight rectangle item wrapper for tracking and as_items results.
|
51
|
+
|
52
|
+
Attributes:
|
53
|
+
id_: Integer identifier.
|
54
|
+
geom: The rectangle geometry as (min_x, min_y, max_x, max_y
|
55
|
+
obj: The attached Python object if available, else None.
|
46
56
|
"""
|
47
57
|
|
48
|
-
__slots__ = ("
|
58
|
+
__slots__ = ("max_x", "max_y", "min_x", "min_y")
|
49
59
|
|
50
60
|
def __init__(self, id_: int, geom: Bounds, obj: Any | None = None):
|
51
61
|
super().__init__(id_, geom, obj)
|
fastquadtree/_native.abi3.so
CHANGED
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: fastquadtree
|
3
|
-
Version: 1.0
|
3
|
+
Version: 1.1.0
|
4
4
|
Classifier: Programming Language :: Python :: 3
|
5
5
|
Classifier: Programming Language :: Python :: 3 :: Only
|
6
6
|
Classifier: Programming Language :: Rust
|
@@ -25,6 +25,7 @@ Requires-Dist: mkdocs-git-revision-date-localized-plugin ; extra == 'dev'
|
|
25
25
|
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
|
+
Requires-Dist: numpy ; extra == 'dev'
|
28
29
|
Provides-Extra: dev
|
29
30
|
License-File: LICENSE
|
30
31
|
Summary: Rust-accelerated quadtree for Python with fast inserts, range queries, and k-NN search.
|
@@ -48,6 +49,7 @@ Rust-optimized quadtree with a clean Python API
|
|
48
49
|
[](https://pypi.org/project/fastquadtree/)
|
49
50
|
[](https://pepy.tech/projects/fastquadtree)
|
50
51
|
[](https://github.com/Elan456/fastquadtree/actions/workflows/release.yml)
|
52
|
+

|
51
53
|
|
52
54
|
[](https://pyo3.rs/)
|
53
55
|
[](https://www.maturin.rs/)
|
@@ -62,7 +64,7 @@ Rust-optimized quadtree with a clean Python API
|
|
62
64
|
|
63
65
|
## Why use fastquadtree
|
64
66
|
|
65
|
-
- Clean [Python API](https://elan456.github.io/fastquadtree/api/quadtree/) with modern typing hints
|
67
|
+
- Clean [Python API](https://elan456.github.io/fastquadtree/api/quadtree/) with no external dependencies and modern typing hints
|
66
68
|
- The fastest quadtree Python package ([>10x faster](https://elan456.github.io/fastquadtree/benchmark/) than pyqtree)
|
67
69
|
- Prebuilt wheels for Windows, macOS, and Linux
|
68
70
|
- Support for [inserting bounding boxes](https://elan456.github.io/fastquadtree/api/rect_quadtree/) or points
|
@@ -1,13 +1,13 @@
|
|
1
|
-
fastquadtree-1.0.
|
2
|
-
fastquadtree-1.0.
|
3
|
-
fastquadtree-1.0.
|
1
|
+
fastquadtree-1.1.0.dist-info/METADATA,sha256=JQmhbeCyVPYw2fDQPTafS3k_DQ2hqYkwYZMWgnogmaI,9501
|
2
|
+
fastquadtree-1.1.0.dist-info/WHEEL,sha256=xBqaWU3Z-cfW-EFy0ENuEqxgXZXkIHUBkA1cT6FlqGM,127
|
3
|
+
fastquadtree-1.1.0.dist-info/licenses/LICENSE,sha256=pRuvcuqIMtEUBMgvP1Bc4fOHydzeuA61c6DQoQ1pb1w,1071
|
4
4
|
fastquadtree/__init__.py,sha256=rtkveNz7rScRasTRGu1yEqzeoJfLfreJNxg21orPL-U,195
|
5
|
-
fastquadtree/_base_quadtree.py,sha256=
|
6
|
-
fastquadtree/_item.py,sha256=
|
7
|
-
fastquadtree/_native.abi3.so,sha256=
|
5
|
+
fastquadtree/_base_quadtree.py,sha256=o5T0xqDM9i_JjpYF4U7VmLM0qUHkw0wr0bbRqb-CGt4,9901
|
6
|
+
fastquadtree/_item.py,sha256=LoTDr7zlsZyUrrKK6Ketzl5fxTcFF8YbcxEXbQ65st4,1679
|
7
|
+
fastquadtree/_native.abi3.so,sha256=hBLK36G-Hk5RGYeKgU5gEmLKHtoZxjnpbus62wnBNNk,499740
|
8
8
|
fastquadtree/_obj_store.py,sha256=vmhZGdzEoTQHvRbFjTne_0X2Z1l48SXyB6I9SAjjbiM,5267
|
9
9
|
fastquadtree/point_quadtree.py,sha256=Pz8ZS7N3kYSYJJYGa3ghKzy7d3JCA1dbi9nfEwwpF_k,5178
|
10
10
|
fastquadtree/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
11
|
fastquadtree/pyqtree.py,sha256=W5akt9gua7mr51eI-I1hqbZJMRdcNKWzpeaZhlOvhb0,5781
|
12
12
|
fastquadtree/rect_quadtree.py,sha256=7F-JceCHn5RLhztxSYCIJEZ_e2TV-NeobobbrdauJQA,3024
|
13
|
-
fastquadtree-1.0.
|
13
|
+
fastquadtree-1.1.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|