PostGISマニュアル

概要

PostGISは、オブジェクトRDBであるPostgreSQLの拡張で、GIS (地理情報システム)オブジェクトを格納することができます。PostGISは、GiSTベースのR木空間インデックスをサポートし、GISオブジェクトの解析および処理を行う機能を持ちます。


目次

1. 導入
1.1. 貢献者
1.2. 追加情報
2. インストール
2.1. 必要なもの
2.2. PostGIS
2.2.1. アップグレード
2.2.2. 共通の問題
2.3. JDBC
2.4. ローダ/ダンパ
3. よくある質問
4. PostGISを使う
4.1. GISオブジェクト
4.1.1. OpenGIS WKBとWKT
4.1.2. PostGIS EWKB, EWKTと標準形式
4.2. OpenGIS標準を使う
4.2.1. SPATIAL_REF_SYSテーブル
4.2.2. GEOMETRY_COLUMNSテーブル
4.2.3. 空間テーブルを作る
4.2.4. ジオメトリのOpenGIS準拠を確実にする
4.3. GISデータのロード
4.3.1. SQLを使う
4.3.2. ローダを使う
4.4. GISデータを検索する
4.4.1. SQLを使う
4.4.2. ダンパを使う
4.5. インデックスを構築する
4.5.1. GiSTインデックス
4.5.2. インデックスを使う
4.6. 複雑なクエリ
4.6.1. インデックスの利点を使う
4.6.2. 空間SQLの例
4.7. MapServerを使う
4.7.1. 基本的な使い方
4.7.2. よくある質問
4.7.3. 踏み込んだ使用法
4.7.4. 例
4.8. Javaクライアント (JDBC)
4.9. Cクライアント (libpq)
4.9.1. テキストカーソル
4.9.2. バイナリカーソル
5. 性能向上に関する技法
5.1. 大きなジオメトリを持つ小さなテーブル
5.1.1. 問題の説明
5.1.2. 応急処置
5.2. ジオメトリインデックスでCLUSTERを実行する
5.3. 次元変換の回避
6. PostGISリファレンス
6.1. OpenGIS関数
6.1.1. 管理関数
6.1.2. 空間関係関数
6.1.3. ジオメトリ処理関数
6.1.4. ジオメトリアクセサ
6.1.5. ジオメトリ コンストラクタ
6.2. PostGIS独自拡張
6.2.1. 管理関数
6.2.2. 演算子
6.2.3. 計測関数
6.2.4. ジオメトリ出力
6.2.5. ジオメトリ コンストラクタ
6.2.6. ジオメトリエディタ
6.2.7. その他の関数
A. リリースノート
A.1. リリース 1.0.0
A.1.1. アップグレード
A.1.2. ライブラリの変更
A.1.3. 他の変更追加
A.2. リリース 1.0.0RC6
A.2.1. アップグレード
A.2.2. ライブラリの変更
A.2.3. スクリプトの変更
A.2.4. 他の変更
A.3. リリース 1.0.0RC5
A.3.1. アップグレード
A.3.2. ライブラリの変更
A.3.3. 他の変更
A.4. リリース 1.0.0RC4
A.4.1. アップグレード
A.4.2. ライブラリの変更
A.4.3. スクリプトの変更
A.4.4. 他の変更
A.5. リリース 1.0.0RC3
A.5.1. アップグレード
A.5.2. ライブラリの変更
A.5.3. スクリプトの変更
A.5.4. JDBC変更
A.5.5. 他の変更
A.6. リリース 1.0.0RC2
A.6.1. アップグレード
A.6.2. ライブラリの変更
A.6.3. スクリプトの変更
A.6.4. 他の変更
A.7. リリース 1.0.0RC1
A.7.1. アップグレード
A.7.2. 変更

第1章 導入

PostGISはRefractions Research Incが空間データベース技術研究プロジェクトとして開発しました。Refractionsはカナダ・ブリティッシュコロンビア州・ビクトリアにある、データインテグレーションとカスタムソフトウェア開発に特化した、GISとデータベースのコンサルティング会社です。私たちは完全なOpenGISサポート、高度なトポロジ構成 (カバレッジ、サーフェス、ネットワーク)、GISデータの表示と編集をするためのデスクトップユーザインタフェースツール、ウェブベースのアクセスツールを持つ、 重要なGIS機能性の範囲をサポートするPostGISを、サポートおよび開発する予定です。

1.1. 貢献者

Sandro Santilli <strk@refractions.net>

全ての誤り訂正と保守、新しいGEOS機能の統合、新関数の機能強化。

Chris Hodgson <chodgson@refractions.net>

新関数の保守と7.2のインデックスバインディング。

Paul Ramsey <pramsey@refractions.net>

JDBCオブジェクトの保守と文書とパッケージの更新記録。

Jeff Lounsbury <jeffloun@refractions.net>

シェープファイルのローダ/ダンパのオリジナル開発者

Dave Blasby <dblasby@gmail.com>

PostGISのオリジナル開発者。サーバサイドオブジェクト、インデックスバインディング、 サーバサイドの解析関数を書きました。

他の貢献者

ABC順で: Alex Bodnaru, Bernhard Reiter, Bruno Wolff III, Carl Anderson, David Skea, David Techer, IIDA Tetsushi, Geographic Data BC, Gerald Fenoy, Gino Lucrezi, Klaus Foerster, Kris Jurka, Mark Cave-Ayland, Mark Sondheim, Markus Schaber, Norman Vine, Olivier Courtin, Ralph Mason, Steffen Macke.

1.2. 追加情報

第2章 インストール

2.1. 必要なもの

PostGISのビルドと利用のために、次のものが必要です。

  • PostgreSQLの完全なコンフィギュアとビルドが行われたコードツリー。PostGISは、ビルドを行った特定のプラットフォームに合わせるために、PostgreSQLのコンフィギュア/ビルド処理で作られた定義を使います。PostgreSQLはhttp://www.postgresql.orgにあります。

  • GNU Cコンパイラ (gcc)。ANSI Cコンパイラの中には、PostGISをコンパイルできるものもありますが、gccでコンパイルするのが最も問題が少ないと見ています。

  • GNU Make (gmakeまたはmake)。多くのシステムで、GNU makeがデフォルトのmakeになっています。make -vを実行して版を確認して下さい。他版のmakeでは、PostGISのMakefileを完全に処理しきれないかもしれません。

  • (推奨) 投影変換ライブラリ Proj4。Proj4ライブラリはPostGISで座標投影変換をサポートするために使われます。Proj4はhttp://www.remotesensing.org/projからダウンロードできます。

  • (推奨) ジオメトリライブラリ GEOS。GEOSライブラリは、PostGISでジオメトリのチェック (Touches(), Contains(), Intersects())および操作(Buffer(), GeomUnion(), Difference()) を提供するために使用します。 GEOSはhttp://geos.refractions.netからダウンロードできます。

2.2. PostGIS

PostGISモジュールは、PostgreSQLバックエンドサーバの拡張です。PostGIS 1.0.0をコンパイルするためにPostgreSQLサーバのヘッダの完全なアクセスが必要です。PostgreSQLのソースコードはhttp://www.postgresql.orgにあります。

PostGIS 1.0.0は、PostgreSQL 7.2.0から7.4.0で構築できます。それ以前のPostgreSQLには対応しません

  1. PostGISサーバモジュールをコンパイルする前に、PostgreSQLをコンパイル、インストールする必要があります。

    注記

    GEOS機能の使用を予定しているなら、PostgreSQLを標準C++ライブラリに、明示的にリンクする必要があることもあります。

    LDFLAGS=-lstdc++ ./configure [コンフィギュアオプション]

    これは、古い開発ツールとインチキC++例外との対話のための応急処置です。怪しい問題 (望んでいないのにバックエンドが閉じたりそれに近い挙動を起こす)を経験したなら、このトリックを試してみて下さい。もちろん、これを行うにはPostgreSQLをはじめからコンパイルし直す必要があります。

  2. PostGISソースコードのアーカイブをhttp://postgis.refractions.net/postgis-1.0.0.tar.gzから取得します。PostgreSQLソースツリーの "contrib"ディレクトリ内で、このアーカイブを解凍します。

    # cd [PostgreSQLソースツリー]/contrib 
    # gzip -d -c postgis-1.0.0.tar.gz | tar xvf -
  3. PostgreSQLのインストールが更新されたら、"postgis"ディレクトリに入り、Makefile.configファイルを編集します。

    • 座標再投影に対応したいならProj4ライブラリをインストールし、USE_PROJ変数に1を入れ、PROJ_DIR変数をProj4をインストールしたディレクトリに合わせます。

    • GEOS機能を使いたいならGEOSライブラリをインストールし、USE_GEOS変数に1を入れ、GEOS_DIR変数をGEOSをインストールしたディレクトリに合わせます。

  4. コンパイルとインストールのコマンドを実行します。

    # make 
    # make install

    全てのファイルが[prefix] (PostgreSQLのインストールディレクトリ)からの相対位置にインストールされます。

    • ライブラリは[prefix]/lib/contribにインストールされます。

    • lwpostgis.sqlといったサポートファイルは[prefix]/share/contribにインストールされます。

    • ローダとダンパのバイナリは[prefix]/binにインストールされます。

  5. PostGISにはPL/pgSQL手続き型言語の拡張が必要です。lwpostgis.sqlファイルをロードする前に、まずPL/pgSQLを有効にする必要があります。createlangコマンドを使うべきです。なんらかの理由で手動で行いたい場合にはPostgreSQLプログラマガイドに詳細があります。

    # createlang plpgsql [データベース名]
  6. そして、lwpostgis.sql定義ファイルをロードして、PostGISオブジェクトと関数定義をデータベースにロードします。

    psql -d [データベース名] -f rtpostgis.sql

    PostGISサーバ拡張はこれでロードされて、使えるようになります。

  7. 完全なEPSG座標系定義IDのセットについては、spatial_ref_sys.sql定義ファイルをロードして、SPATIAL_REF_SYSを生成して下さい。

    psql -d [データベース名] -f spatial_ref_sys.sql

2.2.1. アップグレード

オブジェクト型とジオメトリにに対応するためのCライブラリが版ごとに異なるため、PostGISのアップグレードは扱いにくくなっています。

この目的のために、PostGISは、pg_dump -Fcコマンドによるダンプを格納するためのユーティリティスクリプトを提供しています。これは試験的なもので、出力をファイルにリダイレクトすることで問題がある場合の解決の助けになります。手続きは次の通りです。

# Create a "custom-format" dump of the database you want
        # to upgrade (let's call it "olddb")
        $ pg_dump -Fc olddb olddb.dump

        # Restore the dump contextually upgrading postgis into
        # a new database. The new database doesn't have to exist.
        # Let's call it "newdb"
        $ sh utils/postgis_restore.pl lwpostgis.sql newdb olddb.dump > restore.log

        # Check that all restored dump objects really had to be restored from dump
        # and do not conflict with the ones defined in lwpostgis.sql
        $ grep ^KEEPING restore.log | less

        # If upgrading from PostgreSQL < 7.5 to >= 7.5 you might want to 
        # drop the attrelid, varattnum and stats columns in the geometry_columns
        # table, which are no-more needed. Keeping them won't hurt.
        # !!! DROPPING THEM WHEN REALLY NEEDED WILL DO HURT !!!!
        $ psql newdb -c "ALTER TABLE geometry_columns DROP attrelid"
        $ psql newdb -c "ALTER TABLE geometry_columns DROP varattnum"
        $ psql newdb -c "ALTER TABLE geometry_columns DROP stats"

        # spatial_ref_sys table is restore from the dump, to ensure your custom
        # additions are kept, but the distributed one might contain modification
        # so you should backup your entries, drop the table and source the new one.
        # If you did make additions we assume you know how to backup them before
        # upgrading the table. Replace of it with the new one is done like this:
        $ psql newdb
        newdb=> drop table spatial_ref_sys;
        DROP
        newdb=> \i spatial_ref_sys.sql
        

「古い」手続きの記述を次に示します。可能なら*避けるべき*です。データベース内に意図しない関数が多数入り込むためです。この文書内で残されているのは、postgis_restore.plが動作しない場合の「バックアップ」のためです。

pg_dump -t "*" -f dumpfile.sql yourdatabase
        dropdb yourdatabase
        createdb yourdatabase
        createlang plpgsql yourdatabase
        psql -f lwpostgis.sql -d yourdatabase
        psql -f dumpfile.sql -d yourdatabase
        vacuumdb -z yourdatabase
        

2.2.2. 共通の問題

インストールやアップグレードが思うようにいかない時にチェックすることがいくつかあります。

  1. PostGISディストリビューションをPostgreSQLソースツリーの下のcontribディレクトリに解凍するのが最も簡単です。 しかし、これが何らかの理由で展開できないなら、環境変数PGSQL_SRCにPostgreSQLソースディレクトリのパスを指定します。これで、PostGISのコンパイルができますが、make installはできないので、PostGISライブラリと実行ファイルを適切な位置に自前で複写することになります。

  2. PostgreSQL 7.2以降をインストールしているか、実行中のPostgreSQLと同じ版のPostgreSQLソースを使ってコンパイルしているか、をチェックします。(Linuxの)ディストリビューションによって既にPostgreSQLがインストールされている時や、PostgreSQLを以前にインストールして忘れた場合に、混乱が発生することがあります。PostGISは、PostgreSQL 7.2以上でのみ動作し、 それより前の版を使うと、おかしな、予想外のエラーメッセージが表示されます。 実行中のPostgreSQLの版をチェックするには、psqlを使ってデータベースを接続して、次のクエリを実行します。

    SELECT version();

    RPMベースのディストリビューションを実行している場合、プリインストールされたパッケージが存在するかのチェックは、rpmコマンドを使います。rpm -qa | grep postgresqlでチェックできます。

また、Makefile.configの先頭に行った必要な変更を全てチェックして下さい。このチェックは次の通りです。

  1. 投影変換をできるようにしたいなら、Proj4ライブラリをインストールして、Makefile.config内の、USE_PROJの値を1に設定し、PROJ_DIRをインストール先プリフィクスにします。

  2. GEOS関数を使いたい場合は、 GEOSライブラリをインストールし、Makefile.config内の、USE_GEOSを1に設定し、GEOS_DIRをインストール先プリフィクスにします。

2.3. JDBC

JDBC拡張によって、JavaオブジェクトがPostGISの内部型に対応できるようになります。このオブジェクトを使って、PostGISデータベースに問い合わせを出して、PostGISにあるGISデータの描画や計算を行うJavaクライアントを作成することができます。

  1. PostGISディストリビューションのjdbcサブディレクトリに移動します。

  2. Makefileを編集して、Javaコンパイラ (JAVAC)とインタプリタ (JAVA)を正しいパスにします。

  3. makeコマンドを実行します。postgis.jarファイルをJavaライブラリを保存しているところに複製します。

2.4. ローダ/ダンパ

