def add(self, item, bounds, data=None, debug=False): """ Add an item to the tree. If an item already exists, its bounds are updated and the item is moved to the right bucket. Data can be used to add some extra info to the item """ # Clip item bounds to fit in top-level bucket # Keep original bounds in _ids, for reference clipped_bounds = rectangle_clip(bounds, self._bucket.bounds) if item in self._ids: old_clip = self._ids[item][2] if old_clip: bucket = self._bucket.find_bucket(old_clip) assert item in bucket.items if bucket and rectangle_contains(bounds, bucket.bounds): bucket.update(item, old_clip, clipped_bounds) self._ids[item] = (bounds, data, clipped_bounds) return elif bucket: bucket.find_bucket(old_clip).remove(item) if clipped_bounds: self._bucket.find_bucket(clipped_bounds).add(item, clipped_bounds) self._ids[item] = (bounds, data, clipped_bounds)
def add(self, item, bounds, data=None): """ Add an item to the tree. If an item already exists, its bounds are updated and the item is moved to the right bucket. Data can be used to add some extra info to the item """ # Clip item bounds to fit in top-level bucket # Keep original bounds in _ids, for reference clipped_bounds = rectangle_clip(bounds, self._bucket.bounds) if item in self._ids: old_clip = self._ids[item][2] if old_clip: bucket = self._bucket.find_bucket(old_clip) assert item in bucket.items # Fast lane, if item moved just a little it may still reside # in the same bucket. We do not need to search from top-level. if bucket and clipped_bounds and \ rectangle_contains(clipped_bounds, bucket.bounds): bucket.update(item, clipped_bounds) self._ids[item] = (bounds, data, clipped_bounds) return elif bucket: bucket.remove(item) if clipped_bounds: self._bucket.find_bucket(clipped_bounds).add(item, clipped_bounds) self._ids[item] = (bounds, data, clipped_bounds)
def rebuild(self): """ Rebuild the tree structure. """ # Clean bucket and items: self._bucket.clear() for item, (bounds, data, _) in dict(self._ids).iteritems(): clipped_bounds = rectangle_clip(bounds, self._bucket.bounds) if clipped_bounds: self._bucket.find_bucket(clipped_bounds).add(item, clipped_bounds) self._ids[item] = (bounds, data, clipped_bounds)