我正在尝试在rtree(版本0.8.2)中存储2D点,然后使用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):
删除(id,coordinates)使用给定的索引删除索引中的项目 指定坐标内的“id”。
参数:
id - long integer一个长整数,是此索引的标识符 条目。 ID不必是唯一的,可以插入到索引中,它就是 如果需要,由用户确保它们是唯一的。
坐标 - 序列或数组Dimension * 2坐标对, 表示项目每个维度的最小和最大坐标 要从索引中删除。他们的订购将取决于 index的交错数据成员。这些不是a的坐标 包含项目的空间,但项目本身的空间。和...一起 id参数,它们确定将删除哪个项目。这可能 是一个满足numpy数组协议的对象。
但是可以看出,在输出的第4行中删除了给定id
但不在给定坐标内的点。
文档还明确指出id
在插入或删除时不需要是唯一的。 (示例中重复的0 == id
是故意的,因为我的应用程序我需要重复id
s。同一“事物”的多个点。)
同时确认可以使用xmin == xmax
和ymin == ymax
索引点数。
我使用的库是错误的,还是libspatialindex(Python rtree背后的二进制库)的行为与rtree docs的状态不同?
答案 0 :(得分:4)
不要将重复的id
分配给不同的对象。
它正在删除它在叶子中找到的匹配id
的第一个对象(如果您不信任我,请检查libspatialindex源代码,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不必是唯一的插入到索引中,并且如果需要,则由用户确定它们是唯一的。
- 坐标 - 序列或数组Dimension * 2个坐标对,表示要从索引中删除的项目的每个维度中的最小和最大坐标。它们的排序取决于索引的交错数据成员。这些不是包含项目的空间的坐标,而是项目本身的坐标。与id参数一起,他们确定将删除哪个项目。这可能是满足numpy数组协议的对象。
(强调补充。)
不表示删除不需要id
唯一。它表示您可以使用相同的id
插入多个条目,但它并不表示删除是可预测的。 ;-)同样“确定”是模糊的。坐标用于查找正确的叶子,然后删除此叶子中的第一个匹配id
。 (从libspatialindex的源代码判断)因此, id
必须是唯一的,以便删除才能可靠地工作。