データのローダとダンパは、PostGISのビルドの一部として、自動的にビルド、インストールされます。手動でビルド、インストールするには、次を実行します。

# cd postgis-1.0.0/loader 
# make
# make install

ローダはshp2pgsqlと呼ばれ、ESRIシェープファイルをPostGIS/PostgreSQLにロードするのに適したSQLに変換します。ダンパはpgsql2shpと呼ばれ、PostGISのテーブル (またはクエリ)からESRIシェープファイルに変換します。

第3章 よくある質問

3.1. どの種類のジオメトリオブジェクトを格納できますか?
3.2. GISオブジェクトをデータベースに挿入するにはどうしますか?
3.3. 空間クエリを作成するにはどうするのですか?
3.4. 大きなテーブルでの空間クエリの速度向上はどうするのですか?
3.5. なぜPostgreSQLのR木インデックス機能を持たないのですか?
3.6. なぜ AddGeometryColumn()関数と他のOpsnGIS関数を使うべきなのですか?
3.7. 半径内にあるオブジェクトを全て検索する最善の方法は何ですか?
3.8. クエリの一部として投影変換を実現するにはどうしますか?

3.1.

どの種類のジオメトリオブジェクトを格納できますか?

ポイント、ライン、ポリゴン、マルチポイント、マルチライン、マルチポリゴン、ジオメトリコレクションを格納できます。これらは Open GIS Well Known Text Formatで規定されています (XYZ,XYM,XYZM拡張付き)。

3.2.

GISオブジェクトをデータベースに挿入するにはどうしますか?

まず、GISデータを保持するためにジオメトリ型のカラムをテーブルに作成する必要があります。psqlでデータベースに接続して、次のSQLを実行します。

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(), Intersects(), Contains(), Within()といった空間関数を使用することでしょう。ほとんどの空間クエリはインデックス検索と空間関数検索を行います。インデックス検索によって検索結果のタプルを、対象条件に適合するかもしれないものに制限させます。そして、空間関数は確実に条件にあうかどうかをチェックします。

SELECT id, the_geom FROM thetable
WHERE
  the_geom && 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'
AND
  Contains(the_geom,'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))';

3.4.

大きなテーブルでの空間クエリの速度向上はどうするのですか?

大きなテーブルの速いクエリは、空間データベースのレゾンデートル (トランザクションサポートもそうですが)で、良いインデックスは重要です。

geometryカラムを持つテーブルでの空間インデックスの構築は、"CREATE INDEX"を使って、次のようにします。

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木一般の話ではありません)。

  • PostgreSQLのR木インデックスは、8K以上のサイズのフィーチャーは扱えません。GiSTインデックスはフィーチャー自体の代わりにバウンディングボックスを用いる「不可逆」トリックを使っているので扱うことができます。

  • PostgreSQLのR木インデックスは「NULLセーフ」ではなく、NULLジオメトリを含むジオメトリカラムではインデックス作成に失敗します。

3.6.

なぜ AddGeometryColumn()関数と他のOpsnGIS関数を使うべきなのですか?

OpenGIS関数を使いたくないのでしたら、使う必要はありません。単純にジオメトリカラムをCREATEステートメントで定義する古いやり方で作成して下さい。全てのジオメトリはSRIDが-1になり、OpenGISメタデータテーブルは適切に書き込まれません。これによって、ほとんどのPostGISベースのアプリケーションでは失敗します。一般的にはAddGeometryColumn()を用いることをお勧めします。

MapServerはgeometry_columnsメタデータを使うアプリケーションのひとつです。踏み込んでいえば、MpaServerはジオメトリカラムのSRIDを使って、正しい地図投影へのフィーチャーの自動投影変換を行います。

3.7.

半径内にあるオブジェクトを全て検索する最善の方法は何ですか?

データベースを最も効果的に使うには、半径検索とバウンディングボックス検索を組み合わせた半径検索を行うのが最も良いです。バウンディングボックス検索で空間インデックスを使用するので、半径検索が適用されるサブセットへのアクセスが早くなります。

Expand()関数は、検索対象領域のインデックス検索を可能にするためにバウンディングボックスを拡大させる手軽な方法です。速いインデックスへのアクセスの句と遅い高精度距離テストとの組み合わせで、このクエリにおける、速さと精度の最も良い組み合わせが得られます。

たとえば、POINT(1000 1000)から100メートル内の全てのオブジェクトを見つけるためには、次のクエリで動作します。

SELECT * 
FROM GEOTABLE 
WHERE 
  GEOCOLUMN && Expand(GeomFromText('POINT(1000 1000)',-1),100)
AND
  Distance(GeomFromText('POINT(1000 1000)',-1),GEOCOLUMN) < 100;

3.8.

クエリの一部として投影変換を実現するにはどうしますか?

投影変換を行うには、変換元と変換先双方の座標系がSPATIAL_REF_SYSテーブルに定義されていて、かつ投影変換されるジオメトリがそのSRIDを持っている必要があります。これが行われていると、投影変換は求める変換先SRIDを参照するのと同じぐらい簡単です。

SELECT Transform(GEOM,4269) FROM GEOTABLE;

第4章 PostGISを使う

4.1. GISオブジェクト

PostGISでサポートされるGISオブジェクトは、OpenGIS Consortium (OGC)が定義する"Simple Features" のスーパーセットです。 PostGIS 0.9版からOGCの"Simple Features for SQL"仕様で定められた全てのオブジェクトと関数をサポートしています。

PostGISは標準から拡張して 3DZ, 3DM, 4D 座標 (訳注: それぞれXYZ, XYM, XYZM)をサポートしています。

4.1.1. OpenGIS WKBとWKT

OpenGIS仕様は空間オブジェクトの表現について二つの標準を定義しています。Well-Knownテキスト (WKT)形式とWell-Knownバイナリ (WKB)形式です。WKTもWKBも、オブジェクトの型とオブジェクトを形成する座標に関する情報を持っています。

フィーチャーの空間オブジェクトのテキスト表現 (WKT)の例は、次の通りです。

  • POINT(0 0)

  • LINESTRING(0 0,1 1,1 2)

  • POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))

  • MULTIPOINT(0 0,1 2)

  • MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))

  • MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))

  • GEOMETRYCOLLECTION(POINT(2 3),LINESTRING((2 3,3 4)))

OpenGIS仕様では、空間オブジェクトの内部保存書式は空間参照系識別子 (Spatial Referencing System IDentifier, SRID)を含むことも求められます。SRIDはデータベースへの挿入のために空間オブジェクトが生成される時に求められます。

これらの書式の入出力は次のインタフェースを用いて実現できます。

bytea WKB = asBinary(geometry);
        text WKT = asText(geometry);
        geometry = GeomFromWKB(bytea WKB, SRID); 
        geometry = GeometryFromText(text WKT, SRID);
        

たとえば、OGC空間オブジェクトを生成して挿入する妥当なINSERTステートメントは次の通りです。

INSERT INTO SPATIALTABLE ( 
                  THE_GEOM, 
                  THE_NAME 
        ) 
        VALUES ( 
                  GeomFromText('POINT(-126.4 45.32)', 312), 
                  'A Place' 
        )

4.1.2. PostGIS EWKB, EWKTと標準形式

OGC書式は2次元ジオメトリしかサポートされておらず、また、入出力の表現においてSRIDは*決して*埋め込まれません。

PostGIS拡張書式は現在のところOGC書式のスーパーセットとなっています (全ての妥当なWKB/WKTは妥当なEWKB/EWKTです)。しかし、特にもしOGCがPostGIS拡張と矛盾する新しい書式を出すことがあるなら、これは将来変更されるかも知れません。ゆえにこの機能に頼るべきではありません。

PostGIS EWKB/EWKT では 3dm, 3dz, 4d の座標サポートが追加され、SRID情報が埋め込まれます。

拡張された空間オブジェクトのテキスト表現 (EWKT)の例は、次の通りです。

  • POINT(0 0 0) -- XYZ

  • SRID=32632;POINT(0 0) -- XY with SRID

  • POINTM(0 0 0) -- XYM

  • POINT(0 0 0 0) -- XYZM

  • SRID=4326;MULTIPOINTM(0 0 0,1 2 1) -- SRID付きXYM

  • MULTILINESTRING((0 0 0,1 1 0,1 2 1),(2 3 1,3 2 1,5 4 1))

  • POLYGON((0 0 0,4 0 0,4 4 0,0 4 0,0 0 0),(1 1 0,2 1 0,2 2 0,1 2 0,1 1 0))

  • MULTIPOLYGON(((0 0 0,4 0 0,4 4 0,0 4 0,0 0 0),(1 1 0,2 1 0,2 2 0,1 2 0,1 1 0)),((-1 -1 0,-1 -2 0,-2 -2 0,-2 -1 0,-1 -1 0)))

  • GEOMETRYCOLLECTIONM(POINTM(2 3 9),LINESTRINGM((2 3 4,3 4 5)))

これらの書式の入出力は次のインタフェースを用いて実現できます。

bytea EWKB = asEWKB(geometry);
        text EWKT = asEWKT(geometry);
        geometry = GeomFromEWKB(bytea EWKB);
        geometry = GeomFromEWKT(text EWKT);
        

たとえば、PostGISの空間オブジェクトを作成し挿入する妥当なINSERTステートメントは次の通りです。

INSERT INTO SPATIALTABLE ( 
                  THE_GEOM, 
                  THE_NAME 
        ) 
        VALUES ( 
                  GeomFromEWKT('SRID=312;POINTM(-126.4 45.32 15)'), 
                  'A Place' 
        )

The "canonical forms" of a PostgreSQL type are the representations you get with a simple query (without any function call) and the one which is guaranteed to be accepted with a simple insert, update or copy. For the postgis 'geometry' type these are:

- Output -
        binary: EWKB
         ascii: HEXEWKB (EWKB in hex form)

        - Input -
        binary: EWKB
         ascii: HEXEWKB|EWKT
        

たとえば、次のステートメントは、標準的なASCII文字列による入出力の処理でEWKTを読み、HEXEWKBを返すものです。

=# SELECT 'SRID=4;POINT(0 0)'::geometry;
                              geometry
        ----------------------------------------------------
         01010000200400000000000000000000000000000000000000
        (1 row)
        

4.2. OpenGIS標準を使う

OpenGISの「SQL用シンプルフィーチャー仕様」では、標準GISオブジェクト型とこれらを操作するために必要な関数、メタデータテーブルのセットが定義されています。メタデータが一貫性を維持していることを保証するために、空間カラムの生成、消去といった操作はOpenGISで定義されている空間プロシージャを通して実行されます。

OpenGISメタデータテーブルにはSPATIAL_REF_SYSGEOMETRY_COLUMNSの二つがあります。SPATIAL_REF_SYSテーブルは空間データベースで用いられる座標系の、数字によるIDと文字による説明を持っています。

4.2.1. SPATIAL_REF_SYSテーブル

SPATIAL_REF_SYSテーブル定義は次の通りです。

CREATE TABLE SPATIAL_REF_SYS ( 
  SRID INTEGER NOT NULL PRIMARY KEY, 
  AUTH_NAME VARCHAR(256), 
  AUTH_SRID INTEGER, 
  SRTEXT VARCHAR(2048), 
  PROJ4TEXT VARCHAR(2048)
)

SPATIAL_REF_SYSのカラムは次の通りです。

SRID

一意に定められた整数値で、データベースで空間参照系 (SRS)を識別するものです。

AUTH_NAME

その参照系の引用元である標準の名前です。たとえば「EPSG」は妥当なAUTH_NAMEです。

AUTH_SRID

AUTH_NAMEで引用される団体によって定義された空間参照系のIDです。EPSGの場合、EPSG投影コードが入ります。

SRTEXT

空間参照系のWell-Knownテキスト表現です。たとえば、WKT SRSの表現は、次のようになります。

PROJCS["NAD83 / UTM Zone 10N", 
  GEOGCS["NAD83",
    DATUM["North_American_Datum_1983", 
      SPHEROID["GRS 1980",6378137,298.257222101]
    ], 
    PRIMEM["Greenwich",0], 
    UNIT["degree",0.0174532925199433] 
  ],
  PROJECTION["Transverse_Mercator"], 
  PARAMETER["latitude_of_origin",0],
  PARAMETER["central_meridian",-123], 
  PARAMETER["scale_factor",0.9996],
  PARAMETER["false_easting",500000], 
  PARAMETER["false_northing",0],
  UNIT["metre",1] 
]

EPSG投影コードと対応するWKT表現の一覧についてはhttp://www.opengis.org/techno/interop/EPSG2WKT.TXTをご覧下さい。WKTの一般的な議論については、OpenGISの「座標変換サービス実装仕様」http://www.opengis.org/techno/specs.htmをご覧下さい。欧州石油調査グループ (European Petroleum Survey Group, EPSG)と EPSG空間参照系のデータベースに関する情報は、http://epsg.orgをご覧下さい。

PROJ4TEXT

PostGISは座標変換機能を提供するためにProj4ライブラリを用いています。 PROJ4TEXTカラムには、特定のSRIDを示すProj4座標定義文字列が入ります。たとえば次のようになります。

+proj=utm +zone=10 +ellps=clrk66 +datum=NAD27 +units=m

詳細情報については、Proj4ウェブサイhttp://www.remotesensing.org/projをご覧下さい。spatial_ref_sys.sqlは、全てのEPSG投影のためのSRTEXTPROJ4TEXTを持っています。

4.2.2. GEOMETRY_COLUMNSテーブル

GEOMETRY_COLUMNSテーブルは、次のように定義されています。

CREATE TABLE GEOMETRY_COLUMNS ( 
  F_TABLE_CATALOG VARCHAR(256) NOT NULL, 
  F_TABLE_SCHEMA VARCHAR(256) NOT NULL, 
  F_TABLE_NAME VARCHAR(256) NOT NULL, 
  F_GEOMETRY_COLUMN VARCHAR(256) NOT NULL,
  COORD_DIMENSION INTEGER NOT NULL, 
  SRID INTEGER NOT NULL, 
  TYPE VARCHAR(30) NOT NULL 
)

カラムは次のとおりです。

F_TABLE_CATALOG, F_TABLE_SCHEMA, F_TABLE_NAME

ジオメトリカラムを持つフィーチャーテーブルの完全修飾名。"catalog"および"schema"の語はOracle風であることに注意して下さい。"catalog"に類似するものはPostgreSQLになく、このカラムは空白にされます。"schema"についてはPostgreSQLスキーマ名が使われています (publicがデフォルトです)。

F_GEOMETRY_COLUMN

フィーチャーテーブル内のジオメトリカラムの名前。

COORD_DIMENSION

そのカラムの空間の次元 (2, 3 または 4)。

SRID

このテーブルの座標ジオメトリのために使われる空間参照系のID。SPATIAL_REF_SYSへの外部キーになっています。

TYPE

