2

我正在尝试将 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 数组协议的对象。

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

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

还确认可以使用xmin == xmax和来索引点ymin == ymax

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

4

1 回答 1

4

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

它正在删除与它在叶子中找到的匹配的第一个对象idLeaf::deleteData(如果你不相信我,请检查 libspatialindex 源代码)。坐标仅用于查找要从中删除的正确叶子。你所有的ids 都是0,所以它总是从叶子中删除第一个元素。后面的删除失败,因为你的树的边界框是 now [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 不需要是唯一的才能插入到索引中,如果需要,用户可以确保它们是唯一的。
  • 坐标 - 序列或数组 Dimension * 2 坐标对,表示要从索引中删除的项目的每个维度中的最小和最大坐标。它们的顺序将取决于索引的交错数据成员。这些不是包含项目的空间的坐标,而是项目本身的坐标。它们与 id 参数一起确定将删除哪个项目。这可能是一个满足 numpy 数组协议的对象。

(强调补充。)

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

于 2014-12-26T21:15:02.057 回答