"""Module for binary space partitioning, to facilitate optimal runtime complexity for n-pointproblems."""importabcfromrtreeimportindexasrtree
[docs]classBoxTreeInterface(abc.ABC):""" Tree for fast lookup of queries of axis aligned rhomboids. """
[docs]@abc.abstractmethoddefquery(self,boxes,unique=False):""" Should return a generator that yields lists of intersecting IDs per query box if ``unique=False``. If ``unique=True``, yield a flat list of unique intersecting box IDs for all queried boxes. """pass
@abc.abstractmethoddef__len__(self):pass
[docs]class_BoxRTree(BoxTreeInterface):""" Tree for fast lookup of queries of axis aligned rhomboids using the Rtree package. """def__init__(self,boxes):self._rtree=rtree.Index(properties=rtree.Property(dimension=3))forid,boxinenumerate(boxes):self._rtree.insert(id,box)def__len__(self):returnlen(self._rtree)defquery(self,boxes,unique=False):""" Given an iterable of ``(min_x, min_y, min_z, max_x, max_y, max_z)`` box tuples, find all the boxes that intersect with them. :param boxes: Boxes to look for intersections with. :type boxes: Iterable[Tuple[float, float, float, float, float, float]] :param unique: If ``True``, return a flat generator of unique results. If ``False`` (default), per box in ``boxes``, return a list of intersecting boxes. :returns: See ``unique``. :rtype: Union[Iterator[List[Tuple[float, float, float, float, float, float]]], Iterator[Tuple[float, float, float, float, float, float]]] """all_=(list(self._rtree.intersection(box,objects=False))forboxinboxes)ifunique:seen=set()# Double for loop over results, skipping those that have been seen before.yield from(seen.add(elem)orelemforarrinall_foreleminarrifelemnotinseen)else:yield fromall_
# Cheapo provider pattern.
[docs]classBoxTree(_BoxRTree):""" Tree for fast lookup of repeat queries of axis aligned rhomboids. """pass