fastquadtree 1.2.0__cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl → 1.2.3__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.

Potentially problematic release.


This version of fastquadtree might be problematic. Click here for more details.

@@ -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]
@@ -59,6 +61,10 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
59
61
  def _new_native(self, bounds: Bounds, capacity: int, max_depth: int | None) -> Any:
60
62
  """Create the native engine instance."""
61
63
 
64
+ @classmethod
65
+ def _new_native_from_bytes(cls, data: bytes) -> Any:
66
+ """Create the native engine instance from serialized bytes."""
67
+
62
68
  @staticmethod
63
69
  @abstractmethod
64
70
  def _make_item(id_: int, geom: G, obj: Any | None) -> ItemType:
@@ -94,6 +100,12 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
94
100
 
95
101
  Returns:
96
102
  Includes a binary 'core' key for the native engine state, plus other metadata such as bounds and capacity and the obj store if tracking is enabled.
103
+
104
+ Example:
105
+ ```python
106
+ state = qt.to_dict()
107
+ assert "core" in state and "bounds" in state
108
+ ```
97
109
  """
98
110
 
99
111
  core_bytes = self._native.to_bytes()
@@ -115,11 +127,18 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
115
127
 
116
128
  Returns:
117
129
  Bytes representing the serialized quadtree. Can be saved as a file or loaded with `from_bytes()`.
130
+
131
+ Example:
132
+ ```python
133
+ blob = qt.to_bytes()
134
+ with open("tree.fqt", "wb") as f:
135
+ f.write(blob)
136
+ ```
118
137
  """
119
138
  return pickle.dumps(self.to_dict())
120
139
 
121
140
  @classmethod
122
- def from_bytes(cls, data: bytes) -> _BaseQuadTree[G, HitT, ItemType]:
141
+ def from_bytes(cls, data: bytes) -> Self:
123
142
  """
124
143
  Deserialize a quadtree from bytes.
125
144
 
@@ -128,6 +147,13 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
128
147
 
129
148
  Returns:
130
149
  A new quadtree instance with the same state as when serialized.
150
+
151
+ Example:
152
+ ```python
153
+ blob = qt.to_bytes()
154
+ qt2 = type(qt).from_bytes(blob)
155
+ assert qt2.count_items() == qt.count_items()
156
+ ```
131
157
  """
132
158
  in_dict = pickle.loads(data)
133
159
  core_bytes = in_dict["core"]
@@ -174,6 +200,13 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
174
200
 
175
201
  Raises:
176
202
  ValueError: If geometry is outside the tree bounds.
203
+
204
+ Example:
205
+ ```python
206
+ id0 = point_qt.insert((10.0, 20.0)) # for point trees
207
+ id1 = rect_qt.insert((0.0, 0.0, 5.0, 5.0), obj="box") # for rect trees
208
+ assert isinstance(id0, int) and isinstance(id1, int)
209
+ ```
177
210
  """
178
211
  if self._store is not None:
179
212
  # Reuse a dense free slot if available, else append
@@ -219,6 +252,17 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
219
252
 
220
253
  Raises:
221
254
  ValueError: If any geometry is outside bounds.
255
+
256
+ Example:
257
+ ```python
258
+ n = qt.insert_many([(1.0, 1.0), (2.0, 2.0)])
259
+ assert n == 2
260
+
261
+ import numpy as np
262
+ arr = np.array([[3.0, 3.0], [4.0, 4.0]], dtype=np.float32)
263
+ n2 = qt.insert_many(arr)
264
+ assert n2 == 2
265
+ ```
222
266
  """
223
267
  if type(geoms) is list and len(geoms) == 0:
224
268
  return 0
@@ -283,8 +327,19 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
283
327
  """
284
328
  Delete an item by id and exact geometry.
285
329
 
330
+ Args:
331
+ id_: The id of the item to delete.
332
+ geom: The geometry of the item to delete.
333
+
286
334
  Returns:
287
335
  True if the item was found and deleted.
336
+
337
+ Example:
338
+ ```python
339
+ i = qt.insert((1.0, 2.0))
340
+ ok = qt.delete(i, (1.0, 2.0))
341
+ assert ok is True
342
+ ```
288
343
  """
289
344
  deleted = self._native.delete(id_, geom)
290
345
  if deleted:
