博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
rtree的使用
阅读量:4947 次
发布时间:2019-06-11

本文共 4837 字,大约阅读时间需要 16 分钟。

安装

 

rtree可以看做是二维或者多维空间中的b树

如果不知道b树的建议先去看看b树

rtree的原理

两篇文章相同的

 

Python rtree官方文档

 

rtree中的基本单位是一个个小的矩形

在这个库中是一个类: rtree.index.Item

我这里主要写一下Pythonrtree的使用

初始化对象

from rtree import indexidx = index.Index()

 

插入数据: insert(self, id, coordinates, obj=None), 没有返回值

其中id是一个长整数,coordinates 是形如(xmin, ymin, xmax. ymax)的元组或者列表也可以,都是double类型的浮点数,和python的float相对应(python只有float,相当于c++中的double)

obj是可选的选项,可以是任意的一个Python对象,实际原理就是先将Python对象序列化以后再存储起来

idx.insert(0,(0,0,1,1), obj={1:4})

add方法和insert方法完全一样

In [226]: ctypes.c_double(10.0/3)Out[226]: c_double(3.3333333333333335)In [227]: 10.0/3Out[227]: 3.3333333333333335

大家看,c_double和python的float是相一致的,尽管放心

 

删除数据: delete(self, id, coordinates); 没有返回值

idx.delete(0,(0,0,1,1))

这个函数既需要id,又需要坐标值

如果没有目标点满足,不会报错,,也不会删除

如果有多个目标点满足的话,仅会删除一个(目测和插入顺序相关,但是请避免这种事情的发生)

 

查找区域内的元素intersection(self, coordinates, objects=False): 返回是一个生成器

In [243]: list(c.intersection((0,0,2,2), objects=False))Out[243]: [0, 0, 1]In [244]: list(c.intersection((0,0,2,2), objects=True))Out[244]: [
,
,
]In [245]: list(c.intersection((0,0,2,2), objects=False))Out[245]: [0, 0, 1]

仅仅是边界甚至是一个顶点有重叠也算是重叠,比如(0,0,1,1)和(1,1,2,2)算重叠

objects=False返回的是id, "raw"返回的是object,附带的python对象

True返回的是item对象,有['handle', 'owned', 'id', 'object', 'bounds']五个元素,后三种分别是id,object,范围, 前面的不太清楚,owned是一个布尔类型,handle是一个对象

In [249]: a = list(c.intersection((0,0,2,2), objects=True))[0]In [250]: a.boundsOut[250]: [0.0, 1.0, 0.0, 1.0]In [251]: a.idOut[251]: 0In [252]: a.objectOut[252]: 'b'In [253]: a.ownedOut[253]: False

奇怪的是a.bounds是一个(xmin, xmax, ymin, ymax)的形式

 

查找最近的元素nearest(self, coordinates, num_results=1, objects=False): 返回的是一个python 生成器

寻找最近的点,num_result是返回的点的个数,如果有多个点的距离相等,那么这些点都返回

返回的点按照从短到长来依次排列

据我实验,num_result=0和num_result=1等同,num_result=-1,-2...的时候全部的点都会列出来

据我推测,两个矩形之间的距离是这样计算的:两个矩形区域a,b;分别取一点p,q,距离d=min(pq),

我用Python实现了一个这个方法

def getRangeDistance(range1, range2):    """返回两个区间的最短距离,有重叠为0"""    if min(range1) > max(range2):        result = min(range1) - max(range2)        return result    if min(range2) > max(range1):        result = min(range2) - max(range1)        return result    return 0def getRectangleDistance(coordinates1, coordinates2):    """获得两个矩形之间距离的最短值"""    (xmin1, ymin1, xmax1, ymax1) = coordinates1    (xmin2, ymin2, xmax2, ymax2) = coordinates2    tmp1 = getRangeDistance((xmin1, xmax1), (xmin2, xmax2))    tmp2 = getRangeDistance((ymin1, ymax1), (ymin2, ymax2))    distance =  (tmp1 **2 + tmp2 **2) ** 0.5    return distance

实验结果如下

