zoukankan      html  css  js  c++  java
  • rtree的使用

    安装https://www.cnblogs.com/mangmangbiluo/p/10954836.html

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

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

    rtree的原理https://blog.csdn.net/xiaofengcanyuexj/article/details/41912169

    https://blog.csdn.net/houzuoxin/article/details/16113895

    两篇文章相同的

    Python rtree官方文档

    http://toblerity.org/rtree/index.html#

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

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

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

    初始化对象

    from rtree import index
    
    idx = 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/3
    Out[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]: 
    [<rtree.index.Item at 0x7f6ffc60b8e8>,
     <rtree.index.Item at 0x7f6ffc60b3c0>,
     <rtree.index.Item at 0x7f6ffc60b628>]
    
    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.bounds
    Out[250]: [0.0, 1.0, 0.0, 1.0]
    
    In [251]: a.id
    Out[251]: 0
    
    In [252]: a.object
    Out[252]: 'b'
    
    In [253]: a.owned
    Out[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 0
    
    def 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 turned
    in 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, which
    defaults 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自带的存储方法,

    http://toblerity.org/rtree/tutorial.html

    就到这吧

  • 相关阅读:
    [FPGA与ASIC] 优化方法
    学习《中医药治疗热病的作用机理(韩晶岩)》的体会
    使用Capture CIS Lite仿真电路
    Everything软件-集本地文件搜索、文件服务器、批量操作文件等若干功能于一身的高效率软件
    注册表改右键菜单和默认程序
    Qt Quick开发教程4-QML拖放
    Qt Quick开发教程4--使用第三方QML UI包
    个人 PC/Android 常用软件列表
    Qt Quick开发教程3-C++与QML联合开发
    Qt Quick开发教程2-QML语法
  • 原文地址:https://www.cnblogs.com/mangmangbiluo/p/11092518.html
Copyright © 2011-2022 走看看