我试着在树上存储二维点。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–long integer是此索引的标识符的长整数
进入。id不需要唯一才能插入索引,它是
如果这是一项要求,则由用户来确保它们是唯一的。
坐标-序列或数组维度*2个坐标对,
表示项目的每个维度中的最小和最大坐标
从索引中删除。他们的命令将取决于
索引的交错数据成员。这些不是
包含项的空间,但包含项本身的空间。一起
id参数决定要删除的项。今年五月
成为满足numpy数组协议的对象。
但是可以看到,在输出的第4行中删除了具有给定的id但不在给定坐标内的点。
文档还清楚地指定了ids在插入或删除时不需要是唯一的。(示例中重复的0 == id是故意的,因为我的应用程序需要重复的ids。同一“事物”需要多个点。)
还确认了可以使用xmin == xmaxymin == ymax索引点。
我是否使用了错误的库,或者libspacealindex(Python rtree背后的二进制库)的行为与rtree文档的状态不同?

最佳答案

不要将重复的id分配给不同的对象。
它正在删除在叶中找到的匹配id的第一个对象(检查libspacealindex源代码,如果不信任我,Leaf::deleteData)。坐标仅用于查找要从中删除的正确叶。所有的id都是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–long integer是此索引项的标识符。id不必是唯一的就可以插入到索引中,如果这是一个要求,则由用户来确保它们是唯一的。
坐标–序列或数组维度*2个坐标对,表示要从索引中删除的项的每个维度中的最小和最大坐标它们的顺序将取决于索引的交错数据成员。这些不是包含项的空间的坐标,而是项本身的坐标。它们与id参数一起决定要删除哪个项。这可能是满足numpy数组协议的对象。
(强调的是。)
这并不是说id不需要唯一才能删除。它说你可以用同一个id插入多个条目,但是它没有说删除是可预测的。;—)同样,“确定”也是模糊的。坐标用于找到正确的叶,然后删除该叶中的第一个匹配id。(从libspacealindex的源代码判断)因此,id必须是唯一的,删除才能可靠地工作。

09-25 18:19
查看更多