@@ -297,6 +352,17 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
297
352
  """
298
353
  Attach or replace the Python object for an existing id.
299
354
  Tracking must be enabled.
355
+
356
+ Args:
357
+ id_: The id of the item to attach the object to.
358
+ obj: The Python object to attach.
359
+
360
+ Example:
361
+ ```python
362
+ i = qt.insert((2.0, 3.0), obj=None)
363
+ qt.attach(i, {"meta": 123})
364
+ assert qt.get(i) == {"meta": 123}
365
+ ```
300
366
  """
301
367
  if self._store is None:
302
368
  raise ValueError("Cannot attach objects when track_objects=False")
@@ -309,6 +375,16 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
309
375
  def delete_by_object(self, obj: Any) -> bool:
310
376
  """
311
377
  Delete an item by Python object identity. Tracking must be enabled.
378
+
379
+ Args:
380
+ obj: The Python object to delete.
381
+
382
+ Example:
383
+ ```python
384
+ i = qt.insert((3.0, 4.0), obj="tag")
385
+ ok = qt.delete_by_object("tag")
386
+ assert ok is True
387
+ ```
312
388
  """
313
389
  if self._store is None:
314
390
  raise ValueError("Cannot delete by object when track_objects=False")
@@ -323,6 +399,13 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
323
399
 
324
400
  If tracking is enabled, the id -> object mapping is also cleared.
325
401
  The ids are reset to start at zero again.
402
+
403
+ Example:
404
+ ```python
405
+ _ = qt.insert((5.0, 6.0))
406
+ qt.clear()
407
+ assert qt.count_items() == 0 and len(qt) == 0
408
+ ```
326
409
  """
327
410
  self._native = self._new_native(self._bounds, self._capacity, self._max_depth)
328
411
  self._count = 0
@@ -333,6 +416,14 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
333
416
  def get_all_objects(self) -> list[Any]:
334
417
  """
335
418
  Return all tracked Python objects in the tree.
419
+
420
+ Example:
421
+ ```python
422
+ _ = qt.insert((7.0, 8.0), obj="a")
423
+ _ = qt.insert((9.0, 1.0), obj="b")
424
+ objs = qt.get_all_objects()
425
+ assert set(objs) == {"a", "b"}
426
+ ```
336
427
  """
337
428
  if self._store is None:
338
429
  raise ValueError("Cannot get objects when track_objects=False")
@@ -341,6 +432,13 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
341
432
  def get_all_items(self) -> list[ItemType]:
342
433
  """
343
434
  Return all Item wrappers in the tree.
435
+
436
+ Example:
437
+ ```python
438
+ _ = qt.insert((1.0, 1.0), obj=None)
439
+ items = qt.get_all_items()
440
+ assert hasattr(items[0], "id_") and hasattr(items[0], "geom")
441
+ ```
344
442
  """
345
443
  if self._store is None:
346
444
  raise ValueError("Cannot get items when track_objects=False")
@@ -349,12 +447,25 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
349
447
  def get_all_node_boundaries(self) -> list[Bounds]:
350
448
  """
351
449
  Return all node boundaries in the tree. Useful for visualization.
450
+
451
+ Example:
452
+ ```python
453
+ bounds = qt.get_all_node_boundaries()
454
+ assert isinstance(bounds, list)
455
+ ```
352
456
  """
353
457
  return self._native.get_all_node_boundaries()
354
458
 
355
459
  def get(self, id_: int) -> Any | None:
356
460
  """
357
461
  Return the object associated with id, if tracking is enabled.
462
+
463
+ Example:
464
+ ```python
465
+ i = qt.insert((1.0, 2.0), obj={"k": "v"})
466
+ obj = qt.get(i)
467
+ assert obj == {"k": "v"}
468
+ ```
358
469
  """
359
470
  if self._store is None:
360
471
  raise ValueError("Cannot get objects when track_objects=False")
@@ -364,6 +475,13 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
364
475
  def count_items(self) -> int:
365
476
  """
366
477
  Return the number of items currently in the tree (native count).