空間オブジェクトのタイプ。 空間カラムを単一型に制限するには、 POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION のうちのいずれかを、また、XYMで使う場合には LINESTRINGM, POLYGONM, MULTIPOINTM, MULTILINESTRINGM, MULTIPOLYGONM, GEOMETRYCOLLECTIONM のうちのいずれかを使います。複数の型が混合するコレクションの場合は "GEOMETRY"タイプとすることができます。

注記

この属性は (おそらく)OpenGIS仕様に入っていませんが、型の同一性を保証するために必要です。

4.2.3. 空間テーブルを作る

空間データを持つテーブルを生成するには、次の通り二段階で行います。

  • 通常の非空間テーブルを生成します。

    たとえば、次のようにします。CREATE TABLE ROADS_GEOM ( ID int4, NAME varchar(25) )

  • OpenGISの"AddGeometryColumn"関数によって空間カラムをテーブルに追加します。

    The syntax is:

    AddGeometryColumn(<schema_name>, <table_name>,
                <column_name>, <srid>, <type>,
                <dimension>)

    Or, using current schema:

    AddGeometryColumn(<テーブル名>,
                <カラム名>, <SRID>, <タイプ>,
                <次元>)

    例1: SELECT AddGeometryColumn('public', 'roads_geom', 'geom', 423, 'LINESTRING', 2)

    例2: SELECT AddGeometryColumn( 'roads_geom', 'geom', 423, 'LINESTRING', 2)

次はテーブルを作成して空間カラムを作る例です (128というSRIDがあると仮定します)。

CREATE TABLE parks ( PARK_ID int4, PARK_NAME varchar(128), PARK_DATE date, PARK_TYPE varchar(2) );
SELECT AddGeometryColumn('parks', 'park_geom', 128, 'MULTIPOLYGON', 2 );

もうひとつ、ジェネリックな「ジオメトリ」型とSRID不明を示す-1を使った例を挙げます。

CREATE TABLE roads ( ROAD_ID int4, ROAD_NAME varchar(128) ); 
SELECT AddGeometryColumn( 'roads', 'roads_geom', -1, 'GEOMETRY', 3 );

4.2.4. ジオメトリのOpenGIS準拠を確実にする

GEOSライブラリで実装される関数のほとんどが、ジオメトリがOpenGIS単純フィーチャー仕様の定義から見て妥当であることが仮定されています。ジオメトリの妥当性のチェックには、IsValid()関数を使います。例を次に示します。

gisdb=# select isvalid('LINESTRING(0 0, 1 1)'), isvalid('LINESTRING(0 0,0 0)');
 isvalid | isvalid
---------+---------
 t       | f

デフォルトでは、PostGISはジオメトリ入力に関するこの妥当性チェックを適用しません。複雑なジオメトリの妥当性のチェックはCPU時間を多く必要とするためです。データソースが信用できない場合は、手動でこのチェックを強制するための制約を付けることができます。

ALTER TABLE mytable ADD CONSTRAINT geometry_valid_check CHECK (isvalid(the_geom));

妥当な入力ジオメトリでPostGIS関数を呼んだのに「GEOS Intersection()がエラーを投げました!」や「JTS Intersection()がエラーを投げました!」というようなメッセージに遭遇したら、それはたぶん、PostGISまたは使用しているライブラリの中のエラーを発見しました。PostGIS開発者に連絡するべきです。PostGIS関数が妥当である入力ジオメトリから妥当でないジオメトリが返る場合も同じです。

注記

厳格にOGCジオメトリに準拠すると、Z値やM値を持てません。ST_IsValid()は高次を考慮に入れません。AddGeometryColumn()を実行するとジオメトリの次元をチェックする制約が加わるので、そこで2を指定すれば十分です。

4.3. GISデータのロード

空間テーブルを作成したら、これでGISデータをデータベースにアップロードする準備ができたことになります。現在、PostGIS/PostgreSQLデータベースにデータをロードするには、SQLステートメントを使う、またはシェープファイルのローダ/ダンパを使う、二つの方法があります。

4.3.1. SQLを使う

データをテキスト表現に変換できるなら、フォーマットされたSQLを使うのがデータをPostGISに入れる最も簡単な方法です。Oracleや他のSQLデータベースを使うように、SQL端末モニタにSQLの"INSERT"ステートメントで一杯になった大きなテキストファイルをパイプで送ることで、大量のデータをロードできます。

データアップロードファイル (たとえばroads.sql)は次のようになるでしょう。

BEGIN;
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (1,GeomFromText('LINESTRING(191232 243118,191108 243242)',-1),'Jeff Rd'); 
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (2,GeomFromText('LINESTRING(189141 244158,189265 244817)',-1),'Geordie Rd'); 
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (3,GeomFromText('LINESTRING(192783 228138,192612 229814)',-1),'Paul St'); 
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (4,GeomFromText('LINESTRING(189412 252431,189631 259122)',-1),'Graeme Ave'); 
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (5,GeomFromText('LINESTRING(190131 224148,190871 228134)',-1),'Phil Tce'); 
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (6,GeomFromText('LINESTRING(198231 263418,198213 268322)',-1),'Dave Cres');
COMMIT;

データファイルは、次に示す"psql"というSQL端末モニタを使って、簡単にPostgreSQLにパイプで送ることができます。

psql -d [データベース名] -f roads.sql

4.3.2. ローダを使う

shp2pgsqlデータローダは、ESRIシェープファイルをPostGIS/PostgreSQLデータベースに挿入するための適切なSQLに変換します。ローダには、次に示すコマンドラインフラグによって識別される、いくつかの操作モードがあります。

-d

シェープファイルにあるデータを持つ新しいテーブルを作成する前にデータベーステーブルを削除します。

-a

シェープファイルからデータベーステーブルにデータを追加します。複数のファイルをロードするためにこのオプションを使う場合は、これらのファイルは同じ属性と同じデータ型を持つ必要があります。

-c

新しいテーブルの作成とシェープファイルからのデータの読み込みを行います。これがデフォルトモードです

-p

テーブル作成のSQLコードを生成するだけで、実際のデータは追加しません。このモードは、テーブル作成とデータロードとを完全に分けたい場合に使用します。

-D

出力データにPostgreSQLのダンプ書式を用います。このモードは-a, -c, -dと組み合わせて利用します。デフォルトの"insert"によるSQL書式よりも、大変早くロードできます。大きなデータセットではこちらを使用して下さい。

-s <SRID>

指定したSRIDでジオメトリデーブルの作成とデータの読み込みを行います。

-k

識別子 (カラム、スキーマおよび属性)の大文字小文字を保持します。シェープファイルの属性は全て大文字であることに注意して下さい。

-i

全ての整数を標準の32ビット整数に強制します。DBFヘッダではそれが正当であったとしても、64ビットのbigintを生成しません。

-w

古い版 (0.x版)のPostGISのためにWKT書式を出力します。このオプションを使うと、座標変動が発生したり、M値が削除されることに注意して下さい。

-a, -c, -dおよび-pは互いに排他的であることに注意して下さい。

ローダを使って入力ファイルを生成してアップロードするセッション例は次の通りです。

# shp2pgsql shaperoads myschema.roadstable > roads.sql 
# psql -d roadsdb -f roads.sql

変換とアップロードはUNIXのパイプを使うと一回で実行できます。

# shp2pgsql shaperoads myschema.roadstable | psql -d roadsdb

4.4. GISデータを検索する

データは、SQLまたはシェープファイルローダ/ダンパを使ってデータベースから抜き出すことができます。SQLに関する節において、空間テーブルでの比較とクエリを行うために用いることができる演算子のいくつかを議論します。

4.4.1. SQLを使う

データベースからデータを引き出す最もストレートな手段は、次のように、SQLのSELECTクエリを使ってカラムを可読なテキストファイルとして出力することです。

db=# SELECT id, AsText(geom) AS geom, name FROM ROADS_GEOM; 
id | geom                                    | name 
---+-----------------------------------------+-----------
 1 | LINESTRING(191232 243118,191108 243242) | Jeff Rd  
 2 | LINESTRING(189141 244158,189265 244817) | Geordie Rd 
 3 | LINESTRING(192783 228138,192612 229814) | Paul St 
 4 | LINESTRING(189412 252431,189631 259122) | Graeme Ave 
 5 | LINESTRING(190131 224148,190871 228134) | Phil Tce 
 6 | LINESTRING(198231 263418,198213 268322) | Dave Cres 
 7 | LINESTRING(218421 284121,224123 241231) | Chris Way 
(6 rows)

しかし、返ってくる結果の数を削るために、なんらかの制限をかけることが重要となるときがあるでしょう。属性ベースの制限の場合、非空間テーブルで使う通常の文法と同じSQLを使うだけです。空間ベースの制限の場合、次の演算子が使用可能であり、便利です。

&&

この演算子で、一つのジオメトリのバウンディングボックスが他のバウンディングボックスとインタセクトするかを問い合わせることができます。

~=

この演算子で、二つのジオメトリが幾何的に同一であるかを見ることができます。 たとえば、'POLYGON((0 0,1 1,1 0,0 0))' は 'POLYGON((0 0,1 1,1 0,0 0))' と同じかを見ることができます (これは同じとなります)。

=

この演算子は他より若干素朴なもので、二つのジオメトリのバウンディングボックスが同じかを見るだけです。

次に、これらの演算子をクエリで使うことができます。SQLコマンドラインからジオメトリとボックスの特定を行うときは、"GeomFromText()"関数で、明示的に文字列表現をジオメトリに変換しなければならないことに注意して下さい。たとえば、次のようになります。

SELECT 
  ID, NAME 
FROM ROADS_GEOM 
WHERE 
  GEOM ~= GeomFromText('LINESTRING(191232 243118,191108 243242)',-1);

上のクエリは"ROADS_GEOM"テーブルから、その値と等価である単一のレコードを返します。

"&&"演算子を使うとき、比較フィーチャーをBOX3DかGEOMETRYかに指定することができます。ただし、GEOMETRYを指定すると、それのバウンディングボックスが比較に使われます。

SELECT 
  ID, NAME 
FROM ROADS_GEOM 
WHERE 
  GEOM && GeomFromText('POLYGON((191232 243117,191232 243119,191234 243117,191232 243117))',-1);

上のクエリでは、比較するためにポリゴンのバウンディングボックスを用いています。

最も一般的な空間クエリは「フレームベース」のクエリでしょう。これは、表示するためのデータの価値のある「マップフレーム」を取得するために、データブラウザやウェブマッパのようなクライアントソフトウェアに使われます。このフレームで"BOX3D"オブジェクトを使う場合は、次のようなクエリになります。

SELECT 
  AsText(GEOM) AS GEOM 
FROM ROADS_GEOM 
WHERE 
  GEOM && GeomFromText('BOX3D(191232 243117,191232 243119)'::box3d,-1);

ここで、BOX3Dの投影を指定するためにSRIDを使っていることに注意して下さい。SRIDを-1に設定しているのは、SRIDを指定しないということを示しています。

4.4.2. ダンパを使う

pgsql2shpテーブルダンパは、データベースに直接接続して、テーブル (あるいはクエリによって定義されたもの)をシェープファイルに変換するものです。基本的な文法は次の通りです。

pgsql2shp [<オプション>] <データベース> [<スキーマ>.]<テーブル>
pgsql2shp [<オプション>] <データベース> <クエリ>

コマンドラインオプションは次の通りです。

-f <ファイル名>

特定のファイル名に出力を書きこみます。

-h <ホスト>

接続先データベースのホスト名。

-p <ポート>

接続先データベースのポート。

-P <パスワード>

データベースに接続するためのパスワード。

-u <ユーザ名>

データベースに接続する際のユーザ名。

-g <ジオメトリカラム>

複数のジオメトリカラムを持つテーブルの場合の、シェープファイルの出力に使用するジオメトリカラム。

-b

バイナリカーソルを使います。これは、実行時間を短くしますが、テーブルの非ジオメトリ属性がテキストへのキャストを持っていない場合には、動作しません。

-r

Rawモード。gidフィールドを落としたり、カラム名をエスケープしてはいけません。

-d

後方互換: 古い (1.0.0より前)のPostGISデータベースからダンプする際に3次元のシェープファイルを出力します (デフォルトでは2次元になります)。 PostGIS 1.0.0以上では、次元は完全に反映されます。

4.5. インデックスを構築する

インデックスは大きなデータセットを持つ空間データベースの利用を可能にするものです。インデックスなしでは、フィーチャーの検索でデータベースの全レコードを「シーケンシャルスキャン」する必要があります。インデックスをつけることで、データを検索木に組織化して、特定のレコードを発見するための検索をより早くすることができます。 PostgreSQLは、B木、R木、GiSTの3種類のインデックスをデフォルトでサポートしています。

  • B木は、数字、文字、日付といった、一つの軸に沿ってソートできるデータに使用します。 GISデータは合理的に一つの軸に沿ったソートはできません ((0,0)と(0,1)と(1,0)で大きいのはどれでしょう?)ので、B木インデックスは、ここでは使えません。

  • R木はデータを長方形に分割して、さらにその長方形を小さい長方形に分割していったものです。R木はいくつかの空間データベースでGISデータのインデックスに使われますが、PostgreSQLのR木実装は、GiST実装ほどにロバストではありません。

  • GiST (Generalized Search Trees)インデックスはデータを「一方へのもの」 (訳注: 「左側にあるもの」「上側にあるもの」など)、「オーバラップするもの」、「中にあるもの」に分割して、GISデータを含む幅広いデータ型で使えるようにしたものです。PostGISではGISデータにインデックスを付けるためにGiSTの上でR木インデックス実装を使用しています。

4.5.1. GiSTインデックス

GiSTは「汎用的な検索木 (Generalized Search Tree)」の意味で、インデックスの一般化された形式です。GISインデックスに加えて、GiSTは通常のB木インデックスに従わない全ての種類の不規則なデータ構造 (整数配列, スペクトラルデータ等)の検索速度を向上させるために使います。

ひとたびGISデータテーブルが数千行を超えたら、空間検索の速度向上のためインデックスを構築したくなるでしょう (これは属性検索でない場合です。属性でしたら通常のインデックスを属性フィールドに追加します)。

GiSTインデックスをジオメトリカラムに追加するための文は次の通りです。

CREATE INDEX [indexname] ON [tablename] 
  USING GIST ( [geometryfield] GIST_GEOMETRY_OPS ); 

空間インデックスの構築は、計算量を集中させて行われます。100万行のテーブルで、300MHzのSolaris機ではGiSTインデックスの構築に概ね1時間かかりました。インデックスを構築したあとは、クエリプランの最適化に使うため、次のようにPostgreSQLにテーブル統計情報の収集をさせることが重要です。

VACUUM ANALYZE [テーブル名] [カラム名];
-- 次のクエリはPostgreSQL 7.4以前でのみ必要です
SELECT UPDATE_GEOMETRY_STATS( [テーブル名], [カラム名] );

