OracleでもGIS

なんだか、OracleGIS資料が少ない。APIが明確で必要ないのか何なのか
しかして、なんかリファレンス閲覧にはログインが要求されるみたいなんですけど…

サポートする形式は以下の通り
・点および点クラスタ
・線ストリング
・N点ポリゴン
・円弧線ストリング(すべての円弧は円の一部として生成される)
・円弧ポリゴン
・複合ポリゴン
・複合線ストリング
・円
・最適化された矩形
…複雑である
http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/appdev.102/B19243-02/geom_types.gif
ここに図解がある。こちらの方が分り易いか
色々種類があるが、流石に点と線と面は同居できない様子。というか捩れが発生しやすいポリゴンが色々と深く掘り下げられている
ちなみに、ポリゴンやラインの座標は外部の輪は反時計回り、内部の輪は時計回りである。つまり、反時計回りの座標内に時計回りの座標が存在していれば穴が空いたポリゴンを表現できる。いや、これはすごい
… でもね実際問題として付随するレタリング機構の問題になるような気もして…、どうやってこの特性が生かされるのか不明。いや、検索条件として定義する事で生きてくるんだろうが、うーむ。複数個の条件で定義するより単一の条件にした方が効率は上昇するだろうが互換性が低下する気がする

CREATE TABLE cola_markets (mkt_id NUMBER PRIMARY KEY,name VARCHAR2(32),shape SDO_GEOMETRY);

ジオメトリカラムを保持するテーブル作成クエリの例文
SDO_GEOMETRYがジオメトリ形式らしい。COLLECTIONは汎用ジオメトリで他の全ての形式を含む
とりあえず、形式は以下の通り
・POINT
一つの点を含むジオメトリ
・LINE、CURVE
LINEまたはCURVEの直線又は複合線を含む
・POLYGON
穴などが存在しない二次元的なポリゴン
・COLLECTION
他の全ての形式を持つ
・MULTIPOINT
接触しない複数個の点
・MULTILINEまたはMULTICURVE
ジオメトリにつき、ひとつ又は複数個のラインが存在している
・MULTIPOLYGON
複数個の面

INSERT INTO cola_markets VALUES(1, 'cola_a',
SDO_GEOMETRY(2003,--two-dimensional polygon NULL,NULL, 
SDO_ELEM_INFO_ARRAY(1,1003,3),--one rectangle(1003=exterior)
SDO_ORDINATE_ARRAY(1,1,5,7) --only 2 points needed to -- define rectangle(lower left and upper right)
with -- Cartesian-coordinate data));

これがインサートのクエリ(らしい)

--two-dimensional polygon NULL,NULL,SDO_ELEM_INFO_ARRAY(1,1003,3)

オプションを設定して格納しているのか。yとxは理解できるがその後の値は何なのか
そもそもコンソール仕様を拝んでないからソース見せつけられてもわけわかめですよ(大汗

面白い事に、ジオメトリカラムにもさらに細かい特性を付け加える事で入力される形式を制限できるらしい

CREATE INDEX cola_spatial_idx ON cola_markets(shape) INDEXTYPE IS 
MDSYS.SPATIAL_INDEX PARAMETERS ('layer_gtype=POLYGON');

これはジオメトリカラムの追加クエリ例文
layer_gtypeで制限する形式を定義している。この場合は=trueか
つまり、このジオメトリカラムに入力されたジオメトリは強制的に定義された形式で保存されるという事。ラインの場合はともかく、自己完結しているポイントの場合はどうなるのか?
なお、ジオメトリコレクションは下位を内包するので、MULTIPOINTを指定した場合はPOINTも記録可能である。COLLECTIONは全ての形式をサポートするので、全ての形式が記録可能になる

空間を条件にした検索ではMBRで判定されている
三角形や丸ではなく、それらを包み込む四角形で大体の判定がなされているのだ
一般的な(MySQLPostGIS)ではMBRでの検索はヒットした。Oracleさんはここがなんだか複雑だ

SELECT A.Feature_ID FROM TARGET A WHERE sdo_filter(A.shape,SDO_geometry(2003,NULL,NULL, 
SDO_elem_info_array(1,1003,3),SDO_ordinate_array(x1,y1, x2,y2))) = 'TRUE';

これはフィルタ機能を利用した一時問い合わせの例文
一時フィルターはオブジェクト同士の干渉のみを判定するフィルターらしい。つまり、実際に検索条件の空間を当て嵌めて考えるよりも高速である

SDO_FILTER(geometry1, geometry2, param);

が、一時フィルターを利用する関数で、空間索引を使用して、指定されたオブジェクト(対象領域など)と空間的に作用するオブジェクトの集合を識別したり、指定した2つのオブジェクトが相互作用するかどうかを判別する。非接続でないオブジェクトは、空間的に相互作用であることに注意
SDO_FILTERは接続関係にあるかどうかで真と偽を返す。上の例文では真である、つまり関係する事を条件式にしている

SELECT A.Feature_ID FROM TARGET A WHERE sdo_relate(A.shape, SDO_geometry(2003,NULL,NULL, 
SDO_elem_info_array(1,1003,3),SDO_ordinate_array(x1,y1, x2,y2)),'mask=anyinteract') = 'TRUE';

は一次と二次フィルターの例文
例文では条件空間に重なる、又はその内側に存在する空間を戻してくれる

つまり、一時はたとえば条件がラインストリングだった場合に外周のみしか返さない
二次と一次時の合同なら、望む全てが返されるという事。が、二次を適応する訳だから当然遅くなる。ならばポリゴンを条件空間とすることで速度と効率のupが図れるのではないか
…そう考えると穴あきポリゴンは生きてくるわけか…