478
+
479
+ Example:
480
+ ```python
481
+ before = qt.count_items()
482
+ _ = qt.insert((2.0, 2.0))
483
+ assert qt.count_items() == before + 1
484
+ ```
367
485
  """
368
486
  return self._native.count_items()
369
487
 
Binary file
@@ -49,18 +49,6 @@ class QuadTree(_BaseQuadTree[Point, _IdCoord, PointItem]):
49
49
  track_objects=track_objects,
50
50
  )
51
51
 
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
52
  @overload
65
53
  def query(
66
54
  self, rect: Bounds, *, as_items: Literal[False] = ...
@@ -80,6 +68,13 @@ class QuadTree(_BaseQuadTree[Point, _IdCoord, PointItem]):
80
68
  Returns:
81
69
  If as_items is False: list of (id, x, y) tuples.
82
70
  If as_items is True: list of Item objects.
71
+
72
+ Example:
73
+ ```python
74
+ results = qt.query((10.0, 10.0, 20.0, 20.0), as_items=True)
75
+ for item in results:
76
+ print(f"Found point id={item.id_} at {item.geom} with obj={item.obj}")
77
+ ```
83
78
  """
84
79
  if not as_items:
85
80
  return self._native.query(rect)
@@ -50,18 +50,6 @@ class RectQuadTree(_BaseQuadTree[Bounds, _IdRect, RectItem]):
50
50
  track_objects=track_objects,
51
51
  )
52
52
 
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
53
  @overload
