Source code for stompy.spatial.kdtree_spatialindex

# A wrapper around scipy.spatial's kdtree to make it look like 
# the python rtree / spatialindex implementation

from scipy.spatial import KDTree

[docs]class RtreeKDTree(object): """ wrap scipy KDTree spatial index to look as much like Rtree class as possible """ def __init__(self,stream,interleaved=False): """ stream: an iterable, returning tuples of the form (id,[xmin,xmax,ymin,ymax],object) for now, requires that xmin==xmax, and ymin==ymax For now, only interleaved=False is supported. """ if interleaved: raise Exception("No support for interleaved index. You must use xxyy ordering") it = iter(stream) self.points = [] self.data = [] for fid,xxyy,obj in it: if xxyy[0]!=xxyy[1] or xxyy[2]!=xxyy[3]: raise Exception("No support in kdtree for finite sized objects") self.points.append([xxyy[0],xxyy[2]]) self.data.append( (fid,obj) ) self.refresh_tree()
[docs] def refresh_tree(self): self.kdt = KDTree(self.points)
[docs] def nearest(self, rect, count): xy = [rect[0],rect[2]] dists,results = self.kdt.query( xy,k=count ) if count == 1: dists=[dists] results=[results] return [self.data[r][0] for r in results]
[docs] def intersects(self,xxyy): """ This should be made compatible with the regular RTree call... """ raise Exception("Intersects is not implemented in scipy.KDTree") return []
[docs] def insert(self, feat_id, rect=None ): if rect[0]!=rect[1] or rect[2]!=rect[3]: raise Exception("No support in kdtree for finite sized objects") if rect is None: raise Exception("Not sure what inserting an empty rectangle is supposed to do...") self.points.append( [rect[0],rect[2]] ) self.data.append( [feat_id,None] ) self.refresh_tree()
[docs] def feat_id_to_index(self,feat_id): for i in range(len(self.data)): if self.data[i][0] == feat_id: return i raise Exception("feature id not found")
[docs] def delete(self, feat_id, rect ): index = self.feat_id_to_index(feat_id) del self.data[index] del self.points[index] self.refresh_tree()