内容参考: https://blog.csdn.net/junqing_wu/article/details/106605158
安装
在 Debian 中,可以直接通过以下命令安装:
python3-rtree
编译安装
Linux在安装python库Rtree时, pip install Rtree,会提示未定义符号,因为电脑缺少必要的C库。
参考这个网页的步骤:http://toblerity.org/rtree/install.html#nix
先下载对应的libspatialindex安装包,下载地址:http://libspatialindex.github.io/ spatialindex-src-1.9.3.tar.gz (md5),解压后进入对应文件夹,依次执行
mkdir build
cd build
cmake ..
make
make install
这个时候就安转成功依赖库了;再次pip install Rtree 就可以了。
如果是非root用户,建议在make install 的时候自定义一个路径,因为/usr/local你没有权限写入,参考这样make DESTDIR=/install/directory install ,其中Destdir 填写你的指定目录,但是这样安转以后,需要自己修改环境变量,以便可以找到库
翻阅Rtree的源文件,我们发现它在加载spatialindex时,其实是通过这个环境变量SPATIALINDEX_C_LIBRARY加载的,我们直接定义这个环境变量为 你指定安装的目录即可;
vim ~/.bashrc
export SPATIALINDEX_C_LIBRARY = /home/linuxbrew/.linuxbrew/Cellar/spatialindex
source ~/.bashrc
然后再次pip install Rtree就可以了
Mac
直接 brew install spatialindex即可安转依赖库,Linux下也有相应的LinuxBrew,使用方法和Mac一致,具体可以参考这个 LinuxBrew安转使用
示例
Rtree 是一个 ctypes 的python包装 libspatialindex ,这为空间感兴趣的Python用户提供了许多高级空间索引功能。这些功能包括:
- 最近邻搜索
- 交叉点搜索
- 多维指标
- 聚集索引(直接用索引项存储python pickle)
- 散装装载
- 删除
- 磁盘序列化
- 自定义存储实现(例如,在zodb中实现空间索引)
参考自:Rtree文档
rtree模块有2个常用的类: rtree.index.Index
和 rtree.index.Property
。
其中 rtree.index.Index
用于进行数据操作, rtree.index.Property
用于对index进行属性的设定。
当用rtree包进行三维及以上的维度索引数据到磁盘时会创建俩个索引文件,Rtree默认使用扩展名dat和idx。
可以使用 rtree.index.Property.dat_extension
和 rtree.index.Property.idx_extension
来控制索引文件的扩展名。
其中 .idx
是索引文件, .dat
是数据文件。
from rtree import index
# 主要使用 rtree.index.Index 和 rtree.index.Property . 用户操纵这些类与索引交互。
# 构建 RTree 实例对象
idx = index.Index()
# 插入索引 insert(id, coordinates, obj=None):
# 其中coordinates为坐标顺序,按照 [xmin, xmax, ymin, ymax,…,……、kmin kmax]
left, bottom, right, top = (0.0, 0.0, 1.0, 1.0)
idx.insert(0, (left, bottom, right, top))
# 查询索引
# 查询索引有三种主要方法。:
# 1. 交叉 rtree.index.Index.intersection() 给定一个窗口,返回包含该窗口的ID
list(idx.intersection((1.0, 1.0, 2.0, 2.0)))
# 2. 最近邻
# 给定界限最近的1个项。如果多个项目与边界的距离相等,则返回两个项目,自定义想要寻找的最近邻个数
list(idx.nearest((1.0000001, 1.0000001, 2.0, 2.0), 1))
[0]
使用实例
from rtree import index
class MyIndex():
def __init__(self,idx):
self.id = idx
class Rtree():
def __init__(self):
self.p = index.Property()
self.p.dimension = 4 # 设置 使用的 维度数 (对于地图)
self.p.dat_extension = 'data' # 设置存储的后缀名
self.p.idx_extension = 'index' # 设置存储的后缀名
## interleaved=False时,bbox must be [xmin, xmax, ymin, ymax,…,……、kmin kmax]
self.rtree = index.Index('case',interleaved=False,property=self.p,overwrite=False)
self.rtree.insert(1, (0, 0, 1,1),obj=MyIndex(1))
self.rtree.insert(2, (0, 0, 4,4),obj=MyIndex(2))
self.rtree.insert(3, (0, 0, 5,5),obj=MyIndex(3))
self.rtree.insert(4, (0, 0, 6,6),obj=MyIndex(4))
self.rtree.insert(5, (0, 0, 7,7),obj=MyIndex(5))
# objects == True 时,返回包括obj在内的数据,否则只返回目标 id
def get_nearby_obj(self,width,num):
res=list(self.rtree.nearest(width,num,objects=True))
return res
def main():
ass=Rtree()
hits = ass.get_nearby_obj((0,0,5,5),3)
for x in hits:
print(x.id,'\t',x.object.__dict__)
hits = ass.get_nearby_obj((0,0,1,1),2)
for x in hits:
print(x.id,'\t',x.object.__dict__)
main()
3 {'id': 3} 2 {'id': 2} 4 {'id': 4} 1 {'id': 1} 2 {'id': 2}
index.Index('case',overwrite=True)
第一个参数表示 存储到文件中,会生成case.dat 和 case.idx两个文件,overwrite表示是否覆盖之前的数据,如果为false,那么新插入的数据会追加到之前的文件中;