66
54
  def query(
67
55
  self, rect: Bounds, *, as_items: Literal[False] = ...
@@ -81,6 +69,13 @@ class RectQuadTree(_BaseQuadTree[Bounds, _IdRect, RectItem]):
81
69
  Returns:
82
70
  If as_items is False: list of (id, x0, y0, x1, y1) tuples.
83
71
  If as_items is True: list of Item objects.
72
+
73
+ Example:
74
+ ```python
75
+ results = rqt.query((10.0, 10.0, 20.0, 20.0), as_items=True)
76
+ for item in results:
77
+ print(f"Found rect id={item.id_} at {item.geom} with obj={item.obj}")
78
+ ```
84
79
  """
85
80
  if not as_items:
86
81
  return self._native.query(rect)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastquadtree
3
- Version: 1.2.0
3
+ Version: 1.2.3
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3 :: Only
6
6
  Classifier: Programming Language :: Rust
@@ -31,7 +31,7 @@ License-File: LICENSE
31
31
  Summary: Rust-accelerated quadtree for Python with fast inserts, range queries, and k-NN search.
32
32
  Keywords: quadtree,spatial-index,geometry,rust,pyo3,nearest-neighbor,k-nn
33
33
  Author: Ethan Anderson
34
- Requires-Python: >=3.8
34
+ Requires-Python: >=3.9
35
35
  Description-Content-Type: text/markdown
36
36
  Project-URL: Homepage, https://github.com/Elan456/fastquadtree
37
37
  Project-URL: Repository, https://github.com/Elan456/fastquadtree
@@ -45,6 +45,8 @@ Project-URL: Issues, https://github.com/Elan456/fastquadtree/issues
45
45
 
46
46
  Rust-optimized quadtree with a clean Python API
47
47
 
48
+ 👉 **Check out the Docs:** https://elan456.github.io/fastquadtree/
49
+
48
50
  [![PyPI](https://img.shields.io/pypi/v/fastquadtree.svg)](https://pypi.org/project/fastquadtree/)
49
51
  [![Python versions](https://img.shields.io/pypi/pyversions/fastquadtree.svg)](https://pypi.org/project/fastquadtree/)
50
52
  [![Downloads](https://static.pepy.tech/personalized-badge/fastquadtree?period=total&units=INTERNATIONAL_SYSTEM&left_color=GRAY&right_color=BLUE&left_text=Total%20Downloads)](https://pepy.tech/projects/fastquadtree)
@@ -64,7 +66,7 @@ Rust-optimized quadtree with a clean Python API
64
66
 
65
67
  ## Why use fastquadtree
66
68
 
67
- - Clean [Python API](https://elan456.github.io/fastquadtree/api/quadtree/) with no external dependencies and modern typing hints
69
+ - Clean [Python API](https://elan456.github.io/fastquadtree/api/quadtree/) with **no external dependencies** and modern typing hints
68
70
  - The fastest quadtree Python package ([>10x faster](https://elan456.github.io/fastquadtree/benchmark/) than pyqtree)
69
71
  - Prebuilt wheels for Windows, macOS, and Linux
70
72
  - Support for [inserting bounding boxes](https://elan456.github.io/fastquadtree/api/rect_quadtree/) or points
@@ -76,7 +78,6 @@ Rust-optimized quadtree with a clean Python API
76
78
 
77
79
  ----
78
80
 
79
- 👉 **Docs:** https://elan456.github.io/fastquadtree/
80
81
 
81
82
  ## Examples
82
83
  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.2.3.dist-info/METADATA,sha256=e0f4sEJZ-BgTh9khREHE9BtckrlT0k1fMg2JvW5NWis,9633
2
+ fastquadtree-1.2.3.dist-info/WHEEL,sha256=xBqaWU3Z-cfW-EFy0ENuEqxgXZXkIHUBkA1cT6FlqGM,127
3
+ fastquadtree-1.2.3.dist-info/licenses/LICENSE,sha256=pRuvcuqIMtEUBMgvP1Bc4fOHydzeuA61c6DQoQ1pb1w,1071
4
+ fastquadtree/__init__.py,sha256=rtkveNz7rScRasTRGu1yEqzeoJfLfreJNxg21orPL-U,195
5
+ fastquadtree/_base_quadtree.py,sha256=-umYxuVnKXd7jXcCU2VU2E55kdfUraVrhoN2lpbPQFI,15262
6
+ fastquadtree/_item.py,sha256=EDS3nJHdVtjDsuTqTZKGTZH8iWJIQ-TKxLXqvMScNPA,2405
7
+ fastquadtree/_native.abi3.so,sha256=L7seTFIykBK3bRbAFkQ767e6_12F99SdK3dgxBeUQv0,556588
8
+ fastquadtree/_obj_store.py,sha256=HeYFGUPYhvxBzL7Js0g0jsIxflpZS6RsXNk50rGeNlA,6522
9
+ fastquadtree/point_quadtree.py,sha256=AQKZaO14wrf2PX9QLV_mAC5EjqSOQ_csmzeKAK4fZHw,5632
10
+ fastquadtree/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ fastquadtree/pyqtree.py,sha256=2Khh1gCPalD4z0gb3EmqtzMoga08E9BkB0j5bwkiRPU,6076
12
+ fastquadtree/rect_quadtree.py,sha256=JN72J8kXasl9JHL3qgiDUBNRL2H-TnkB_mgRIUYzyfE,3482
13
+ fastquadtree-1.2.3.dist-info/RECORD,,
@@ -1,13 +0,0 @@
1
- fastquadtree-1.2.0.dist-info/METADATA,sha256=MUUv_93xtLD1Vbsm3t0JelXhuKt0VP1OmFlkQPcioHU,9614
2
- fastquadtree-1.2.0.dist-info/WHEEL,sha256=xBqaWU3Z-cfW-EFy0ENuEqxgXZXkIHUBkA1cT6FlqGM,127
3
- fastquadtree-1.2.0.dist-info/licenses/LICENSE,sha256=pRuvcuqIMtEUBMgvP1Bc4fOHydzeuA61c6DQoQ1pb1w,1071
4
- fastquadtree/__init__.py,sha256=rtkveNz7rScRasTRGu1yEqzeoJfLfreJNxg21orPL-U,195
5
- fastquadtree/_base_quadtree.py,sha256=ukiCKjsOPmnrkkKNLNJS5ad0X2HURYAWp9W60pk-c9Q,12045
6
- fastquadtree/_item.py,sha256=EDS3nJHdVtjDsuTqTZKGTZH8iWJIQ-TKxLXqvMScNPA,2405
7
- fastquadtree/_native.abi3.so,sha256=CVib-xgwo5sbXSJ5ypr25JmZ8u3reVrnivgamFeN-eM,556572
8
- fastquadtree/_obj_store.py,sha256=HeYFGUPYhvxBzL7Js0g0jsIxflpZS6RsXNk50rGeNlA,6522
9
- fastquadtree/point_quadtree.py,sha256=5ic-ZPq2AC20f9GkunKQAoH-W_doRFePOlJwqhST0FI,5697
10
- fastquadtree/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- fastquadtree/pyqtree.py,sha256=2Khh1gCPalD4z0gb3EmqtzMoga08E9BkB0j5bwkiRPU,6076
12
- fastquadtree/rect_quadtree.py,sha256=9JXqvh9WZGy7ZcfbXIRCWUf8oYpQz2QLB39f6XdP7u8,3559
13
- fastquadtree-1.2.0.dist-info/RECORD,,