In [283]: list(c.nearest((10,10,19,19), num_results=-2))Out[283]: [1, 0, 0, 3]In [284]: list(f.nearest((0,0,0.9,0.9), num_results=0))Out[284]: []In [285]: list(c.nearest((0,0,0.9,0.9), num_results=1))Out[285]: [0, 0]In [286]: list(c.nearest((0,0,0.9,0.9), num_results=2))Out[286]: [0, 0]In [287]: list(c.nearest((0,0,0.9,0.9), num_results=3))Out[287]: [0, 0, 1]In [288]: list(c.nearest((0,0,0.9,0.9), num_results=4))Out[288]: [0, 0, 1, 3]In [289]: list(c.nearest((0,0,0.9,0.9), num_results=5))Out[289]: [0, 0, 1, 3]

当是空树时候无论如何都会返回一个空的生成器

 

查找某个范围内的对象个数 count(self, coordinates): 返回是一个长整数

In [291]: c.count((1,1,2,2))Out[291]: 3L

 

获得r树的范围get_bounds(self, coordinate_interleaved=None), 获得的是整个r树的范围

:param coordinate_interleaved: If True, the coordinates are turnedin the form [xmin, ymin, ..., kmin, xmax, ymax, ..., kmax],otherwise they are returned as[xmin, xmax, ymin, ymax, ..., ..., kmin, kmax]. If not specified,the :attr:`interleaved` member of the index is used, whichdefaults to True.

None的时候是由self.interleaved决定的,这个是r树生成时的参数默认是True

 

获得节点信息levels(self), 返回是一个列表,元素是(id, child_ids, bounds)

虽然名字叫做叶子节点但是实际上并不能搞得清楚是什么意思

In [295]: c.leaves()Out[295]: [(0, [0, 0, 1, 3], [-1.0, -1.0, 2.0, 2.0])]

太少了,看不清楚,再多加几个看一看

n [296]: for i in range(4,100):     ...:     c.insert(i,(i,i,i+0.5,i+0.5))     ...:     In [297]: c.leaves()Out[297]: [(0,  [0,   0,   1,   3,   4,   5,   6,   7,   8,   9,   10,   11,   12,   13,   14,   15,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   40,   41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,   52,   53,   54,   55,   56,   57,   58,   59,   60,   61,   62,   63,   64,   65,   66,   67,   68,   69,   70,   71,   72,   73,   74,   75,   76,   77,   78,   79,   80,   81,   82,   83,   84,   85,   86,   87,   88,   89,   90,   91,   92,   93,   94,   95,   96,   97,   98,   99],  [-1.0, -1.0, 99.5, 99.5])]

什么鬼,再加几个

for i in range(4,10000):            ...:     c.insert(i,(i,i,i+0.5,i+0.5))

过程略,

最后的结论就是这些id是叶子节点的上一层节点的信息,一个叶子节点至少有50个元素;所以至多应该是100个,最后的四个元素的列表是这个区域的范围

 

dumps是序列化,但是我们不要用这个对树进行序列化,因为叶子节点会丢失掉,这个只是调用的Python的pickle的dump序列化而已;序列化是序列内存空间的,就好像你序列化一个二叉树的一个节点,但是这个节点不包括他的子子节点内容,所以你在另一个文件中载入这个序列化,就不能知道他的子节点的内容信息,要用rtree自带的存储方法,

就到这吧

转载于:https://www.cnblogs.com/mangmangbiluo/p/11092518.html

你可能感兴趣的文章
三剑客-grep
查看>>
Keycloak集成三方身份提供者的注销流程
查看>>
ASP.NET5 静态文件
查看>>
ubuntu-12.04.5-desktop-i386.iso:ubuntu-12.04.5-desktop-i386:安装Oracle11gR2
查看>>
hdu4333(扩展KMP)
查看>>
C# datatable数据导出为excel,并解决长数据变为科学计数法问题
查看>>
CF 某套题 O :Grid (简单BFS)
查看>>
C# partial关键字详解
查看>>
hdu 1907 John (anti—Nim)
查看>>
WebLogic XMLDecoder反序列化漏洞复现
查看>>
雅虎前端优化军规
查看>>
python & go 语言完成最简单的web应用
查看>>
获取IMEI码
查看>>
实现自己的脚本语言ngscript之一:词法分析
查看>>
缓存测试分享篇:如何利用测试环境进行灰度测试缓存迁移solo
查看>>
经常使用的数据挖掘软件/软件包大盘点
查看>>
配置EditPlus的JAVA编译环境
查看>>
界面跳转
查看>>
爱情,这种高级玩意儿--一个码农的自白
查看>>
【leetcode】【189】Rotate Array
查看>>