GiSTインデックスはPostgreSQLのR木インデックスと比べて二つの利点を持っています。まず、GiSTインデックスは「NULLセーフ」、すなわちNULL値を含むインデックスカラムで利用できることです。次に、GiSTインデックスはGISオブジェクトがPostgreSQLで8Kのページサイズを超えるサイズを扱う際に重要な「不可逆」の概念を持っていることです。不可逆にすることによって、PostgreSQLは、インデックスにおけるオブジェクトの「重要な」部分、GISオブジェクトの場合にはバウンディングボックスになりますが、これのみを納めることができます。 R木インデックスで8Kを超えるGISオブジェクトのインデックスを構築しようとすると、失敗します。

4.5.2. インデックスを使う

通常、インデックスは見えないところでデータアクセスの速度向上を行います。すなわち、ひとたびインデックスが構築されたら、クエリプランナは透過的に、クエリプランの速度を向上させるためにインデックス情報を使うべき時を判断します。残念なことに、PostgreSQLクエリプランナは、GiSTインデックスの使用について十分に最適化できず、時々、検索で空間インデックスを使用すべきなのに、テーブル全体を順に走査することがあります。

空間インデックスが使用されていない (または属性インデックスがその問題のために使用されていない)場合、次の二つのことができます。

  • まず、クエリプランナにインデックス使用まわりの判断に利用するためのより良い情報を提供するために、値の数量と分散に関する統計情報が収集されたかを確認してください。PostgreSQL 7.4以前では、update_geometry_stats([テーブル名], [カラム名]) (分散計算)とVACUUM ANALYZE [テーブル名] [カラム名] (値の数量の計算)とを実行します。PostgreSQL 8.0については、VACUUM ANALYZEを実行することで同じ動作になります。常に定期的なデータベースへのvacuumを実行すべきです。多くのPostgreSQLのデータベースエージェントは、閑散時のcronジョブとして定期的にVACUUMを実行します。

  • vacuumが働かないなら、SET ENABLE_SEQSCAN=OFFコマンドで、プランナにインデックス情報を強制的に使わせることができます。このコマンドは控え目に実行すべきで、かつ、空間インデックスがあるクエリ上でのみ使うべきです。一般的に言うと、通常のB木インデックスを使うべき時に関してあなたが知っていることよりも、プランナはより良く知っています。クエリを実行したら、ENABLE_SEQSCAN設定を戻して、他のクエリでは通常通りプランナを使用することを考えるべきです。

    注記

    0.6版では、ENABLE_SEQSCANでプランナにインデックスを強制的に使わせることは重要ではありません。

  • 順に走査する際のコストとインデックスを使う際のコストとを比較してプランナが間違っていることに気付いたら、postgresql.confでrandom_page_costの値を減らしてみるか"SET random_page_cost=#"を使ってみてください。このパラメータのデフォルト値は4ですが、1か2にしてみて下さい。値を減らすことでプランナがよりインデックス検索を行う傾向になります。

4.6. 複雑なクエリ

空間データベース機能のレゾンデートルは、通常はデスクトップGISに求める機能を、データベース内部のクエリで実現することです。PostGISを効果的に使用するには、どの空間機能が有効かを知り、また、良い性能を提供する所に適切にインデックスがあることが保証されていることが求められます。

4.6.1. インデックスの利点を使う

クエリを作成するとき、 &&のようなバウンディングボックスを基準とした演算子によってのみGiST空間インデックスの利点が出てくることだけは覚えておくことが重要です。distance()のような関数では演算の最適化を行うためにインデックスを使うことができません。 たとえば、次のクエリでは、大きなテーブルでは本当に遅くなります。

SELECT the_geom FROM geom_table
WHERE distance( the_geom, GeomFromText( 'POINT(100000 200000)', -1 ) ) < 100

このクエリは、geom_tableにおける (100000, 200000) の点から距離が100単位以内にある全てのジオメトリを選択します。これは、テーブル内にあるそれぞれの点と指定した点との距離を計算する、すなわち、それぞれの行でひとつのdistance()計算を行うため、遅くなるのです。&&演算子を使うと、求められる距離計算の量を減らすことで回避できます。次のようにします。

SELECT the_geom FROM geom_table
WHERE the_geom && 'BOX3D(90900 190900, 100100 200100)'::box3d
  AND distance( the_geom, GeomFromText( 'POINT(100000 200000)', -1 ) ) < 100

このクエリは、同じジオメトリを選択しますが、より効果的な方法で行われます。the_geomにGiSTインデックスがあると仮定すると、クエリプランナは、distance()関数の結果を計算する前に行を減らすためにインデックスを使うことができると認識します。&&演算子で使われているBOX3Dジオメトリは、指定位置を中心とした一辺200単位の正方形です。これが「クエリボックス」です。&&演算子は 結果セットを「クエリボックス」にオーバラップするバウンディングボックスを持つジオメトリだけに素早く減らすためにインデックスを使います。「クエリボックス」がジオメトリテーブル全体の範囲より十分に小さいと仮定すると、行われなければならない距離計算の量は劇的に減少します。

4.6.2. 空間SQLの例

本節の例では、線型の道、ポリゴンの自治体境界、の二つのテーブルを使います。テーブルの定義をしまします。bc_roadsについては次の通りです。

Column    |       Type        |   Description
------------+-------------------+-------------------
 gid        | integer           | Unique ID
 name       | character varying | Road Name
 the_geom   | geometry          | Location Geometry (Linestring)

bc_municipalityテーブルの定義については次の通りです。

Column   |       Type        |   Description
-----------+-------------------+-------------------
 gid       | integer           | Unique ID
 code      | integer           | Unique ID
 name      | character varying | City / Town Name
 the_geom  | geometry          | Location Geometry (Polygon)
4.6.2.1.1. 道路の総延長はkm表記でいくらになるでしょう?
4.6.2.1.2. プリンスジョージ市の大きさはha表記でいくらになるでしょう?
4.6.2.1.3. 県内で最も大きな面積となる自治体はどこでしょう?
4.6.2.1.4. 各自治体内に含まれる道路の総延長はいくらでしょう?
4.6.2.1.5. プリンスジョージ市内の全ての道路からなるテーブルを作る
4.6.2.1.6. ビクトリア州の「ダグラス通り」の長さはkm表記でいくらになるでしょう?
4.6.2.1.7. 穴を持つ自治体ポリゴンのうち最も大きいのはどれでしょう?
4.6.2.1.1. 道路の総延長はkm表記でいくらになるでしょう?
4.6.2.1.2. プリンスジョージ市の大きさはha表記でいくらになるでしょう?
4.6.2.1.3. 県内で最も大きな面積となる自治体はどこでしょう?
4.6.2.1.4. 各自治体内に含まれる道路の総延長はいくらでしょう?
4.6.2.1.5. プリンスジョージ市内の全ての道路からなるテーブルを作る
4.6.2.1.6. ビクトリア州の「ダグラス通り」の長さはkm表記でいくらになるでしょう?
4.6.2.1.7. 穴を持つ自治体ポリゴンのうち最も大きいのはどれでしょう?

4.6.2.1.1.

道路の総延長はkm表記でいくらになるでしょう?

この問題は、次のようなとても単純なSQLで答を得ることができます。

postgis=# SELECT sum(length(the_geom))/1000 AS km_roads FROM bc_roads;
     km_roads
------------------
 70842.1243039643
(1 row)

4.6.2.1.2.

プリンスジョージ市の大きさはha表記でいくらになるでしょう?

このクエリでは、属性条件 (municipality name, 自治体名)に空間計算 (面積)を併用しています。

postgis=# SELECT area(the_geom)/10000 AS hectares FROM bc_municipality 
          WHERE name = 'PRINCE GEORGE';
     hectares
------------------
 32657.9103824927
(1 row) 

4.6.2.1.3.

県内で最も大きな面積となる自治体はどこでしょう?

このクエリは、空間計測をクエリ条件に持ってきています。この問題へのアプローチの方法はいくつかありますが、最も効率的なのは次の通りです。

postgis=# SELECT name, area(the_geom)/10000 AS hectares 
          FROM bc_municipality 
          ORDER BY hectares DESC 
          LIMIT 1;
     name      |    hectares
---------------+-----------------
 TUMBLER RIDGE | 155020.02556131
(1 row)

このクエリの答を出すためには、全てのポリゴンの面積を求める必要があることに注意して下さい。このクエリを多く実行する場合、性能向上のためにテーブルにareaカラムを追加して、別のインデックスを追加することができるようにするのは、意義のあることです。結果を距離について降順に並べ替え、PostgreSQLの"LIMIT"コマンドを用いることで、max()のような集約関数を使わずに、簡単に最も大きい値を得ることができます。

4.6.2.1.4.

各自治体内に含まれる道路の総延長はいくらでしょう?

これは、二つのテーブルからデータを持ち込んで (結合して)いるので「空間結合」の例です。しかし、結合の条件として共通キーの上で接続するという普通のリレーションのやり方でなく空間インタラクション条件 (「含む」)を使っています。

postgis=# SELECT m.name, sum(length(r.the_geom))/1000 as roads_km 
          FROM bc_roads AS r,bc_municipality AS m 
          WHERE r.the_geom && m.the_geom 
          AND contains(m.the_geom,r.the_geom) 
          GROUP BY m.name 
          ORDER BY roads_km;

            name            |     roads_km
----------------------------+------------------
 SURREY                     | 1539.47553551242
 VANCOUVER                  | 1450.33093486576
 LANGLEY DISTRICT           | 833.793392535662
 BURNABY                    | 773.769091404338
 PRINCE GEORGE              |  694.37554369147
 ...

このクエリは、テーブル内の全ての道路の合計を最終結果 (この例での話ですが約250Kmの道です)にまとめられるので、少し時間がかかります。より小さいオーバレイ (数百の道路で数千のレコード)の場合、応答はもっと早くなりえます。

4.6.2.1.5.

プリンスジョージ市内の全ての道路からなるテーブルを作る

これは「オーバレイ」の例です。つまり、二つのテーブルを取得して、空間的に切り取られた結果からなる新しいテーブルを出力します。上で示した「空間結合」と違い、このクエリは実際に新しいジオメトリを生成します。生成されたオーバレイはターボのかかった空間結合みたいなもので、より確かな解析作業に便利です。

postgis=# CREATE TABLE pg_roads as
          SELECT intersection(r.the_geom, m.the_geom) AS intersection_geom, 
                 length(r.the_geom) AS rd_orig_length, 
                 r.* 
          FROM bc_roads AS r, bc_municipality AS m 
          WHERE r.the_geom && m.the_geom 
          AND intersects(r.the_geom, m.the_geom) 
          AND m.name = 'PRINCE GEORGE';

4.6.2.1.6.

ビクトリア州の「ダグラス通り」の長さはkm表記でいくらになるでしょう?

postgis=# SELECT sum(length(r.the_geom))/1000 AS kilometers 
          FROM bc_roads r, bc_municipality m 
          WHERE r.the_geom && m.the_geom 
          AND r.name = 'Douglas St' 
          AND m.name = 'VICTORIA';
    kilometers
------------------
 4.89151904172838
(1 row)

4.6.2.1.7.

穴を持つ自治体ポリゴンのうち最も大きいのはどれでしょう?

postgis=# SELECT gid, name, area(the_geom) AS area 
          FROM bc_municipality 
          WHERE nrings(the_geom) > 1 
          ORDER BY area DESC LIMIT 1;
 gid |     name     |       area
-----+--------------+------------------
  12 | SPALLUMCHEEN | 257374619.430216
(1 row)

4.7. MapServerを使う

Minnesota MapServerはOpenGIS Web Mapping Server仕様を満たすウェブマッピングサーバです。

4.7.1. 基本的な使い方

MapServerでPostGISを使うには、MapServerのコンフィギュレーション方法についての知識が必要ですが、この文書の範囲外です。この節では、PostGIS特有の問題とコンフィギュレーション詳細について記載します。

MapServerでPostGISを使うには、次のものが必要です。

  • PostGIS 0.6以上

  • MapServer 3.5以上

MapServerは、他のPostgreSQLクライアントのように、libpqを使ってPostGIS/PostgreSQLデータにアクセスします。これは、システムがPostgreSQLクライアントライブラリであるlibpqを持っている限りは、PostGISサーバへのネットワークアクセスを持つあらゆる機械にMapServerをインストールできるということを示しています。

  1. "--with-postgis"と好きなconfigureオプションを付けてMpaserverのコンパイルとインストールを行います。

  2. MapServerのmapファイルの中に、PostGISレイヤを追加します。たとえば次のようになります。

    LAYER
      CONNECTIONTYPE postgis
      NAME "widehighways"
      # リモートの空間データベースに接続します
      CONNECTION "user=dbuser dbname=gisdatabase host=bigserver"
      # 'roads'テーブルの'geom'カラムからラインを取得します
      DATA "geom from roads"
      STATUS ON
      TYPE LINE
      # 範囲内のラインのうち、広い高速道路のみ描画します
      FILTER "type = 'highway' and numlanes >= 4"
      CLASS
        # 非常に広い高速道路はより明るい色かつ2ピクセル幅にします
        EXPRESSION ([numlanes] >= 6)
        COLOR 255 22 22      
        SYMBOL "solid"
        SIZE 2
      END
      CLASS
        # 残りは、暗い色かつ1ピクセル幅です
        EXPRESSION ([numlanes] < 6)
        COLOR 205 92 82      
      END
    END

    上の例におけるPostGIS特有のディレクティブは次の通りです。

    CONNECTIONTYPE

    PostGISレイヤでは常に"postgis"とします。

    CONNECTION

    データベース接続は「接続文字列」によって制御されます。接続文字列は、次に示すような標準的なキーと値からなります(<>内はデフォルト値)。

    user=<ユーザ名> password=<パスワード> dbname=<ユーザ名> hostname=<サーバ> port=<5432>

    空の接続文字列も妥当とされますし、あらゆるキーと値のペアは省略できます。接続するためには一般的にはdbnameとusernameとが最少で与えるものとなります。

    DATA

    このパラメータの形式は "<カラム名> from <テーブル名>"となります。ここで、カラム名は地図に描画したい空間カラムを指します。

    FILTER

    フィルタは、妥当なSQL文字列でなければなりません。この文字列は、通常はSQLクエリにおける"WHERE"に続く論理式に対応します。たとえば、6レーン以上の道路だけを描画する場合には、"num_lanes >= 6"というフィルタを使います。

  3. 空間データベースにおいては、空間 (GiST)インデックスを、マップに描かれるレイヤ全てに構築していることを保証して下さい。

    CREATE INDEX [インデックス名]
      ON [テーブル名] 
      USING GIST ( [ジオメトリカラム] GIST_GEOMETRY_OPS );
  4. MapServerを使ってレイヤにクエリを発行する場合は、「oidインデックス」も必要です (訳注: PostgreSQL 8.1以降は、oidはデフォルトでは追加されなくなりました。替わりにSERIAL型フィールドを生成して使うべきです。テーブル生成時に"WITH OID"を付けるとoid付きテーブルが生成されます)。

    MapServerからは、クエリを実行するときに、それぞれの空間レコードを識別する一意な識別子が求められ、MapServerのPostGISモジュールはPostgreSQLのoid値を一意な識別子に使います。これの副作用はクエリ内のレコードのランダムアクセスを早く行うのにoidインデックスが必要となることです。

    「oidインデックス」を構築するには、次のようなSQLを実行します。

    CREATE INDEX [インデックス名] ON [テーブル名] ( oid );

