>>> from env_helper import info; info()
页面更新时间: 2024-04-04 20:23:14
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-18-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

15.3. Python:Rtree 安转和使用

内容参考: https://blog.csdn.net/junqing_wu/article/details/106605158

15.3.1. 安装

在 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安转使用

15.3.2. 示例

Rtree 是一个 ctypes 的python包装 libspatialindex ,这为空间感兴趣的Python用户提供了许多高级空间索引功能。这些功能包括:

  1. 最近邻搜索

  2. 交叉点搜索

  3. 多维指标

  4. 聚集索引(直接用索引项存储python pickle)

  5. 散装装载

  6. 删除

  7. 磁盘序列化

  8. 自定义存储实现(例如,在zodb中实现空间索引)

参考自:Rtree文档

rtree模块有2个常用的类: rtree.index.Indexrtree.index.Property。 其中 rtree.index.Index 用于进行数据操作, rtree.index.Property 用于对index进行属性的设定。

当用rtree包进行三维及以上的维度索引数据到磁盘时会创建俩个索引文件,Rtree默认使用扩展名dat和idx。 可以使用 rtree.index.Property.dat_extensionrtree.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}
3    {'id': 3}
2    {'id': 2}
2    {'id': 2}
4    {'id': 4}
4    {'id': 4}
1    {'id': 1}
1    {'id': 1}

index.Index('case',overwrite=True) 第一个参数表示 存储到文件中,会生成case.dat 和 case.idx两个文件,overwrite表示是否覆盖之前的数据,如果为false,那么新插入的数据会追加到之前的文件中;