概要
ArcObjectsのサンプルプログラムで提供している空間検索はArcMapと比較するとパフォーマンスが悪い。特に大量のデータ(数十万件)に対する場合だと差が歴然となる。
http://www.esrij.com/support/arcobjects/samples/Geodatabase/Accessing_Data/PerformSpatialQuery.html
ここでは空間検索をより高速に行う方法について解説する。
処理方法
できるだけ早く検索を行う方法として
ISpatialIndexを利用
これにより速度は劇的に改善される。 検索用ジオメトリを用意し、SpatialFilterへ渡す前に以下のコードを実行する。
ISpatialFilter::GeometryFieldを指定
ジオデータベースの場合はGeometryFieldを指定しなければ“非常に“遅くなる。シェープファイルの場合は指定した時としない時の違いは見られない。
GeometryBagの使用
検索用ジオメトリをひとつ用意して1回で検索する方法と複数のジオメトリをひとつひとつ使って検索をして選択結果を次々に足していく方法(SelectFeaturesの第2引数をesriSelectionResultAddにして選択結果を追加していく方法)とでは、1回で検索した方が速く処理できる。&br; 検索用ジオメトリの作成の方法では(選択セットのフィーチャで検索すると仮定します)
選択セット内でカーソルを取得してカーソルをまわしてGeometryBagにジオメトリを追加する方法
IEnumGeometryBind::BindGeometrySourceを使用して選択セットのジオメトリをひとつにまとめて、まとめられた列挙型のジオメトリからジオメトリを作成(geomtryBagができる)する方法はどちらも大差なし。ただしどちらも最初の一回目の検索は遅く、2回目の検索から同程度の速度が出る。
この方がカーソルをぐるぐる回さずにエレガントな感じがするので、私はこちらを使っていましたがパフォーマンスに違いはなさそうです。
サンプルコード
補足
過去にISpatialIndexに関する不具合(CQ00196129)が登録されているが、ESRIに問い合わせたところ、現在ISpatialIndexに不具合はない”はず”との見解だった。
「に完全に含まれる」 ポリゴン同士だとISpatialIndexを作成しても処理時間が非常にかかる。ポリゴンからITopologicalOperator:Boundaryでラインを取得し、これをインターセクトするとArcMap並みの速さが得られる。