4.7.2. よくある質問

4.7.2.1.1. EXPRESSIONをマップファイルで使う時に、値がテーブルにあるのを確認しているのに条件がtrueになりません。
4.7.2.1.2. シェープファイルで使っているFILTERが、同じデータを持つPostGISテーブルでは動作しません。
4.7.2.1.3. PostGISレイヤの描画がシェープファイルより遅くなりますが、これが普通なのでしょうか?
4.7.2.1.4. PostGISレイヤはちゃんと描けましたが、クエリが本当に遅いです。何が問題なのですか?
4.7.2.1.1. EXPRESSIONをマップファイルで使う時に、値がテーブルにあるのを確認しているのに条件がtrueになりません。
4.7.2.1.2. シェープファイルで使っているFILTERが、同じデータを持つPostGISテーブルでは動作しません。
4.7.2.1.3. PostGISレイヤの描画がシェープファイルより遅くなりますが、これが普通なのでしょうか?
4.7.2.1.4. PostGISレイヤはちゃんと描けましたが、クエリが本当に遅いです。何が問題なのですか?

4.7.2.1.1.

EXPRESSIONをマップファイルで使う時に、値がテーブルにあるのを確認しているのに条件がtrueになりません。

EXPRESIONで使うフィールド名は、シェープファイルと違ってPostGISの場合小文字になります。

EXPRESSION ([numlanes] >= 6)

4.7.2.1.2.

シェープファイルで使っているFILTERが、同じデータを持つPostGISテーブルでは動作しません。

シェープファイルと違い、PostGISレイヤのフィルタはSQL構文を使います (PostGISコネクタがMapServerでレイヤを描画するために生成するSQLステートメントに追加されます)。

FILTER "type = 'highway' and numlanes >= 4"

4.7.2.1.3.

PostGISレイヤの描画がシェープファイルより遅くなりますが、これが普通なのでしょうか?

一般的に、PostGISレイヤは同等のシェープファイルレイヤより10%遅いと考えて下さい。 データベースとMapServerとの間で発生するデータベース接続、データの変換と転送によってオーバヘッドが増えるためです。

重大な描画性能の問題があるようでしたら、テーブルにある空間インデックスを構築していないというのがありそうです。

postgis# CREATE INDEX geotable_gix ON geotable USING GIST ( geocolumn );
postgis# SELECT update_geometry_stats();  -- PostgreSQL 8.0より後
postgis# VACUUM ANALYZE;                  -- PostgreSQL 8.0以前

4.7.2.1.4.

PostGISレイヤはちゃんと描けましたが、クエリが本当に遅いです。何が問題なのですか?

クエリを早くするには、空間テーブルに一意なキーを持たせ、そのキーにインデックスを持たせなければなりません。

DATA行のUSING UNIQUE節で、MapServerで使用する一意なキーをどれにするか指定することができます。

DATA "the_geom FROM geotable USING UNIQUE gid"

テーブルに明示的に一意なカラムが無い場合は、PostgreSQLの行"oid"を用いて一意なカラムを「模造する」ことができます。"oid"は、宣言していないなら、デフォルトの一意なカラムです。ですから、クエリ速度を強化するには、空間テーブルのoid値にインデックスを構築することです (訳注: PostgreSQL 8.1以降は、oidはデフォルトでは追加されなくなりました)。

postgis# CREATE INDEX geotable_oid_idx ON geotable (oid);

4.7.3. 踏み込んだ使用法

USING疑似SQL節を使ってMapServerがより複雑なクエリの結果を理解できるようにするための情報を追加します。より詳しく言うと、ビューまたは副問い合わせが元テーブル (DATA定義で"FROM"の右にあるもの)として使われる時、MapServerが自動的に一意な識別子がそれぞれの行にあるか、また、SRIDがテーブルにあるかを判別するのは困難です。USING節によって、MapServerがこれらの情報を得ることができます。例を次に挙げます。

DATA "the_geom FROM (SELECT table1.the_geom AS the_geom, table1.oid AS oid, table2.data AS data
 FROM table1 LEFT JOIN table2 ON table1.id = table2.id) AS new_table USING UNIQUE oid USING SRID=-1"
USING UNIQUE <uniqueid>

MapServerは、マップクエリを実行する際、行識別のために、それぞれの行に一意な識別子を求めます。 通常なら、oidを一意な識別子として使えますが、ビューや副問い合わせでは、自動的にoidを持つことができません。MapServerのクエリ機能を使いたいなら、一意性のあるカラムをビューまたは副問い合わせに追加する必要があり、USING UNIQUE宣言を付ける必要があります。たとえば、この目的のための主キー値のテーブルでのカラム名や、結果セットで一意性が保障されたカラムを明示的にSELECTに入れることができます。

マップクエリを実行する場合には、USINGステートメントは単純なDATAステートメントに対しても便利なものになります。マップクエリの速度性能向上のために、クエリ実行可能なレイヤで使われるテーブルのoidカラムにインデックスを追加することを、前に推奨しました。しかしながら、USINGを使うと、MapServerがテーブルのプライマリキーをマップクエリの識別子に使うことができ、インデックスを追加する必要はもうありません。

注記

「マップクエリ」はマップ上でクリックして、その場所におけるフィーチャーに関する情報を問い合わせる動作です。「マップクエリ」とDATA定義におけるSQLクエリと混同しないで下さい。

USING SRID=<srid>

PostGISは、MapServerに正しいデータを返すために、ジオメトリがどの空間参照系を使っているかを知る必要があります。通常は、この情報はPostGISデータベースの"geometry_columns"テーブルから得ることができます。しかし、副問い合わせやビューのような一時テーブルでは、この方法は不可能です。そこで、USING SRID=オプションを使って、正しいSRIDがDATA定義で使われるように指定します。

警告

MapserverのPostGISレイヤのパーサは、かなり原始的で、大文字小文字を区別するところが2,3あります。全てのSQLキーワードと全てのUSING節が大文字であることを保証し、USING UNIQUE節がUSING SRID節より前に来るようにして下さい。

4.7.4. 例

簡単な例から始めて、ステップアップしていきましょう。次のMapServerレイヤ定義を考えて下さい。

LAYER
 CONNECTIONTYPE postgis
 NAME "roads"
 CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
 DATA "the_geom FROM roads"
 STATUS ON
 TYPE LINE
 CLASS
  COLOR 0 0 0
 END
END

このレイヤは"roads"テーブルにある道路ジオメトリの全部を黒線で表示するものです。

では、少なくとも1:100000にズームするまでは高速道路だけを表示したい、としましょう。次の二つのレイヤで、その効果が実現できます。

LAYER
 CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
 DATA "the_geom FROM roads"
 MINSCALE 100000
 STATUS ON
 TYPE LINE
 FILTER "road_type = 'highway'"
 CLASS
  COLOR 0 0 0
 END
END

LAYER
 CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
 DATA "the_geom FROM roads"
 MAXSCALE 100000
 STATUS ON
 TYPE LINE
 CLASSITEM road_type
 CLASS
  EXPRESSION "highway"
  SIZE 2
  COLOR 255 0 0
 END
 CLASS
  COLOR 0 0 0
 END
END

一つ目のレイヤはスケールが1:100000以上であるときに使われ、道路タイプが"highway"である道路のみ黒線で表示されます。FILTERオプションによって、道路タイプが"highway"の場合のみ表示することになります。

二つ目のレイヤはスケールが1:100000未満である時に使われ、"highway"は赤い二重細線で表示され、他の道路は黒線で表示されます。

さて、MapServerの機能を使うだけで、二つのおもしろいことを実行しました。しかし、DATAのSQLステートメントは、単純なままです。道路名が (どういう理由かは知りませんが)他のテーブルに収められていて、それのデータを取得するためにテーブルを連結して、道路のラベルを取る必要がある、とします。

LAYER
 CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
 DATA "the_geom FROM (SELECT roads.oid AS oid, roads.the_geom AS the_geom, road_names.name as name
   FROM roads LEFT JOIN road_names ON roads.road_name_id = road_names.road_name_id) AS named_roads
   USING UNIQUE oid USING SRID=-1"
 MAXSCALE 20000
 STATUS ON
 TYPE ANNOTATION
 LABELITEM name
 CLASS
  LABEL
   ANGLE auto
   SIZE 8
   COLOR 0 192 0
   TYPE truetype
   FONT arial
  END
 END
END

このANNOTAIONレイヤでは、縮尺が1:20000以下のときに、全ての道路に緑色のラベルを表示します。また、この例は、DATA定義で、SQLのJOINを使用する方法も示しています。

4.8. Javaクライアント (JDBC)

Javaクライアントは、直接的にテキスト表現として、またはPostGISに同梱されているJDBC拡張オブジェクトを使用して、PostgreSQLデータベース内にある、PostGISの"geometry"オブジェクトにアクセスできます。JDBC拡張オブジェクトを使うためには、"postgis.jar"ファイルを、JDBCドライバパッケージの"postgresql.jar"とともに、 CLASSPATHに置く必要があります。

import java.sql.*; 
import java.util.*; 
import java.lang.*; 
import org.postgis.*; 

public class JavaGIS { 
  public static void main(String[] args) 
  { 
    java.sql.Connection conn; 
    try 
    { 
      /* 
      * JDBCドライバをロードして接続を確立します。
      */  
      Class.forName("org.postgresql.Driver"); 
      String url = "jdbc:postgresql://localhost:5432/database"; 
      conn = DriverManager.getConnection(url, "postgres", ""); 
    
      /*
      * ジオメトリ型を接続に追加します。
      * ご注意 : addDateType()を呼ぶ前に
      *   接続をpgsql特有の接続実装にキャストしなければなりません。
      */
      ((org.postgresql.Connection)conn).addDataType("geometry","org.postgis.PGgeometry");
      ((org.postgresql.Connection)conn).addDataType("box3d","org.postgis.PGbox3d");

      /*
      * ステートメントの生成とSELECTクエリの実行を行います。
      */
      Statement s = conn.createStatement(); 
      ResultSet r = s.executeQuery("select AsText(geom) as geom,id from geomtable"); 
      while( r.next() ) 
      { 
        /*
        * ジオメトリをオブジェクトとして検索してジオメトリ型にキャストします。
        * オブジェクトを印字します
        */
        PGgeometry geom = (PGgeometry)r.getObject(1); 
        int id = r.getInt(2);
        System.out.println("Row " + id + ":"); 
        System.out.println(geom.toString()); 
      }
      s.close(); 
      conn.close(); 
    } 
    catch( Exception e ) 
    { 
      e.printStackTrace(); 
    }  
  }
}

"PGeometry"オブジェクトは、Point、LineString、Polygon、MultiPoint、MultiLineString、MultiPolygonの各型に依存する、特定のトポロジカルジオメトリオブジェクト ("Geometory"抽象クラスの子クラス)を持つラッパオブジェクトです。

PGgeometry geom = (PGgeometry)r.getObject(1); 
if( geom.getType() = Geometry.POLYGON ) 
{ 
  Polygon pl = (Polygon)geom.getGeometry();
  for( int r = 0; r < pl.numRings(); r++ ) 
  { 
    LinearRing rng = pl.getRing(r);
    System.out.println("Ring: " + r); 
    for( int p = 0; p < rng.numPoints(); p++ ) 
    { 
      Point pt = rng.getPoint(p); 
      System.out.println("Point: " + p);
      System.out.println(pt.toString()); 
    } 
  } 
}

幾何オブジェクトのさまざまなデータアクセサ関数に関する参照情報については、拡張オブジェクトのJavaDocをご覧下さい。

4.9. Cクライアント (libpq)

...

4.9.1. テキストカーソル

...

4.9.2. バイナリカーソル

...

第5章 性能向上に関する技法

5.1. 大きなジオメトリを持つ小さなテーブル

5.1.1. 問題の説明

現版のPostgreSQL (8.0を含む)では、TOASTテーブルに従うクエリオプティマイザの弱さに苦しみます。 TOASTテーブルは、(長いテキスト、イメージ、多数の頂点を持つ複合ジオメトリといった)通常のデータページに適合しない、(データサイズという意味では)巨大な値を納めるための「拡張部屋」の一種です。詳細情報はhttp://www.postgresql.org/docs/8.0/static/storage-toast.htmlをご覧ください。

(高解像度で全てのヨーロッパの国の境界を含むテーブルのような)大きなジオメトリがあるうえ、行がそう多くないテーブルを持つようになると、この問題が出てきます。テーブル自体は小さいのですが、多くのTOASTスペースを使います。例として、テーブル自体は概ね80行で3データページしか使わなくてもTOASTテーブルで8225ページを使うとします。

ここで、ジオメトリ演算子の&&を使って、ほとんどマッチしないようなバウンダリボックスを検索するクエリを出してみます。クエリオプティマイザにはテーブルは3ページ80行しかないように見えます。オプティマイザは、小さなテーブルを順に走査する方がインデックスを使うよりも早いと見積もります。そして、GiSTインデックスは無視すると決めます。通常なら、この見積もりは正しいです。しかし、この場合は&&演算子が全てのジオメトリをディスクから呼び出しでバウンディングボックスと比較しなければならなくなり、ゆえに、全てのTOASTページもまた呼び出す必要があります。

