3.1. | どの種類のジオメトリオブジェクトを格納できますか? |
ポイント、ライン、ポリゴン、マルチポイント、マルチライン、マルチポリゴン、ジオメトリコレクションを格納できます。これらは Open GIS Well Known Text Formatで規定されています (XYZ,XYM,XYZM拡張付き)。 | |
3.2. | GISオブジェクトをデータベースに挿入するにはどうしますか? |
まず、GISデータを保持するためにジオメトリ型のカラムをテーブルに作成する必要があります。 CREATE TABLE gtest ( ID int4, NAME varchar(20) ); SELECT AddGeometryColumn('', 'gtest','geom',-1,'LINESTRING',2); ジオメトリカラムの追加に失敗したなら、PostGIS関数とオブジェクトをそのデータベースにロードしていない可能性があります。インストール方法をご覧ください。 これで、SQLのINSERTステートメントを使って、ジオメトリをテーブルに挿入することができます。GISオブジェクト自体は、OpenGISコンソーシアムの"well-known text"形式を使っています。 INSERT INTO gtest (ID, NAME, GEOM) VALUES ( 1, 'First Geometry', GeomFromText('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) | |
3.3. | 空間クエリを作成するにはどうするのですか? |
他のデータベースクエリを作るのと同じで、返り値、関数、テストのSQLの組み合わせです。 空間クエリでは、クエリを作成する際に心を平静に保つための重要な二つの問題があります。 一つは、使用することができる空間インデックスがあるか、です。もう一つは、多数のジオメトリを相手に計算量の多い計算を行っているか、です。 一般的に、フィーチャーのバウンディングボックスがインタセクト (交差)しているかをテストするインタセクト演算子 (&&)を使います。&&演算子が便利な理由は、速度向上のために空間インデックスが付けられているなら、&&演算子は空間インデックスを使うからです。これによって、クエリの速度はとてもとても速くなります。 また、検索結果をより狭めるために、Distance(), ST_Intersects(), ST_Contains(), ST_Within() などといった空間関数を使うことでしょう。ほとんどの空間クエリは、インデクスのテストと空間関数のテストを含みます。インデクスのテストで返ってくるタプルを、求める条件に合致するかもしれないタプルのみとして、タプルの数を制限します。それから、空間関数で確実な条件のテストを行います。 SELECT id, the_geom FROM thetable WHERE the_geom && 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))' AND _ST_Contains(the_geom,'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'); | |
3.4. | 大きなテーブルでの空間クエリの速度向上はどうするのですか? |
大きなテーブルの速いクエリは、空間データベースのレゾンデートル (トランザクションサポートもそうですが)で、良いインデックスは重要です。
CREATE INDEX [インデックス名] ON [テーブル名] USING GIST ( [ジオメトリカラム] ); "USING GIST"オプションによって、サーバにGiST (Generalized Search Tree)インデックスを作るよう指示が渡ります。 注記GiSTインデックスは、不可逆であると仮定します。不可逆インデックスの構築には、代理オブジェクト (空間インデックスの場合はバウンディングボックス)を使います。 PostgreSQLのクエリプランナがインデックスを作るべきかについて合理的な決定を行うよう、十分な情報を確実に持てるようにすべきです。そのために、ジオメトリテーブル上で"gather statistics"を実行しなければなりません。 PostgreSQL 8.0.x以上では、VACUUM ANALYZEコマンドを実行するだけです。 PostgreSQL 7.4.x以下では、SELECT UPDATE_GEOMETRY_STATS()を実行します。 | |
3.5. | なぜPostgreSQLのR木インデックス機能を持たないのですか? |
PostGISの、かつての版では、PostgreSQLのR木インデックスを使っていましたが、0.6版でPostgreSQLのR木は完全に捨てて、R-Tree-over-GiSTスキームによる空間インデックスを提供しています。 私たちの試験では、R木とGiSTの検索速度は同程度であることが示されています。PostgreSQLのR木には、GISフィーチャーで使うためには好ましくない二つの制限があります (これらの制限は現在のPostgreSQLネイティブのR木実装についてであって、R木一般の話ではありません)。
| |
3.6. | なぜ |
OpenGIS関数を使いたくないのでしたら、使う必要はありません。単純にジオメトリカラムをCREATEステートメントで定義する古いやり方で作成して下さい。全てのジオメトリはSRIDが-1になり、OpenGISメタデータテーブルは適切に書き込まれません。これによって、ほとんどのPostGISベースのアプリケーションでは失敗します。一般的には MapServerは | |
3.7. | 半径内にあるオブジェクトを全て検索する最善の方法は何ですか? |
データベースを最も効果的に使うには、半径検索とバウンディングボックス検索を組み合わせた半径検索を行うのが最も良いです。バウンディングボックス検索で空間インデックスを使用するので、半径検索が適用されるサブセットへのアクセスが早くなります。
たとえば、POINT(1000 1000)から100メートル内の全てのオブジェクトを見つけるためには、次のクエリで動作します。 SELECT * FROM geotable WHERE ST_DWithin(geocolumn, 'POINT(1000 1000)', 100.0); | |
3.8. | クエリの一部として投影変換を実現するにはどうしますか? |
投影変換を行うには、変換元と変換先双方の座標系がSPATIAL_REF_SYSテーブルに定義されていて、かつ投影変換されるジオメトリがそのSRIDを持っている必要があります。これが行われていると、投影変換は求める変換先SRIDを参照するのと同じぐらい簡単です。 SELECT ST_Transform(the_geom,4269) FROM geotable; |