【问题标题】:Remove 2D points from rtree in Python从 Python 中的 rtree 中删除 2D 点
【发布时间】:2014-12-26 17:57:40
【问题描述】:

我正在尝试将 2D 点存储在 rtree(版本 0.8.2)中,然后使用 Python 删除它们。我知道 rtree 适用于矩形(或 3D 框),但我猜点是矩形的子集。

从 rtree 中删除项目时出现奇怪的行为。下面的脚本显示了这种行为:

from rtree import index as rtindex

def pt2rect(pt):
    return pt[0], pt[1], pt[0], pt[1]

pts = [(0.0, 0.0), (1.0, 1.0), (0.0, 1.0)]
rt = rtindex.Index()

# Add the points
[rt.add(0, pt2rect(pt)) for pt in pts]
print [r.bbox for r in list(rt.nearest((0, 0), 10, True))]

# Remove the same points
for pt in pts:
    rt.delete(0, pt2rect(pt))
    print pt2rect(pt), [r.bbox for r in list(rt.nearest((0, 0), 10, True))]

输出是:

True
[[0.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 1.0], [1.0, 1.0, 1.0, 1.0]]  # Whole index
(0.0, 0.0, 0.0, 0.0) [[0.0, 1.0, 0.0, 1.0], [1.0, 1.0, 1.0, 1.0]]  # <-- Ok
(1.0, 1.0, 1.0, 1.0) [[1.0, 1.0, 1.0, 1.0]]  # <-- Wrong point deleted!
(0.0, 1.0, 0.0, 1.0) [[1.0, 1.0, 1.0, 1.0]]  # <-- Ok, as it's not found.

来自文档 (http://toblerity.org/rtree/class.html):

delete(id, coordinates) 从给定的索引中删除项目 'id' 在指定坐标内。

参数:

id – 长整数 一个长整数,它是该索引的标识符 入口。插入索引的 ID 不必是唯一的,它是 如果这是要求,则由用户确保它们是唯一的。

坐标 – 序列或数组 Dimension * 2 个坐标对, 表示项目每个维度的最小和最大坐标 从索引中删除。他们的顺序将取决于 索引的交错数据成员。这些不是坐标 包含项目的空间,但项目本身的空间。和...一起 id 参数,它们确定将删除哪个项目。这可能 是满足numpy数组协议的对象。

但是可以看出,在输出的第 4 行中删除了具有给定 id 但不在给定坐标内的点。

文档还明确指出ids 在插入或删除中不需要是唯一的。 (示例中重复的0 == id 是故意的,因为我的应用程序需要重复的ids。同一“事物”的多个点。)

还确认可以使用xmin == xmaxymin == ymax 对点进行索引。

是我使用了错误的库,还是 libspatialindex(Python rtree 背后的二进制库)的行为与 rtree 文档状态不同?

【问题讨论】:

    标签: python r-tree


    【解决方案1】:

    不要将重复的id 分配给不同的对象。

    它正在删除它在叶子中找到的与id 匹配的第一个对象(如果您不信任我,请查看 libspatialindex 源代码,Leaf::deleteData)。 坐标仅用于查找要删除的正确。你所有的ids 都是0,所以它总是从叶子中删除第一个元素。后面的删除失败,因为你的树的边界框现在是[0.0,1.0,1.0,1.0],y=0.0 的点不能在这个叶子中。

    试试

    [rt.add(id, [x[0], x[1], x[0], x[1]]) for id, x in enumerate(pts)]
    

    for id, x in enumerate(pts):
        rt.delete(id, [x[0], x[1], x[0], x[1]])
        print [x.bbox for x in list(rt.nearest([0, 0], 10, True))]
    

    请注意,rtree 模块的文档具有误导性

    从索引中删除指定坐标内具有给定 'id' 的项目。

    参数:

    • id – 长整数 一个长整数,它是该索引条目的标识符。 ID 不必是唯一的插入到索引中,如果需要,用户可以确保它们是唯一的。
    • coordinates – 序列或数组 Dimension * 2 坐标对,表示要从索引中删除的项目的每个维度中的最小和最大坐标。它们的顺序将取决于索引的交错数据成员。这些不是包含项目的空间的坐标,而是项目本身的坐标。它们与 id 参数一起确定将删除哪个项目。这可能是一个满足 numpy 数组协议的对象。

    (已添加重点。)

    不是id对于删除不需要是唯一的。它说您可以插入多个具有相同id 的条目,但它并没有说删除是可以预测的。 ;-) “确定”也是模糊的。坐标用于找到正确的叶子,然后删除该叶子中第一个匹配的id。 (从 libspatialindex 的源代码来看)因此,id 必须是唯一的,删除才能可靠地工作

    【讨论】:

    • 您的回答没有解释观察到的行为,也没有提供解释背后的任何理由。
    • 当然可以。您总是以这种方式删除第一个对象。尝试使用不同的ids,它会起作用。删除不检查坐标,它使用坐标定位正确的叶节点,然后删除该叶中第一个匹配的id
    • 故意使用公共 id,因为要添加的点都属于同一个对象,该对象在列表中的一个索引下。如果这不可能,您能否解释原因或指出一些参考资料?而且,如果您查看输出,有时预期的矩形没有被删除,而在其他情况下,错误的矩形被删除或什么都没有。怎么回事?
    • 您说“不要将重复的 id 分配给不同的对象。”,而文档说:“ID 不必是唯一的才能插入到索引中。”
    • 删除Leaf::deleteData(使用源代码,luke)只使用id。后来的删除并没有删除,因为叶子边界框不再包含您的坐标;因此不考虑叶子。但显然,你不想得到帮助......
    猜你喜欢
    • 1970-01-01
    • 2018-11-05
    • 2014-04-19
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 2018-12-21
    • 2021-12-13
    • 2019-06-27
    相关资源
    最近更新 更多