このバグに苦しむかどうかを見るには、PostgreSQLの"EXPLAIN ANALYZE"コマンドを使います。詳しい情報と技術に関する詳細については、postgres performance mailing list のスレッド(http://archives.postgresql.org/pgsql-performance/2005-02/msg00030.php)をご覧下さい。

5.1.2. 応急処置

PostgreSQLコミュニティでは、TOASTを意識したクエリ見積もりを作ることで、この問題を解決しようとしています。今のところは、二つの応急処置があります。

一つは、クエリプランナにインデックスの使用を強制することです。クエリを発行する前に"SET enable_seqscan TO off;"をサーバに送信します。これは基本的にクエリプランナに対して可能な限り順に走査することを避けるよう強制します。そのためGiSTインデックスを通常使うようになります。しかし、このフラグは接続するたびに設定しなければならず、他のケースにおいてはクエリプランナに誤った見積もりをさせることになるので、 "SET enable_seqscan TO on;"をクエリの後に送信すべきです。

もう一つは、順に走査することをクエリプランナが考える程度に早くすることです。これは、バウンダリボックスの「キャッシュ」を行う追加カラムを作成し、このカラムにマッチさせるようにすることで達成することができます。ここでの例では次のようになります。

SELECT addGeometryColumn('myschema','mytable','bbox','4326','GEOMETRY','2');

UPDATE mytable set bbox = Envelope(Force_2d(the_geom));

そして、次のように、&&演算子をgeom_columnに対して行っていたものをbboxに変更します。

SELECT geom_column FROM mytable WHERE bbox && SetSrid('BOX3D(0 0,1 1)'::box3d,4326);

もちろん、mytableの行を変更または追加したら、bboxを「同期」するようにしなければなりません。最もすっきりした方法はトリガです。もしくは、アプリケーションを変更してbboxカラムの現状を保持するか、テーブル更新後にいつもUPDATEクエリを実行するかでも対応できます。

5.2. ジオメトリインデックスでCLUSTERを実行する

読み込むことがほとんどで、かつほとんどのクエリでひとつのインデックスを使うようなテーブルのために、PostgreSQLはCLUSTERコマンドを提供しています。このコマンドは、全てのデータ行を、インデックス基準にあわせて物理的に再整理するので、二つの性能の利点を生みます。一つは、インデックスの範囲走査のために、データテーブルのシーク回数が劇的に減少することです。もう一つは、いくつかの小さなインデックス間隔に集中する場合には、データ行が分布するデータページがより少なくなるので、より効率的なキャッシュを持つことです (この点で、PostgreSQLマニュアルのCLUSTERコマンドのドキュメントを読むように仕向けられていると感じて下さい)。

しかし、GiSTインデックスは単純にNULL値を無視するため現在のところPostGISのGiSTインデックスのクラスタリングはできず、次のようなエラーメッセージを得ます。

lwgeom=# CLUSTER my_geom_index ON my_table;
ERROR:  cannot cluster when index access method does not handle null values
HINT:  You may be able to work around this by marking column "the_geom" NOT NULL.

ヒントメッセージにある通り、テーブルに"not null"制限を追加することで、この欠陥にとりあえず対応できます。例を示します。

lwgeom=# ALTER TABLE my_table ALTER COLUMN the_geom SET not null;
ALTER TABLE

もちろん、ジオメトリカラムで実際にNULL値が必要な場合、この対応はできません。さらには、制限を追加するには上の方法を使わなければならず、"ALTER TABLE blubb ADD CHECK (geometry is not null);"のようなCHECK制限は使えません。

5.3. 次元変換の回避

ときどき、テーブルで3次元、4次元のデータを持つのに、常にOpenGIS準拠のasText()またはasBinary()関数を使ってアクセスして 2次元ジオメトリを出力させるようなことが起きます。 内部でforce_2d()関数を呼んでいるために発生しますが、 これは、大きなジオメトリでは重大なオーバヘッドを誘引することになります。 このオーバヘッドを回避するには、一度追加された次元を前もって落とし、かつこれを永続化するのが適当かも知れません。

UPDATE mytable SET the_geom = force_2d(the_geom);
VACUUM FULL ANALYZE mytable;

AddGeometryColumn()を使ってジオメトリカラムを追加した場合、ジオメトリの次元に関する制限があることに注意してください。この制限を迂回するには、制限の削除が必要になります。geometry_columnsテーブル内のエントリを更新して、その後で制限を再作成することを忘れないで下さい。

In case of large tables, it may be wise to divide this UPDATE into smaller portions by constraining the UPDATE to a part of the table via a WHERE clause and your primary key or another feasible criteria, and running a simple "VACUUM;" between your UPDATEs. This drastically reduces the need for temporary disk space. Additionally, if you have mixed dimension geometries, restricting the UPDATE by "WHERE dimension(the_geom) >2" skips re-writing of geometries that already are in 2D.

第6章 PostGISリファレンス

ここで示す関数はPostGISユーザが必要とすると思われる関数です。この他に、一般的なユーザが使わないPostGISオブジェクトに対して求められるサポート関数があります。

6.1. OpenGIS関数

6.1.1. 管理関数

AddGeometryColumn(varchar, varchar, varchar, integer, varchar, integer)

構文: AddGeometryColumn(<スキーマ名>, <テーブル名>, <カラム名>, <srid>, <タイプ>, <次元>). 存在する属性テーブル (訳注:ジオメトリカラムが存在しない意と思われますが、ジオメトリカラムが既に存在していても追加できます)」にジオメトリカラムを追加します。スキーマ名は、テーブルスキーマの名前です (プリスキーマ版PostgreSQLの場合は使われません)。 sridは、SPATIAL_REF_SYSテーブルに登録されている整数値でなければなりません。 型は、'POLGYON', 'MULTILINESTRING' などのように、常に大文字の文字列で、ジオメトリ型に対応していなければなりません。

DropGeometryColumn(varchar, varchar, varchar)

構文: DropGeometryColumn(<スキーマ名>, <テーブル名>, <カラム名>). ジオメトリカラムを空間テーブルから削除します。 スキーマ名はgeometry_columnsテーブル内にある、そのテーブル名を持つ行のf_schema_nameフィールドと一致しなければならないことに注意して下さい。

SetSRID(geometry)

ジオメトリのSRIDを特定の整数値に設定します。クエリのためのバウンディングボックスを生成する際に使います。

6.1.2. 空間関係関数

Distance(geometry,geometry)

二つのジオメトリ間の2次元距離の最大値を、投影法の単位で返します。

Equals(geometry,geometry)

ジオメトリが「空間的に等価」であるなら1 (TRUE)を返します。 '='より「良い」回答が得られます。equals('LINESTRING(0 0, 10 10)','LINESTRING(0 0, 5 5, 10 10)')は、TRUEになります。

GEOSモジュールによって実現しています。

OGC SPEC s2.1.1.2

Disjoint(geometry,geometry)

ジオメトリが「空間的に接続されていない」なら1 (TRUE)を返します。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

ご注意: これは論理値を返して整数を返さないのが「許される」版です。

OGC SPEC s2.1.1.2 //s2.1.13.3 - a.Relate(b, 'FF*FF****')

Intersects(geometry,geometry)

ジオメトリが「空間的にインタセクトしている (訳注:共通領域を持つ)」なら1 (TRUE)を返します。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

ご注意: これは論理値を返して整数を返さないのが「許される」版です。

OGC SPEC s2.1.1.2 //s2.1.13.3 - Intersects(g1, g2 ) --> Not (Disjoint(g1, g2 ))

Touches(geometry,geometry)

ジオメトリが「空間的に接触している」なら1 (TRUE)を返します。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

ご注意: これは論理値を返して整数を返さないのが「許される」版です。

OGC SPEC s2.1.1.2 // s2.1.13.3- a.Touches(b) -> (I(a) intersection I(b) = {empty set} ) and (a intersection b) not empty

Crosses(geometry,geometry)

ジオメトリが「空間的にクロスしている (訳注:共通領域を持ち、かつ共通領域の次元が引数ジオメトリの最大次元-1」なら1 (TRUE)を返します。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

ご注意: これは論理値を返して整数を返さないのが「許される」版です。

OGC SPEC s2.1.1.2 // s2.1.13.3 - a.Relate(b, 'T*T******')

Within(geometry,geometry)

ジオメトリAが「空間的に」ジオメトリB「の中にある」なら1 (TRUE)を返します。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

ご注意: これは論理値を返して整数を返さないのが「許される」版です。

OGC SPEC s2.1.1.2 // s2.1.13.3 - a.Relate(b, 'T*F**F***')

Overlaps(geometry,geometry)

ジオメトリが「空間的にオーバラップしている (訳注:共通領域を持ち、引数の2ジオメトリと共通領域が同次元で、かつ共通領域が引数の2ジオメトリと同一でない)」なら1 (TRUE)を返します。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

ご注意: これは論理値を返して整数を返さないのが「許される」版です。

OGC SPEC s2.1.1.2 // s2.1.13.3

Contains(geometry,geometry)

ジオメトリAがジオメトリBを「空間的に含んでいる」なら1 (TRUE)を返します。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

ご注意: これは論理値を返して整数を返さないのが「許される」版です。

OGC SPEC s2.1.1.2 // s2.1.13.3 - same as within(geometry,geometry)

Intersects(geometry,geometry)

ジオメトリが「空間的にインタセクトしている (訳注:共通領域を持つ)」なら1 (TRUE)を返します。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

ご注意: これは論理値を返して整数を返さないのが「許される」版です。

OGC SPEC s2.1.1.2 // s2.1.13.3 - NOT disjoint(geometry,geometry)

Relate(geometry,geometry, intersectionPatternMatrix)

このジオメトリが空間的に、もう一つのジオメトリに関連しているなら1 (TRUE)を返します。 この関連は、intersectionPatternMatrix行列の値によって指定された、 二つのジオメトリの内部、境界、外部の交差要素を見ることで決定されます。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

ご注意: これは論理値を返して整数を返さないのが「許される」版です。

OGC SPEC s2.1.1.2 // s2.1.13.3

Relate(geometry,geometry)

DE-9IM (次元拡張された9要素行列)を返します。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

OGC仕様にはありませんが実装しました。s2.1.13.2をご覧下さい。

6.1.3. ジオメトリ処理関数

Centroid(geometry)

ジオメトリの重心をポイントとして返します。

GEOSモジュールによって実現されている (コンパイル時に指定されます)なら、より正確に計算できます。

Area(geometry)

ジオメトリがポリゴンかマルチポリゴンならジオメトリの面積を返します。

Length(geometry)

ジオメトリの、組み込まれている空間参照系での曲線長を返します。

これはlength2d()の別名です。

OGC SPEC 2.1.5.1

PointOnSurface(geometry)

表面にあることが保障された点を返します。

GEOSモジュールによって実現しています。

OGC SPEC 3.2.14.2 and 3.2.18.2 -

Boundary(geometry)

ジオメトリの組み合わせ境界の閉包を返します (訳注: ラインストリングは端点、ポリゴンはエッジ、複合オブジェクトは境界のうち奇数番)。組み合わせ境界はOGC仕様の3.12.3.2節に記述されています。結果として出てくる境界は、OGC SPEC 3.12.2で議論されているように、ジオメトリプリミティブを使って表現できます。

GEOSモジュールによって実現しています。

OGC SPEC s2.1.1.1

Buffer(geometry,double,[integer])

ジオメトリからの距離が指定した距離未満となる全てのポイントを示すジオメトリを返します。オプションの第3引数では、4分の1にした円を近似するために使われる弦の数を設定します (デフォルトは8です)。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

OGC SPEC s2.1.1.3

ConvexHull(geometry)

ジオメトリの凸包を表現するジオメトリを返します。

GEOSモジュールによって実現しています。

OGC SPEC s2.1.1.3

Intersection(geometry,geometry)

ジオメトリがインタセクトする点を示すジオメトリを返します。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

OGC SPEC s2.1.1.3

SymDifference(geometry,geometry)

ジオメトリの対称差 (AとBで共通しない部分)を示すジオメトリを返します。対称と呼ばれるのは、ST_SymDifference(A,B) = ST_SymDifference(B,A)となるからです。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

OGC SPEC s2.1.1.3

Difference(geometry,geometry)

ジオメトリの対称差 (AとBで共通しない部分)を示すジオメトリを返します。対称と呼ばれるのは、ST_SymDifference(A,B) = ST_SymDifference(B,A)となるからです。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

OGC SPEC s2.1.1.3

GeomUnion(geometry,geometry)

ジオメトリを結合したポイント集合を示すジオメトリを返します。

GEOSモジュールによって実現しています。

ジオメトリコレクションを引数として呼ばないでください。

ご注意: この関数は"union"から名前を変更しました。SQLの予約語であるためです。

OGC SPEC s2.1.1.3

GeomUnion(geometry set)

与えられた集合の全てのジオメトリを結合したポイント集合を示すジオメトリを返します。

GEOSモジュールによって実現しています。

GeometryCollectionを引数集合で呼んではいけません。

OGC仕様では明示的に定義されていません。

MemGeomUnion(geometry set)

上と同じですが、メモリフレンドリ (少ないメモリ使用で長い処理時間)です。

6.1.4. ジオメトリアクセサ

AsText(geometry)

ジオメトリのWell-Known Text表現を返します。たとえばPOLYGON(0 0,0 1,1 1,1 0,0 0)などです。

OGC SPEC s2.1.1.1

AsBinary(geometry)

ジオメトリをOGC"Well-Known Binary"表現で返します。データベースが動いているサーバのエンディアンを使います。これは文字列表現に変換せずにデータをデータベースから引き出すバイナリカーソルに有用です。

OGC SPEC s2.1.1.1 - asBinary(<geometry>,'XDR') and asBinary(<geometry>,'NDR')も参照して下さい

SRID(geometry)

ジオメトリの空間参照系SRIDを整数で返します。

OGC SPEC s2.1.1.1

Dimension(geometry)

このジオメトリオブジェクトの固有の次元です。 ジオメトリオブジェクトは座標の次元以下である必要があります。OGC SPEC s2.1.1.1 - 0ならポイント、1ならライン、2ならポリゴン、ジオメトリコレクションの場合は要素ごとの次元の最大値です。

select dimension('GEOMETRYCOLLECTION(LINESTRING(1 1,0 0),POINT(0 0)'); 
dimension 
-----------
1
Envelope(geometry)

ジオメトリーのバウンディングボックスを表している有効なジオメトリ (POINT、LINESTRINGまたはPOLYGON)を返します。

OGC SPEC s2.1.1.1 -このジオメトリの最小のバウンディングボックスをジオメトリとして返します。ポリゴンはバウンディングボックスの頂点((MINX, MINY), (MAXX, MINY), (MAXX, MAXY), (MINX, MAXY), (MINX, MINY))で定義されます。

ご注意: PostGISはZmin/Zmax座標も同様に加えます。

IsEmpty(geometry)

ジオメトリが空ジオメトリなら1 (TRUE)を返します。 TRUEなら、このジオメトリは空のポイント集合を示すジオメトリ、すなわちGEOMETRYCOLLECTION(EMPTY)です。

OGC SPEC s2.1.1.1

IsSimple(geometry)

ジオメトリが、自己交差、自己接触といった異常な幾何学点を持っていないなら1 (TRUE)を返します。

GEOSモジュールによって実現しています。

OGC SPEC s2.1.1.1

IsClosed(geometry)

開始点と終了点とが同じになっているジオメトリならTRUEを返します。

IsRing(geometry)

この曲線が閉じていて( StartPoint( ) = EndPoint( ) )、この曲線が単純 (2回以上同一点を通過しない)なら1 (TRUE)を返します。

GEOSモジュールによって実現しています。

OGC spec 2.1.5.1

NumGeometries(geometry)

ジオメトリがGEOMETRYCOLLECTION (または MULTI系)の場合はジオメトリ数を返し、そうでないならNULLを返します。

GeometryN(geometry,int)

ジオメトリがGEOMETRYCOLLECTION, MULTIPOINT, MULTILINESTRINGまたはMULTIPOLYGONの場合はN番目のジオメトリを返します。それ以外の場合はNULLを返します。

1が最初のジオメトリです。

NumPoints(geometry)

ジオメトリの最初のラインストリングのポイント数を返します。ジオメトリにラインストリングが無い場合はNULLを返します。

PointN(geometry,integer)

ジオメトリの最初のラインストリングにおける、N番目のポイントを返します。ジオメトリにラインストリングが無い場合はNULLを返します。

ExteriorRing(geometry)

ポリゴンの外環を返します。ジオメトリがポリゴンでない場合はNULLを返します。

NumInteriorRings(geometry)

ジオメトリの最初のポリゴンの内環数を返します。ジオメトリにポリゴンが無い場合はNULLを返します。

InteriorRingN(geometry,integer)

ポリゴンのN番目の内環を返します。ジオメトリがポリゴンでないか、N番が範囲外である場合はNULLを返します。

EndPoint(geometry)

ラインストリングの最後のポイントをポイントで返します。

StartPoint(geometry)

ラインストリングの最初のポイントをポイントで返します。

GeometryType(geometry)

ジオメトリタイプを文字列で返します。たとえば'LINESTRING', 'POLYGON', 'MULTIPOINT'等です。

OGC SPEC s2.1.1.1 - このジオメトリインスタンスがメンバーになっているジオメトリのインスタンス化可能な派生タイプの名前を返します。インスタンス化可能な派生タイプの名前は、文字列として返されます。

X(geometry)

ジオメトリの最初のポイントのX値を探索して返します。ジオメトリにポイントが無い場合はNULLを返します。

Y(geometry)

ジオメトリの最初のポイントのY値を探索して返します。ジオメトリにポイントが無い場合はNULLを返します。

Z(geometry)

ジオメトリの最初のポイントのZ値を探索して返します。ジオメトリにポイントが無い場合はNULLを返します。

6.1.5. ジオメトリ コンストラクタ

GeomFromText(text,[<srid>])

ジオメトリをWKTから作成し、SRIDを与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

PointFromText(text,[<srid>])

ジオメトリをWKTから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

WKTがポイントでない場合はエラーを投げます。

LineFromText(text,[<srid>])

ジオメトリをWKTから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

ジオメトリをWKTから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

LinestringFromText(text,[<srid>])

ジオメトリをWKTから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

仕様適合のためです。

ジオメトリをWKTから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

PolyFromText(text,[<srid>])

ジオメトリをWKTから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

WKTがポリゴンでない場合はエラーを投げます。

PolygonFromText(text,[<srid>])

ジオメトリをWKTから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

仕様適合のためです。

WKTがポリゴンでない場合はエラーを投げます。

MPointFromText(text,[<srid>])

ジオメトリをWKTから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

WKTがマルチポイントでない場合はエラーを投げます。

MLineFromText(text,[<srid>])

ジオメトリをWKTから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

WKTがマルチラインストリングでない場合はエラーを投げます。

MPolyFromText(text,[<srid>])

ジオメトリをWKTから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

WKTがマルチポリゴンでない場合はエラーを投げます。

GeomCollFromText(text,[<srid>])

ジオメトリをWKTから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

WKTがジオメトリコレクションでない場合はエラーを投げます。

GeomFromWKB(bytea,[<srid>])

ジオメトリをWKBから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

GeomFromWKB(bytea,[<srid>])

ジオメトリをWKBから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

PointFromWKB(bytea,[<srid>])

ジオメトリをWKBから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

WKBがポイントでない場合はエラーを投げます。

LineFromWKB(bytea,[<srid>])

ジオメトリをWKBから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

WKBがラインストリングでない場合はエラーを投げます。

LinestringFromWKB(bytea,[<srid>])

ジオメトリをWKBから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

仕様適合のためです。

WKBがラインストリングでない場合はエラーを投げます。

PolyFromWKB(bytea,[<srid>])

ジオメトリをWKBから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

WKBがポリゴンでない場合はエラーを投げます。

PolygonFromWKB(bytea,[<srid>])

ジオメトリをWKBから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

仕様適合のためです。

WKBがポリゴンでない場合はエラーを投げます。

MPointFromWKB(bytea,[<srid>])

ジオメトリをWKBから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

WKBがマルチポイントでない場合はエラーを投げます。

MLineFromWKB(bytea,[<srid>])

ジオメトリをWKBから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

WKBがマルチラインストリングでない場合はエラーを投げます。

MPolyFromWKB(bytea,[<srid>])

ジオメトリをWKBから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

WKBがマルチポリゴンでない場合はエラーを投げます。

GeomCollFromWKB(bytea,[<srid>])

ジオメトリをWKBから作成し、SRIDを与えます。SRIDが与えられない場合は-1をデフォルトで与えます。

OGC SPEC 3.2.6.2 - 任意引数SRIDは仕様適合のためです。

WKBがジオメトリコレクションでない場合はエラーを投げます。

6.2. PostGIS独自拡張

6.2.1. 管理関数

DropGeometryTable([<スキーマ名>], <テーブル名>)

テーブルとgeometry_columnsからの参照を削除します。 ご注意: スキーマ対応版PostgreSQLでは、スキーマが与えられない場合はcurrent_schema()を使います。

UpdateGeometrySRID([<schema_name>], <table_name>, <column_name>, <srid>)

ジオメトリカラムにある全てのフィーチャーのSRIDを更新し、SRIDに関するジオメトリ制限とgeometry_columnsのSRIDを更新します。ご注意: スキーマ対応版PostgreSQLでは、スキーマが与えられない場合はcurrent_schema()を使います。

update_geometry_stats([<table_name>, <column_name>])

クエリプランナが使う、空間テーブルの統計情報を更新します。統計情報収集処理を完全にするためにはには"VACUUM ANALYZE [テーブル名] [カラム名]"も実行する必要があります。ご注意: PostgreSQL 8.0からは統計情報の収集は"VACUUM ANALYZE"で自動的に行われます。

postgis_version()

このデータベースにインストールされたPostGIS関数の版番号を返します (非推奨です。替わりにpostgis_full_version()を使います)。

postgis_lib_version()

PostGISライブラリの版を返します。

postgis_lib_build_date()

PostGISライブラリをビルドした日を返します。

postgis_script_build_date()

PostGISスクリプトをビルドした日を返します。

postgis_scripts_installed()

インストールされたlwpostgis.sqlスクリプトの版番号を返します。

postgis_scripts_released()

インストールされたPostGISライブラリからリリースされたlwpostgis.sqlスクリプトの版番号を返します。

postgis_geos_version()

GEOSライブラリの版を返します。GEOS対応が有効でないならNULLを返します。

postgis_proj_version()

PROJ4ライブラリの版を返します。PROJ4対応が有効でないならNULLを返します。

postgis_uses_stats()

STATSの使用が可能になっているならTRUEを返し、そうでないならFALSEを返します。

postgis_full_version()

完全なPostGISの版情報とコンフィギュレーション情報を報告します。

6.2.2. 演算子

A &< B

"&<"演算子は、AのバウンディングボックスがBのバウンディングボックスとオーバラップしているか左側にある場合にTRUEを返します。

A &> B

"&>"演算子は、AのバウンディングボックスがBのバウンディングボックスとオーバラップしているか右側にある場合にTRUEを返します。

A << B

"<<"演算子は、Aのバウンディングボックスが厳密にBのバウンディングボックスの左側にある場合にTRUEを返します。

A >> B

">>"演算子はAのバウンディングボックスが厳密にBンバウンディングボックスの右側にある場合にTRUEを返します。

A &<| B

"&<|"演算子は、AのバウンディングボックスがBのバウンディングボックスとオーバラップしているか下にある場合にTRUEを返します。

A |&> B

"|&>"演算子は、AのバウンディングボックスがBのバウンディングボックスとオーバラップしているか上にある場合にTRUEを返します。

A <<| B

"<<|"演算子は、Aのバウンディングボックスが厳密にBのバウンディングボックスの下にある場合にTRUEを返します。

A |>> B

"|>>"演算子は、Aのバウンディングボックスが厳密にBのバウンディングボックスの上にある場合にTRUEを返します。

A ~= B

"~="演算子は、「同じ形のもの」演算子です。 二つのジオメトリが実際に幾何学的に等価であるかどうかを見ます。AとBが頂点ごとに見て同じフィーチャーの場合にTRUEを返します。

A @ B

"@"演算子は、Aのバウンディングボックスが完全にBのバウンディングボックスに含まれる場合にTRUEを返します。

A ~ B

"~"演算子は、Aのバウンディングボックスが完全にBのバウンディングボックスを含む場合にTRUEを返します。

A && B

"&&"演算子は、オーバラップ演算子です。AのバウンディングボックスがBのバウンディングボックスをオーバラップする場合にTRUEを返します。

6.2.3. 計測関数

area2d(geometry)

ジオメトリがポリゴンかマルチポリゴンならジオメトリの面積を返します。

distance_sphere(point, point)

緯度経度で示された二点の直線距離をメートルで返します。半径6370986メートルの球体とします。distance_spheroid()より早いですが、精度は落ちます。ポイントについてのみ実装しています。

distance_spheroid(point, point, spheroid)

指定した楕円体を使って、緯度経度で示された2点の直線距離をメートルで返します。length_spheroid()にある楕円体の説明をご覧下さい。現在は、ポイントについてのみ実装しています。

length2d(geometry)

ラインストリングまたはマルチラインストリングの場合に、ジオメトリの2次元の長さを返します。

length3d(geometry)

ラインストリングまたはマルチラインストリングの場合に、ジオメトリの3次元の長さを返します。

length_spheroid(geometry,spheroid)

楕円体上の長さを計算します。この関数は、ジオメトリの座標が緯度経度単位であって、投影変換なしに長さを求めたい場合に有用です。楕円体は別々のデータベースタイプで、次のように構成することができます。

SPHEROID[<名称>,<長軸半径>,<扁平率の逆数>]

Eg:

SPHEROID["GRS_1980",6378137,298.257222101]

計算例は次のようになるでしょう。

SELECT
 length_spheroid(
  geometry_column,
  'SPHEROID["GRS_1980",6378137,298.257222101]'
 )
FROM geometry_table;

length3d_spheroid(geometry,spheroid)

ジオメトリの楕円体上の長さを、標高を考慮して計算します。この関数は、鉛直変動によって加えられる距離を計算するために鉛直座標 (楕円体の軸と同じ単位です)を使うことを除くと、ちょうどlength_spheroidに似ています。

distance(geometry, geometry)

二つのジオメトリ間の最短距離を返します。

max_distance(linestring,linestring)

二つのラインストリング間の最長距離を返します。

perimeter(geometry)

POLYGONまたはMULTIPOLYGONジオメトリの場合に、2次元周囲長を返します。

perimeter2d(geometry)

POLYGONまたはMULTIPOLYGONジオメトリの場合に、2次元周囲長を返します。

perimeter3d(geometry)

POLYGONまたはMULTIPOLYGONジオメトリの場合には、3次元周囲長を返します。

6.2.4. ジオメトリ出力

AsBinary(geometry,{'NDR'|'XDR'})

リトルエンディアン(NDR)またはビッグエンディアン(XDR)を使ったOGC "Well-known-binary"表現をbytea型で返します。この関数は、データをデータベース外に文字列表現を使わずに持ち出すバイナリカーソルで有用です。

AsEWKT(geometry)

ジオメトリのEWKT表現をTEXT型で返します。

AsEWKB(geometry, {'NDR'|'XDR'})

リトルエンディアン (NDR)またはビッグエンディアン (XDR)を使ったEWKB表現をbytea型で返します。

AsSVG(geometry, [rel], [precision])

ジオメトリをSVGパスデータで返します。第2引数に1を指定すると、相対移動によるパスデータ実装を返します。デフォルト (または0指定)では、絶対移動を使います。第3引数は、出力の十進数の最大桁数を減らすために使います (デフォルトは15です)。'rel'が0のときはポイントはcx/cyに、'rel'が1のときはx/yに、それぞれ出力します。

AsGML(geometry, [precision])

ジオメトリをGMLエレメントで返します。第2引数は、出力の最大有効桁数を減らすために使います (デフォルトは15です)。

6.2.5. ジオメトリ コンストラクタ

GeomFromEWKT(text)

EWKBからジオメトリを生成します。

GeomFromEWKB(bytea)

EWKBからジオメトリを生成します。

MakePoint(<x>, <y>, [<z>], [<m>])

2次元、3次元、4次元のポイントジオメトリを生成します。

MakePointM(<x>, <y>, <m>)

XYMのポイントジオメトリを生成します。

MakeBox2D(<LL>, <UR>)

与えられたポイントジオメトリから定義されるBOX2Dを生成します。

MakeBox3D(<LLB>, <URT>)

与えられた3次元ポイントジオメトリから定義されるBOX3Dを生成します。

MakeLine(geometry set)

ポイントジオメトリの集合からラインストリングをひとつ生成します。この集計関数に渡す前に、副問い合わせでポイントを並べ替えると良いかも知れません。

MakeLine(geometry, geometry)

与えられた二つのポイントからラインストリングを生成します。

LineFromMultiPoint(multipoint)

マルチポイントジオメトリからラインストリングを生成します。

AddPoint(linestring, point, [<position>])

ポイントを、ラインストリングの<pos>の位置に追加します。第3引数を省略するか-1を設定すると、末尾に追加します。

MakePolygon(linestring, [linestring[]])

与えられた外周、穴の配列で形作られるポリゴンを生成します。ジオメトリ配列はAccumを使って生成します。 入力ジオメトリは閉じたラインストリングである必要があります (IsClosedGeometryTypeを参照して下さい)。

Polygonize(geometry set)

Aggregate. Creates a GeometryCollection containing possible polygons formed from the costituent linework of a set of geometries. Only available when compiled against GEOS >= 2.1.0.

Collect(geometry set)

ジオメトリの集合からジオメトリコレクションまたはマルチ系オブジェクトを返します。collect()関数はPostgreSQLの用語で言うところの「集計関数」です。これは、sum()やmean()関数と同じようにデータの複数行を扱うということを意味します。たとえば、"SELECT COLLECT(GEOM) FROM GEOMTABLE GROUP BY ATTRCOLUMN"は、ATTRCOLUMNの値ごとに分かれたジオメトリコレクションを返します。

Collect(geometry, geometry)

二つの入力ジオメトリをまとめたジオメトリを返します。出力タイプはMULTI系またはGEOMETRYCOLLECTIONです。

Dump(geometry)

これは集合を返す関数 (SRF=set-returning function)です。ジオメトリ (geom)と整数配列 (path)で作られるgeometry_dump行を返します。入力ジオメトリが単純型 (POINT,LINESTRING,POLYGON)の場合は、単一の行で返り、pathには空配列、geomには入力ジオメトリが入ります。入力ジオメトリがジオメトリコレクションまたはMULTI系の場合は、要素ごとの行で返り、pathはコレクション内の要素位置を表します。

ご注意: この関数はPostgreSQL 7.2.xでビルドした場合には有効ではありません

6.2.6. ジオメトリエディタ

AddBBOX(geometry)

ジオメトリにバウンディングボックスを追加します。これにより、バウンディングボックスに基づく検索が早くなりますが、ジオメトリのサイズが大きくなります。

DropBBOX(geometry)

ジオメトリからバウンディングボックスのキャッシュを削除します。この関数は、ジオメトリのサイズを減らしますが、バウンディングボックスを用いたクエリを遅くします。

Force_collection(geometry)

ジオメトリをジオメトリコレクションに変換します。これはWKB表現を単純化するのに便利です。

Force_2d(geometry)

ジオメトリを「2次元モード」に強制させます。全ての出力表現はXY座標値のみを持つことになります。OGC準拠の出力 (OGCは2次元ジオメトリのみ策定しています)に強制するために使われます。

Force_3dz(geometry), Force_3d(geometry)

ジオメトリをXYZモードに強制します。

Force_3dm(geometry)

ジオメトリをXYMモードに強制します。

Force_4d(geometry)

ジオメトリをXYZMモードに強制します。

Multi(geometry)

マルチ系ジオメトリを返します。ジオメトリが既にマルチ系なら変更せずに返します。

Transform(geometry,integer)

新しいジオメトリを整数値で参照されるSRIDに座標変換します。変換先SRIDはSPATIAL_REF_SYSテーブルに存在するものでなければなりません。

Translate(geometry,float8,float8,float8)

引数の数値をオフセットとして、ジオメトリを新しい位置に変換するものです。すなわち translate(geom,X,Y,Z) となります。

Reverse(geometry)

ジオメトリの頂点の並びを逆順にして返します。

ForceRHR(geometry)

コレクションのポリゴンを右回りに従わせます。

Simplify(geometry, tolerance)

引数のジオメトリをDouglas-Peukerアルゴリズムを使って「単純化した」ものを返します。(マルチ)ラインと(マルチ)ポリゴンでないと実際には動作しませんが、安全にあらゆる種類のジオメトリを引数にできます。単純化はオブジェクトごとに実行されるものですから、ジオメトリコレクションをこの関数に送ることもできます。返されるジオメトリが単純性を失う可能性もあることにご注意ください(IsSimpleを参照して下さい)。

SnapToGrid(geometry, originX, originY, sizeX, sizeY), SnapToGrid(geometry, sizeX, sizeY), SnapToGrid(geometry, size)

引数のジオメトリの全てのポイントを、定義された原点とセルサイズを持つグリッド上にスナップします。 同じセルに落ちた、連続するポイントを削除します。引数ジオメトリのジオメトリタイプを定義できないポイントしか残らなかった場合は、NULLを返します。コレクション内で崩壊したジオメトリはそこから削除されます。返されるジオメトリは単純性を失う可能性がありますのでご注意ください (IsSimpleを参照して下さい)。

Segmentize(geometry, maxlength)

与えられた距離を超えるセグメントを持たないように変更されたジオメトリを返します。差し込まれたポイントはZとM値を (必要なら)持ち、値は0に設定されます。距離計算は2次元でのみ行います。

6.2.7. その他の関数

Summary(geometry)

ジオメトリについての要約文を返します。

box2d(geometry)

ジオメトリの最大範囲を表すBOX2Dを返します。

box3d(geometry)

ジオメトリの最大範囲を表すBOX3Dを返します。

extent(geometry set)

extent()関数はPostgreSQL用語で言うところの「集計関数」です。これは、sum()やmean()と同じ方法でデータリストの操作を行うことを意味します。たとえば、"SELECT EXTENT(GEOM) FROM GEOMTABLE"は、テーブル内の全てのフィーチャーの最大範囲を示すBOX3Dを返します。同様に、"SELECT EXTENT(GEOM) FROM GEOMTABLE GROUP BY CATEGORY"は、カテゴリごとの範囲を返します。

zmflag(geometry)

ジオメトリのZM (次元の意味)フラグをsmall intで返します。値は、0=2次元, 1=M-三次元, 2=Z-3次元, 3=4次元です。

HasBBOX(geometry)

このジオメトリのバウンディングボックスがキャッシュされている場合はTRUEを返し、それ以外の場合はFALSEを返します。キャッシュ制御にはaddBBOX()dropBBOX()を使います。

ndims(geometry)

ジオメトリの座標次元をsmall intで返します。値は2, 3, 4のいずれかです。

nrings(geometry)

ジオメトリがポリゴンまたはマルチポリゴンの場合、リング数を返します。

npoints(geometry)

ジオメトリのポイント (頂点)数を返します。

isvalid(geometry)

ジオメトリが妥当な場合にはTRUEを返します。

expand(geometry, float)

入力ジオメトリのバウンディングボックスから、第2引数で指定される量によって、全ての方向に拡大させたバウンディングボックスを返します。 クエリにインデックスフィルタを追加するdistance()クエリにとても便利です。

estimated_extent([schema], table, geocolumn)

与えられた空間テーブルの「見積もられた」範囲を返します。ジオメトリカラムの統計情報から見積もります。指定されていない場合は現在のスキーマが使われます。

PostgreSQL 8.0.0以上では、統計情報はVACUUM ANALYZEで集められ、結果の範囲は実際の約95%です。

PostgreSQL 8.0.0より前では、統計情報はupdate_geometry_stats()で集められ、範囲は確実です。

find_srid(varchar,varchar,varchar)

この関数の書式はfind_srid(a_db_schema, a_table, a_column)です。GEOMETRY_COLUMNSで検索して、指定したカラムのSRID整数値を返します。ジオメトリカラムがAddGeometryColumn()関数で確実に追加していない場合には、確実には動作しません (訳注: GEOMETRY_COLUMNSビューで確実な登録が確認できていれば良いです)。

mem_size(geometry)

ジオメトリが取る容量 (バイト単位)を返します。

numb_sub_objects(geometry)

ジオメトリに格納されているオブジェクトの数を返します。マルチ系ジオメトリとジオメトリコレクションに使えます。

point_inside_circle(geometry,float,float,float)

この関数の書式はpoint_inside_circle(<geometry>,<circle_center_x>,<circle_center_y>,<radius>)です。ジオメトリがポイントで、かつ指定した円内にある場合はTRUEを返し、それ以外はFALSEを返します。

xmin(box3d) ymin(box3d) zmin(box3d)

バウンディングボックスの、それぞれX,Y,Z軸の最小値を返します。

xmax(box3d) ymax(box3d) zmax(box3d)

バウンディングボックスの、それぞれX,Y,Z軸の最大値を返します。

line_interpolate_point(geometry, proportion)

線に沿った内挿点を返します。第1引数はLINESTRINGでなければなりません。 第2引数は、float型で0から1の区間にある数です。ポイントを返します。

Accum(geometry set)

集約関数です。ジオメトリの配列を生成します。

付録A リリースノート

A.1. リリース 1.0.0

リリース日: 2005/04/19

最後の1.0.0リリースです。若干の誤り訂正、ローダのいくつかの改良 (古いPostGISへの対応が特筆すべき点)、文書の追加がありました。

A.1.1. アップグレード

1.0.0RC6から更新する場合には、ダンプ/リロードは不要です

前のリリースからアップグレードするにはダンプ/リロードが必要です。詳細についてはアップグレードをご覧下さい。

A.1.2. ライブラリの変更

transform()が不規則なメモリアドレスを解放する問題を訂正

force_3dm()のメモリ確保が必要より小さい問題を訂正

JOIN選択度見積もりの誤り (デフォルト値、メモリリーク、行カウント、SD)訂正

A.1.3. 他の変更追加

shp2pgsqlがタブまたはシングルクォートで始まる値を読み飛ばす誤りを訂正

マニュアルへのローダ/ダンパの追加

古い (HWGEOM)PostGISに対応するshp2gsql

shp2pgsqlのフラグに -p (prepare)を追加

マニュアルにOGC互換の強制に関する新章追加

JTSライブラリに対応する新しいautoconf

推測器のテストの誤り訂正 (LWGEOMとスキーマの構文解析への対応)

A.2. リリース 1.0.0RC6

リリース日: 2005/03/30

1.0.0の6番目のリリース候補、若干の誤り訂正と整理を行っています。

A.2.1. アップグレード

前のリリースからアップグレードするにはダンプ/リロードが必要です。詳細についてはアップグレードをご覧下さい。

A.2.2. ライブラリの変更

multi()の誤り訂正

noop時にmulti()からの早い復帰

A.2.3. スクリプトの変更

{x,y}{min,max}(box2d)関数の削除

A.2.4. 他の変更

postgis_restore.plスクリプトの誤り訂正

64ビット対応のダンパの誤り訂正

A.3. リリース 1.0.0RC5

リリース日: 2005/03/25

1.0.0の5番目のリリース候補、若干の誤り訂正と改善があります

A.3.1. アップグレード

1.0.0RC4から更新する場合には、ダンプ/リロードは不要です

前のリリースからアップグレードするにはダンプ/リロードが必要です。詳細についてはアップグレードをご覧下さい。

A.3.2. ライブラリの変更

box3d計算の問題 (セグメンテーションフォールト)の訂正 (ほかにもあります)

estimated_extent()でのセグメンテーションフォールトの訂正

A.3.3. 他の変更

ビルドスクリプトとユーティリティの若干の改良

性能向上に関する技法の文章の追加

A.4. リリース 1.0.0RC4

リリース日: 2005/03/18

1.0.0の4番目のリリース候補、誤り訂正と若干の改善があります

A.4.1. アップグレード

前のリリースからアップグレードするにはダンプ/リロードが必要です。詳細についてはアップグレードをご覧下さい。

A.4.2. ライブラリの変更

geom_accum()のセグメンテーションフォールトの誤り訂正

64ビットアーキテクチャ対応の誤り訂正

コレクションを引数に取るbox3d計算関数の誤りの訂正

副問い合わせの選択度推定への対応

force_collectionからの早い復帰

SnapToGrid()の一貫性検査の訂正

Box2d出力精度を15桁に後退

A.4.3. スクリプトの変更

distance_sphere()の追加

get_proj4_from_sridの実装をSQLからPL/pgSQLに変更

A.4.4. 他の変更

ローダとダンパのMULTOLINEシェープの処理の問題を訂正

ローダでポリゴンの最初の穴を読み飛ばす誤りを訂正

jdbc2: コードの整理、Makefileの改善

FLEX変数とYACC変数がpgsqlのMakefile.globalが取り込まれた*後*で、pgsqlの*空白を除いた*ものが空文字列と評価された場合に限って設定される

既に作成されていたパーサの追加

ビルドスクリプトの改良

Version.configの改善を中心とした版処理の改善

postgis_restore.plの改善

A.5. リリース 1.0.0RC3

リリース日: 2005/02/24

1.0.0の3番目のリリース候補、多数の誤り訂正と改善があります。

A.5.1. アップグレード

前のリリースからアップグレードするにはダンプ/リロードが必要です。詳細についてはアップグレードをご覧下さい。

A.5.2. ライブラリの変更

transform()でSRIDが消える問題を訂正、エラー処理を改善。

メモリアラインメントのハンドリングに関する誤り訂正

force_collection()で単純な (単一)ジオメトリ型でMapServerの接続が切れる問題を訂正。

GeometryFromText()でbboxキャッシュを追加しない誤り訂正。

box2d出力の精度低下。

pgsqlで異常終了する問題を避けるため、DEBUGマクロにPGIS_の前置辞を付加

GEOS2POSTGISコンバータのリークを訂正

pallocで確保したクエリコンテキストのメモリを早く開放することによるメモリ使用の削減

A.5.3. スクリプトの変更

PostgreSQL 7.2のインデックスのバインディングを訂正しました。

PG72での動作と、1テーブルに複数カラムの場合への対応のため、probe_geometry_columns()の誤り訂正

boolからtextへのキャストの更新

動作効率改善のため、いくつかの関数をSTABLEからIMMUTABLEに変更

A.5.4. JDBC変更

jdbc2: 小さなパッチ、box2d/box3dの試験、文書とライセンスの改定

jdbc2: pgjdbc 8.0の型の自動登録の誤り訂正とテストケース作成

jdbc2: 古いjdkリリースでの構築を有効にするためためにjdk1.4使用箇所の削除

jdbc2: pg72jdbc2.jarに対するビルドへの対応の追加

jdbc2: Makefileの更新と無駄の除去

jdbc2: JTSジオメトリクラス対応のベータ版を追加

jdbc2: 古いPostGISサーバに対して失敗するのが判明しているテストをスキップするようにしました。

jdbc2: EWKTのM値を持つジオメトリの処理の訂正

A.5.5. 他の変更

性能向上に関する技法の新章追加

ドキュメント更新: pgsql72に必要なもの、lwpostgis.sql

autoconfの若干の変更

BUILDDATE抽出の移植可能範囲を広げました

spatial_ref_sys.sqlを訂正してvacuumが全体のデータベースに及ぶのを避けるようにしました。

spatial_ref_sys: NTF (Paris)を0.xで配布していたものに合うよう変更。

A.6. リリース 1.0.0RC2

リリース日: 2005/01/26

1.0.0の第2リリース候補版。誤り訂正と若干の改善。

A.6.1. アップグレード

前のリリースからアップグレードするにはダンプ/リロードが必要です。詳細についてはアップグレードをご覧下さい。

A.6.2. ライブラリの変更

ポイント配列からのbox3d計算に関する誤り訂正

distance_spheroid定義に関する誤り訂正

bboxキャッシュ更新がtransform()無かったことに関する誤り訂正

新しいJDBCドライバ (jdbc2)

後方互換のためのGEOMETRYCOLLECTION(EMPTY)書式への対応

バイナリ出力の高速化

OGC WKB/WKTコンストラクタの厳格化

A.6.3. スクリプトの変更

lwpostgis.sql内でのSTABLE, IMMUTABLE, STRICTの訂正

OGC WKB/WKTコンストラクタの厳格化

A.6.4. 他の変更

ローダ (i18n、非i18nの両方)の高速化と堅牢化

最初のautoconfスクリプト

A.7. リリース 1.0.0RC1

リリース日: 2005/01/13

最初のPostGISメジャーリリース候補版。格納領域の低減とインデックス使用クエリの高速化のためのPostGIS型の内部格納の再設計。

A.7.1. アップグレード

前のリリースからアップグレードするにはダンプ/リロードが必要です。詳細についてはアップグレードをご覧下さい。

A.7.2. 変更

標準形式入力パースの高速化。

標準形式出力の可逆化。

EWKB Canonical binary IO with PG >73.

Support for up to 4d coordinates, providing lossless shapefile->postgis->shapefile conversion.

新関数: UpdateGeometrySRID(), AsGML(), SnapToGrid(), ForceRHR(), estimated_extent(), accum().

垂直方向位置インデックス演算子。

JOIN選択関数。

ジオメトリコンストラクタとエディタの強化。

PostGISエクステンションAPI。

ローダのUTF-8対応。