ポイント,ライン,ポリゴン,マルチポイント,マルチライン,マルチポリゴン,ジオメトリ集合を登録することができます.これらは,Open GIS WellKnownテキストフォーマット(3次元拡張付)に記述されています.
最初に,GISデータを保持するための"geometry"タイプのカラムを持つテーブ ルを作る必要があります.psqlでデータベースに接続し,以下のSQLを試してください:
CREATE TABLE gtest ( ID int4, NAME varchar(20) ); SELECT AddGeometryColumn('dbname','gtest','geom',-1,'LINESTRING',2); |
もし,ジオメトリカラムの追加に失敗したのなら,おそらくこのデータベースにはPostGISの関数とオブジェクトがロードされていません.インストール説明書を参照してください.
これで,SQLのinsert分を使ってテーブルにジオメトリを登録することができます.GISオブジェクトはそれ自身Open GISコンソーシアムの"well-known text"フォーマットでフォーマットされます:
INSERT INTO gtest (ID, NAME, GEOM) VALUES (1, 'First Geometry', GeometryFromText('LINESTRING(2 3,4 5,6 5,7 8)', -1)); |
他のGISオブジェクトについての詳しい情報については,オブジェクトリファレンスを参照してください.
表中のGISデータを見るには以下のようにします:
SELECT id, name, AsText(geom) AS geom FROM gtest; |
返値はこのようになるでしょう:
id | name | geom ----+----------------+----------------------------- 1 | First Geometry | LINESTRING(2 3,4 5,6 5,7 8) (1 row) |
PostgreSQLで利用可能な空間演算子がたくさんあり,それらのいくつかはインデックスサポートを提供するためにPostGISによって実現されています.
インデックスをサポートしたspatial queryを実行するために,次の重要な単純化の仮定を利用する「overlap演算子("overlap operator")」(&&)を使用しなければなりません:全ての図形はbounding boxによって表現されるでしょう.
bounding boxを図形の代わりに使うことは制限的な仮定ですが,空間インデックス機能を提供する上で重要な仮定であると考えています.商用空間データベースは同じ仮定を使っています-- bounding boxは,ほとんどの空間インデックススキームにとって重要です.
ユーザの視点で最も重要な空間演算子はoverlap演算子"&&"です.これは,ある図形のbounding boxが他の図形のbounding boxに重なるかどうかをテストします.&&を使った空間クエリの例は次のようになります:
SELECT id,name FROM GTEST WHERE GEOM && 'BOX3D(3 4,4 5)'::box3d |
問合せのために使われるbounding boxは,キャスト操作"::box3d"を使ってbox3dとして明示的に宣言しなければならないことに注意してください.
大きなテーブルでの高速な問合せは,(トランザクションのサポートとともに)良いインデックスを持つ空間データベースの重要な存在理由です.
geometryカラムを持つテーブルに空間インデックスを構築するために,以下のように"CREATE INDEX"関数を使ってください:
CREATE INDEX [indexname] ON [tablename] USING GIST ( [geometrycolumn] gist_geometry_ops); |
"USING GIST"オプションは,サーバにGiST(Generalized Search Tree)インデックスを使うことを指示します."gist_geometry_ops"の記述(reference to)は,インデックスを作るために用いる固有の比較演算子のセットを指示します:"gist_geometry_ops"はPostGISの拡張の一部です.
注: PostgreSQL version 7.1.xでは,インデックス作成コマンドにWITH (ISLOSSY)を追加することで,"lossy"インデックスを明確に要求することができます.PostgreSQL 7.2.xと上記の全てのGiSTインデックスは,lossyとみなされます.lossyインデックスは,インデックスの作成に代用のオブジェクト(空間の場合bounding box)を用います.
'&&'演算子は,bounding_boxの重なりだけをチェックしますが,本当に検索領域(search box)と交差する図形だけを得るために,"truly_inside()"関数を使うことができます.例えば,高速なインデックス検索のための"&&"と結果集合の厳密な最終チェックのためtruly_inside()とを組み合わせて使うことによって,検索領域(serch box)に含まれる図形だけを得ることができます(これは現在のところsearch boxについてのみ上手くいき,任意の勝手なジオメトリでは上手くいかないことに注意してください):
SELECT [COLUMN1],[COLUMN2],AsText([GEOMETRYCOLUMN]) FROM [TABLE] WHERE [GEOM_COLUMN] && [BOX3d] AND truly_inside([GEOM_COLUMN],[BOX3d]); |
PostGISの初期のバージョンではPostgreSQLのR-Treeインデックスを使っていました.しかしながら,バージョン0.6からPostgreSQLのR-Treeは完全に切り捨てられ,空間インデックスはGist上のR-Tree(R-Tree-over-GiST)スキームで提供されます.
我々のテストはネイティブのR-TreeとGiSTの検索速度は匹敵することを示しています.ネイティブのPostgreSQLのR-Treesは,GIS機能として使う場合,好ましくない2つの制限があります(これらの制限は現在のPostgreSQLのネイティブR-Treeの実装が原因で,一般的なR-Treeのコンセプトが原因でないことに注意してください):
PostgreSQLのR-Treeインデックスは,8Kより大きいサイズの図形を扱うことができません.GisTインデックスは,図形そのものをbounding boxで代用する"lossy"トリックを使うことで,扱うことができます.
PostgreSQLのR-Treeインデックスは"null safe"ではありません.そのため,nullジオメトリを含むジオメトリカラムのインデックス作成は失敗するでしょう.
もし,OpenGISサポート関数を使いたくない場合,使う必要はありません.単純に,CREATEステートメントでジオメトリカラムを定義する,古いバージョンとしてテーブルを作成てください.全てのジオメトリのSRIDは-1となり,OpenGISメタデータテーブルは適切に埋められないでしょう.しかしながら,このことはほとんどのPostGISベースのアプリケーションに失敗を引き起こし,通常あなたにジオメトリテーブル作成するためにAddGeometryColumn()を使うことを勧めるでしょう.
Mapserverは,geometry_columnsのめたデータを利用するアプリケーションの一つです.特にMapserverは,ジオメトリカラムのSRIDを正しい地図の投影法への図形の即時(on-the-fly)投影法変換を行うために利用します.
もっとも効果的にデータベースを使うために,範囲のテストbounding boxのテスト組み合わせた範囲のクエリを実行することが一番です:bounding boxテストは空間インデックスを使い,範囲テストが適用されるデータのサブセットへの高速なアクセスを提供します.
たとえば,POINT(1000 1000)から100メートル以内の全てのオブジェクトを見つけるには,以下のクエリが上手く働くでしょう:
SELECT * FROM GEOTABLE WHERE GEOM && GeometryFromText('BOX3D(900 900,1100 1100)',-1) AND Distance(GeometryFromText('POINT(1000 1000)',-1),GEOM) < 100; |