2

2D ポイントを rtree (ver. 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 ):

指定された座標内の指定された「id」を持つインデックスから項目を削除します

パラメーター:

id – long integer このインデックス エントリの識別子である long integer。インデックスに挿入する ID は一意である必要はありません。ID が一意である必要がある場合は、ユーザーが一意であることを確認する必要があります。

座標– シーケンスまたは配列 ディメンション * インデックスから削除する項目の各次元の最小座標と最大座標を表す 2 つの座標ペア。それらの順序は、インデックスのインターリーブ データ メンバーによって異なります。これらは、アイテムを含む空間の座標ではなく、アイテム自体の座標です。id パラメータとともに、削除する項目を決定します。これは、numpy 配列プロトコルを満たすオブジェクトである可能性があります。

idしかし、ご覧のとおり、指定されたが指定された座標内にないポイントが、出力の 4 行目で削除されています。

idドキュメントはまた、挿入または削除のいずれにおいても s が一意である必要がないことを明確に指定しています。(この例で繰り返さ0 == idれているのは、私のアプリケーションでは重複したids が必要なため、意図的なものです。同じ「もの」に対して複数のポイントが必要です。)

xmin == xmaxまた、とを使用して点をインデックスできることも確認しましたymin == ymax

ライブラリの使い方が間違っているのでしょうか、それとも libspatialindex (Python rtree の背後にあるバイナリ ライブラリ) の動作が rtree ドキュメントの状態と異なるのでしょうか?

4

1 に答える 1

4

id異なるオブジェクトに重複を割り当てないでください。

リーフで見つかった一致する最初のオブジェクトをid削除しています(Leaf::deleteData信頼できない場合は、libspatialindex ソース コードを確認してください)。座標は、から削除する正しい葉を見つけるためにのみ使用されます。あなた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 このインデックス エントリの識別子である long integer。インデックスに挿入する ID は一意である必要はありません。ID が一意である必要がある場合は、ユーザーが一意であることを確認する必要があります。
  • 座標 – シーケンスまたは配列 ディメンション * インデックスから削除するアイテムの各次元の最小座標と最大座標を表す 2 つの座標ペア。それらの順序は、インデックスのインターリーブ データ メンバーによって異なります。これらは、アイテムを含む空間の座標ではなく、アイテム自体の座標です。id パラメータとともに、削除する項目を決定します。これは、numpy 配列プロトコルを満たすオブジェクトである可能性があります。

(強調を追加しました。)

これは、 が削除のために一意である必要がないということではありませ。同じ. ;-) 「決定」も曖昧です。座標は正しい葉を見つけるために使用され、この葉で最初に一致したものが削除されます。(libspatialindex のソース コードから判断すると) したがって、削除が確実に機能するには、 が一意である必要がありますidididid

于 2014-12-26T21:15:02.057 に答える