PostGIS 1.5.1 マニュアル 日本語訳

概要

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

これは,1.5.1版のマニュアルです.

[注意]

この翻訳文書は,PostGIS 1.5.1 Releaseに添付されていたマニュアルをもとに作成しました.

日本語または日本国内固有の問題がありますので,付録B 日本語訳に関する追加情報を追加しました.あわせてご覧ください.


目次

1. 導入
1.1. プロジェクト運営委員会
1.2. 過去と現在の貢献者
1.3. 追加情報
2. インストール
2.1. 簡略版
2.2. 必要なもの
2.3. ソースの取得
2.4. インストール
2.4.1. コンフィギュレーション
2.4.2. ビルド
2.4.3. テスト
2.4.4. インストール
2.5. 空間データベースの作成
2.6. 空間データベースをテンプレートから生成する
2.7. アップグレード
2.7.1. ソフトアップグレード
2.7.2. ハードアップグレード
2.8. 共通の問題
2.9. JDBC
2.10. ローダ/ダンパ
3. よくある質問
4. PostGISを使う: データ管理とクエリ
4.1. GISオブジェクト
4.1.1. OpenGIS WKB とWKT
4.1.2. PostGIS EWKB,EWKT と 標準形式
4.1.3. SQL-MM Part 3
4.2. ジオグラフィ型
4.2.1. ジオグラフィ基礎
4.2.2. ジオグラフィ型をジオメトリ型にして使用すべき時
4.2.3. ジオグラフィの高度なよくある質問
4.3. OpenGIS標準を使う
4.3.1. SPATIAL_REF_SYSテーブルと空間参照系
4.3.2. GEOMETRY_COLUMNSテーブル
4.3.3. 空間テーブルを作る
4.3.4. 手動でジオメトリカラムをgeometry_columnsに登録する
4.3.5. ジオメトリのOpenGIS準拠を確実にする
4.3.6. Dimensionally Extended 9 Intersection Model (DE-9IM)
4.4. GISデータをロードする
4.4.1. SQLを使う
4.4.2. ローダを使う
4.5. GISデータを検索する
4.5.1. SQLを使う
4.5.2. ダンパを使う
4.6. インデクスを構築する
4.6.1. GiSTインデクス
4.6.2. インデクスを使う
4.7. 複雑なクエリ
4.7.1. インデクスの利点を使う
4.7.2. 空間SQLの例
5. PostGISを使う: アプリケーションを構築する
5.1. MapServerを使う
5.1.1. 基本的な使い方
5.1.2. よくある質問
5.1.3. 踏み込んだ使用法
5.1.4. 例
5.2. Javaクライアント(JDBC)
5.3. Cクライアント(libpq)
5.3.1. テキストカーソル
5.3.2. バイナリカーソル
6. 性能向上に関する技法
6.1. 大きなジオメトリを持つ小さなテーブル
6.1.1. 問題の説明
6.1.2. 応急処置
6.2. ジオメトリインデクスでCLUSTERを実行する
6.3. 次元変換の回避
6.4. コンフィギュレーションのチューン
6.4.1. スタートアップ
6.4.2. 実行時
7. PostGISリファレンス
7.1. PostgreSQLのPostGIS型
7.2. 管理関数
7.3. ジオメトリコンストラクタ
7.4. ジオメトリアクセサ
7.5. ジオメトリエディタ
7.6. ジオメトリ出力
7.7. 演算子
7.8. 空間関係関数と空間計測関数
7.9. ジオメトリ処理関数
7.10. 線参照
7.11. ロングトランザクションサポート
7.12. その他の関数
7.13. 例外的関数
8. PostGIS空間関数索引
8.1. PostGIS集計関数
8.2. PostGIS SQL-MM対応関数
8.3. PostGISジオグラフィサポート関数
8.4. PostGISジオメトリダンプ関数
8.5. PostGISボックス関数
8.6. 三次元をサポートするPostGIS関数
8.7. PostGIS曲線ジオメトリサポート関数
8.8. PostGIS関数サポートマトリクス
8.9. 新しいPostGIS関数
8.9.1. PostGIS 1.5で新しくできた関数,ふるまいが変わった関数,機能強化された関数
8.9.2. PostGIS 1.4で新しくできた関数,ふるまいが変わった関数,機能強化された関数
8.9.3. PostGIS 1.3で新しくできた関数
9. 問題を報告する
9.1. ソフトウェアのバグを報告する
9.2. 文書の問題を報告する
A. Appendix
A.1. Release 1.5.1
A.2. Release 1.5.0
A.3. Release 1.4.0
A.4. Release 1.3.6
A.5. Release 1.3.5
A.6. Release 1.3.4
A.7. Release 1.3.3
A.8. Release 1.3.2
A.9. Release 1.3.1
A.10. Release 1.3.0
A.11. Release 1.2.1
A.12. Release 1.2.0
A.13. Release 1.1.6
A.14. Release 1.1.5
A.15. Release 1.1.4
A.16. Release 1.1.3
A.17. Release 1.1.2
A.18. Release 1.1.1
A.19. Release 1.1.0
A.20. Release 1.0.6
A.21. Release 1.0.5
A.22. Release 1.0.4
A.23. Release 1.0.3
A.24. Release 1.0.2
A.25. Release 1.0.1
A.26. Release 1.0.0
A.27. Release 1.0.0RC6
A.28. Release 1.0.0RC5
A.29. Release 1.0.0RC4
A.30. Release 1.0.0RC3
A.31. Release 1.0.0RC2
A.32. Release 1.0.0RC1
B. 日本語訳に関する追加情報
B.1. 「インタセクト」と「クロス」
B.2. 空間参照系等について
B.2.1. わが国でよく使われる空間参照系
B.2.2. 測地系
B.2.3. UTM
B.2.4. 平面直角座標系
B.3. 日本測地系から投影変換する場合の問題点
B.3.1. Proj.4で問題点を見る
B.3.2. PostGISでの問題回避
B.4. Shift JIS系文字コードについて

第1章 導入

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

1.1. プロジェクト運営委員会

PostGISプロジェクト運営委員会(PostGIS Project Steering Committee, PSC)は, 総合的な指示,リリースサイクル,ドキュメンテーション,支援活動に関する調整を行っています. また,委員会は, 全体的なユーザサポート,PostGISコミュニティからのパッチの受け付けと適用, 開発者のコミットのアクセス,新しい委員,APIの重要な変更といった,PostGISを含む雑多な問題に関する投票を行っています.

Mark Cave-Ayland

バグフィクスとメンテナンス活動,PostgreSQLのリリースとの調整,空間インデクスの選択とバインディング,ウィンドウズ用のビルド,新しいGEOS機能の統合,新しい機能の強化に関する調整.

Paul Ramsey

PostGISプロジェクトの副創始者.総合的なバグフィクス,地理サポート,GEOS機能の統合とGEOSリリースとの調整.

Kevin Neufeld

文書作成,Hudson automatedのビルド,PostGISニュースグループでの高度なユーザサポート,PostGISメンテナンス機能の強化.

Regina Obe

文書作成,PostGISニュースグループでの総合的なユーザサポート,Windows用のビルドと試験版のビルド,新機能や大きなコード変更のスモークテスト.

1.2. 過去と現在の貢献者

Sandro Santilli

バグフィクスと新しいGEOS機能のメンテナンスと統合.WKTラスタのサポート.

Dave Blasby

PostGISのオリジナルの開発/副創始者.サーバサイドのオブジェクト,インデクスのバインディングや多数のサーバサイドの解析機能を記述.

Jeff Lounsbury

シェープファイルのローダ/ダンパのオリジナルの開発者.現在のPostGISプロジェクトオーナーの代表.

Mark Leslie

中核機能の,継続的なメンテナンスと開発.

Olivier Courtin

XML (KML,GML)/GeoJSON の入出力機能とバグフィクス.

Pierre Racine

WKTラスタの全体的なアーキテクチャとプログラミングサポート.

Mateusz Loskot

WKTラスタのサポート.

Chris Hodgson

総合的な開発.

Nicklas Aven

距離関数の強化と追加,Windowsのテスト,総合的なユーザサポート.

Jorge Arevalo

WKTラスタ開発.

Stephen Frost

Tigerジオコーダの開発.

Other contributors

Alex Bodnaru, Alex Mayrhofer, Barbara Phillipot, Ben Jubb, Bernhard Reiter, Bruce Rindahl, Bruno Wolff III, Carl Anderson, Charlie Savage, Dane Springmeyer, David Skea, David Techer, Eduin Carrillo, IIDA Tetsushi, George Silva, Geographic Data BC, Gerald Fenoy, Gino Lucrezi, Guillaume Lelarge, Klaus Foerster, Kris Jurka, Mark Sondheim, Markus Schaber, Michael Fuhr, Nikita Shulga, Norman Vine, Ralph Mason, Steffen Macke, Vincent Picavet (アルファベット順)

重要なサポートライブラリ

ジオメトリ演算ライブラリ GEOS . Martin Davisがアルゴリズムを作成し,Mateusz Loskot,Paul Ramseらで動作するようにし,メンテナンスとサポートの進行を行っています.

地図投影ライブラリ Proj4 . Gerald EvendenとFrank Warmerdamによって作成とメンテナンスがされています.

1.3. 追加情報

第2章 インストール

本章では,PostGISのインストールに必要な手順について説明します.

2.1. 簡略版

tar xvfz postgis-1.5.1.tar.gz
cd postgis-1.5.1
./configure
make
make install
createdb yourdatabase
createlang plpgsql yourdatabase
psql -d yourdatabase -f postgis.sql
psql -d yourdatabase -f postgis_comments.sql
psql -d yourdatabase -f spatial_ref_sys.sql

本章の残りで,上記のステップそれぞれの説明をします.

2.2. 必要なもの

PostGISには,ビルド,利用するために,次のものが必要です.

必須

  • PostgreSQL 8.3以上.PostgreSQLの完全なインストール(サーバヘッダを含む)が必要です. PostgreSQLは http://www.postgresql.org にあります.

    完全なPostgreSQL/PostGISサポートマトリクスとPostGIS/GEOSのサポートマトリクスは http://trac.osgeo.org/postgis/wiki/UsersWikiPostgreSQLPostGIS にあります.

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

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

  • 投影変換ライブラリ Proj4 の 4.6.0版以上.Proj4ライブラリは,PostGISの座標系投影変換サポートに使われます.Proj4は,http://trac.osgeo.org/proj/ からダウンロードできます.

  • ジオメトリライブラリ GEOS の 3.1.1版以上.GEOS 3.2 を推奨します. GEOS 3.2 以外では,トポロジ例外の処理が強化され, ST_Bufferで接続部の面取り接合や鋭角接合が可能となり,またバッファの速度が向上しています. GEOSライブラリは,PostGISでの ジオメトリテスト (ST_Touches(), ST_Contains(), ST_Intersects()) や ジオメトリ演算 (ST_Buffer(), ST_Union(), ST_Intersection(), ST_Difference()) を行うのに使われます. GEOSは,http://trac.osgeo.org/geos/ からダウンロードできます.

オプション

  • javaディレクトリ下のドライバのビルドを行うには Apache ANT (ant) が必要です. Antは http://ant.apache.org にあります.

  • 文書のビルドには DocBook (xsltproc) が必要です. Docbook は http://www.docbook.org/ にあります.

  • 文書をPDFでビルドするには DBLatex (dblatex) が必要です. DBLatex は http://dblatex.sourceforge.net/ にあります.

  • 文書で使う画像を生成するには ImageMagick (convert) が必要です. ImageMagix は http://www.imagemagick.org/ にあります.

2.3. ソースの取得

ダウンロードサイト http://postgis.refractions.net/download/postgis-1.5.1.tar.gz から,ソースのアーカイブを入手します.

wget http://postgis.refractions.net/download/postgis-1.5.1.tar.gz
tar -xvzf postgis-1.5.1.tar.gz

これで,カレントディレクトリの下に postgis-1.5.1 ができます.

もしくは svn レポジトリ http://svn.osgeo.org/postgis/trunk/ からチェックアウトします.

svn checkout http://svn.osgeo.org/postgis/trunk/ postgis-1.5.1

新しく作られた postgis-1.5.1 ディレクトトリに移動して,インストールを続けます.

2.4. インストール

[注意]

多くのOSでは,ビルドされたPostgreSQL/PostGISパッケージがあります. 多くの場合,コンパイルが必要なのは,最もひどい最先端の版が欲しい場合やパッケージメンテナンス人ぐらいです.

PostGISモジュールは,PostgreSQLバックエンドサーバの拡張です. PostGIS 1.5.1 では,コンパイルのために,完全なPostgreSQLサーバヘッダが必要です. PostgreSQL 8.3以上でビルドできます.古い版のPostgreSQLはサポートされません

PostgreSQLのインストールを済ませていない場合は,PostgreSQLインストールガイドをご覧ください. http://www.postgresql.org (訳注: 日本語版は http://www.postgresql.jp/) にあります.

[注意]

GEOS機能のために,PostgreSQLをインストールする際に,PostgreSQLに標準C++ライブラリへの明示的なリンクが必要になるかもしれません.

LDFLAGS=-lstdc++ ./configure [YOUR OPTIONS HERE]

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

次のステップでは,PostGISソースのコンフィギュレーションとコンパイルに概要を記述します. これらは,Linuxユーザ用に書いてありますので,WindowsやMacでは動作しません.

2.4.1. コンフィギュレーション

ほとんどのLinuxのインストールと同様に,最初のステップでは,ソースコードのビルドに使われる Makefile を生成します.これは,シェルスクリプトで行います.

./configure

パラメータを付けない場合は,このコマンドは自動で,PostGISのソースコードのビルドを行うのに必要なコンポーネントやライブラリを,システム上で探します. ./configure とするのが一般的な使い方ですが,標準的でない位置に必要なライブラリやプログラムを置いてある場合のために,いくつかのパラメータを受け付けます.

次のリストで,共通して使われるパラメータを示します. 完全なリストについては, --help または --help=short パラメータを使って下さい.

--prefix=PREFIX

PostGISライブラリとSQLスクリプトのインストール先を指定します. デフォルトでは,検出されたPostgreSQLのインストール先と同じになります.

[注意]

このパラメータは現在のところ壊れていて,PostgreSQLのインストール先にしかインストールされません.このバグのトラックについては http://trac.osgeo.org/postgis/ticket/160 をご覧ください.

--with-pgconfig=FILE

PostgreSQLは,PostGISなどの拡張に対してPostgreSQLのインストール先ディレクトリを伝える pg_config というユーティリティを持っています. PostGISの対象とするPostgreSQLインストール先を手動で指定する場合は,このパラメータ (--with-pgconfig=/path/to/pg_config) を使います.

--with-geosconfig=FILE

必須のジオメトリライブラリであるGEOSは,ソフトウェアのインストール時にGEOSのインストール先ディレクトリを伝える geos-config というユーティリティを持っています. PostGISのビルドに使う特定のGEOSを手動で指定する場合は,このパラメータ (--with-geosconfig=/path/to/geos-config) を使います.

--with-projdir=DIR

Proj4はPostGISに必須の投影変換ライブラリです.ostGISのビルドに使う特定のProj4のディレクトリを手動で指定する場合は,このパラメータ (--with-projdir=/path/to/projdir) を使います.

--with-gui

データインポートGUI(GTK+2.0が必要)をコンパイルします. このパラメータによって,shp2pgsql-gui という,shp2pgsqlのグラフィカルユーザインタフェースが作成されます.

[注意]

PostGISを SVN レポジトリを得た場合は,本当は最初に次のスクリプトを実行します.

./autogen.sh

このスクリプトは,PostGISのインストールのカスタマイズを行うための configure スクリプトを生成するものです.

PostGISをtarballから得た場合は, configure が既に生成されているので ./autogen.sh を実行する必要はありません.

2.4.2. ビルド

Makefileが生成されたら,PostGISのビルドは,次のコマンドを実行するだけです.

make

出力の最後の行が "PostGIS was built successfully. Ready to install." と出れば終わりです.

PostGIS 1.4.0版からは,全ての関数に文書から生成されるコメントが付きます. これらのコメントを後ほどインストールするには,次のコマンドを実行しますが,docbookが必要です. postgis_comments.sql が docフォルダに tar.gz でパッケージ化されます. tarballからインストールする場合は,postgis_comments.sql が docフォルダに入っているので,コメントを生成する必要はありません.

make comments

2.4.3. テスト

PostGISのテストを行うには,次のコマンドを実行します.

make check

このコマンドは,実際のPostgreSQLデータベースに対して生成したライブラリを使用した,様々なチェックとレグレッションテストを行います.

[注意]

PostgreSQL, GEOS または Proj4 を標準の位置にインストールしていない場合には, 環境変数 LD_LIBRARY_PATH に,ライブラリの位置を追加する必要があるかも知れません.

[注意]

現在のところ make check は,チェックを行う際に 環境変数 PATHPGPORT によっています. コンフィギュレーションパラメータ --with-pgconfig を使って特定した PostgreSQL ではありません. PATHを編集して,コンフィギュレーションの際に検出したPostgreSQLと一致するようにして下さい. もしくは,間もなく襲ってくる頭痛の準備をしておいて下さい. このバグのトラックについては http://trac.osgeo.org/postgis/ticket/186 をご覧ください.

成功したら,テストの出力は次のようなかんじになります.

     CUnit - A Unit testing framework for C - Version 2.1-0
	 http://cunit.sourceforge.net/


Suite: PostGIS Computational Geometry Suite
  Test: test_lw_segment_side() ... passed
  Test: test_lw_segment_intersects() ... passed
  Test: test_lwline_crossing_short_lines() ... passed
  Test: test_lwline_crossing_long_lines() ... passed
  Test: test_lwpoint_set_ordinate() ... passed
  Test: test_lwpoint_get_ordinate() ... passed
  Test: test_lwpoint_interpolate() ... passed
  Test: test_lwline_clip() ... passed
  Test: test_lwline_clip_big() ... passed
  Test: test_lwmline_clip() ... passed
  Test: test_geohash_point() ... passed
  Test: test_geohash_precision() ... passed
  Test: test_geohash() ... passed
Suite: PostGIS Measures Suite
  Test: test_mindistance2d_recursive_tolerance() ... passed

--Run Summary: Type      Total     Ran  Passed  Failed
			   suites        2       2     n/a       0
			   tests        14      14      14       0
			   asserts      84      84      84       0


Creating spatial db postgis_reg
TMPDIR is /tmp/pgis_reg_15328

 PostgreSQL 8.3.7 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44)
 Postgis 1.4.0SVN - 2009-05-25 20:21:55
   GEOS: 3.1.0-CAPI-1.5.0
   PROJ: Rel. 4.6.1, 21 August 2008

Running tests

 loader/Point.............. ok
 loader/PointM.............. ok
 loader/PointZ.............. ok
 loader/MultiPoint.............. ok
 loader/MultiPointM.............. ok
 loader/MultiPointZ.............. ok
 loader/Arc.............. ok
 loader/ArcM.............. ok
 loader/ArcZ.......... ok
 loader/Polygon.............. ok
 loader/PolygonM.............. ok
 loader/PolygonZ.............. ok
 regress. ok
 regress_index. ok
 regress_index_nulls. ok
 lwgeom_regress. ok
 regress_lrs. ok
 removepoint. ok
 setpoint. ok
 simplify. ok
 snaptogrid. ok
 affine. ok
 wkt. ok
 measures. ok
 long_xact. ok
 ctors. ok
 sql-mm-serialize. ok
 sql-mm-circularstring. ok
 sql-mm-compoundcurve. ok
 sql-mm-curvepoly. ok
 sql-mm-general. ok
 sql-mm-multicurve. ok
 sql-mm-multisurface. ok
 geojson. ok
 gml. ok
 svg. ok
 kml. ok
 regress_ogc. ok
 regress_bdpoly. ok
 regress_proj. ok
 regress_ogc_cover. ok
 regress_ogc_prep. ok

Run tests: 42
Failed: 0

2.4.4. インストール

PostGISをインストールするには,次のコマンドを実行します.

make install

これにより,PostGISのインストールファイルが,--prefix パラメータで指定した,適切なサブディレクトリに複写されます.次に特筆すべきサブディレクトリを示します.

  • ローダとダンパのバイナリのインストール先は [prefix]/bin

  • postgis.sql などの SQLファイルのインストール先は [prefix]/share/contrib

  • PostGISライブラリのインストール先は [prefix]/lib

先に make comments を実行していた場合は,次のコマンドを実行すると,SQLファイルのインストール先に postgis_comments.sql がインストールされます.

make comments-install

[注意]

postgis_comments.sql は,xsltproc の外部依存ができたので,通常のビルド,インストールから切り離されました.

2.5. 空間データベースの作成

PostGISデータベースを作るた最初のステップは,単純なPostgreSQLデータベースの作成です.

createdb [yourdatabase]

多くのPostGIS関数は,PL/pgSQL手続き言語で書かれています. 次のステップは,PL/pgSQL言語を新たに作成したデータベースで有効にすることです. 次のコマンドを実行します.

createlang plpgsql [yourdatabase]

次に,PostGISオブジェクトと関数定義をデータベースにロードします. 定義ファイル postgis.sql ( [prefix]/share/contrib にあります ) をロードします.

psql -d [yourdatabase] -f postgis.sql

完全なEPSG座標系定義IDセットについては,spatial_ref_sys.sql 定義ファイルをロードして spatial_ref_sys を生成して下さい. これによりジオメトリ関数 ST_Transform() が実行できるようになります.

psql -d [yourdatabase] -f spatial_ref_sys.sql

PostGISが持つ関数についての助けとなるコメントが必要なら, postgis_comments.sql を,データベースにロードします.コメントは,psqlターミナルウィンドウで単に \dd [function_name] とすれば見ることができます.ロードは次のようにします.

psql -d [yourdatabase] -f postgis_comments.sql

2.6. 空間データベースをテンプレートから生成する

PostGISのディストリビューション (特にPostGIS >= 1.1.5 の Win32インストーラ) の中には, template_postgis というテンプレートにPostGIS関数をロードしているこt5おがあります. PostgreSQLに template_postgis データベースが存在るなら,空間データベースの生成がコマンドひとつで済みます. この二種類のやり方のどちらを使うににしても,データベースユーザは,新しいデータベースを作成する権限を与えられる必要があります.

シェルからの実行:

# createdb -T template_postgis my_spatial_db

SQLからの実行:

postgres=# CREATE DATABASE my_spatial_db TEMPLATE=template_postgis

2.7. アップグレード

既にある空間データベースのアップグレードは,新しいPostGISオブジェクト定義の置き換えや導入を必要とするとき,慎重を要することがあります.

不幸なことに,定義の全てが実行中のデータベース内で簡単には置き換えられるわけではないので,ダンプ/リロードが最善策となることがあります.

PostGISには,マイナーバージョンアップやバグフィクスリリースの場合に使うソフトアップグレードと,メジャーアップグレードで使うハードアップグレードが用意されています.

PostGISをアップグレードしようとする前にデータのバックアップを取ることは,常に価値のあるものです. pg_dumpで -Fc フラグを使うと,ハードアップグレードによってダンプをリストアすることができます.

2.7.1. ソフトアップグレード

コンパイル後に postgis_upgrade*.sql を探して下さい. PostGISの版にあったものをインストールします. たとえば,PostGIS 1.3 から 1.5 に上げるには postgis_upgrade_13_to_15.sql を使います.

$ psql -f postgis_upgrade_13_to_15.sql -d your_spatial_database

ソフトアップグレードができなかった場合に,スクリプトは強制終了されて,ハードアップグレードが必要であると警告されますので,先にソフトアップグレードを実行することをためらってはなりません.

[注意]

postgis_upgrade*.sql ファイルが見つからない場合は,1.1版より前の版のものを使っているかも知れません.この場合,次のコマンドで手動で生成する必要があります.

$ utils/postgis_proc_upgrade.pl postgis.sql > postgis_upgrade.sql

2.7.2. ハードアップグレード

ハードアップグレードは,PostGISデータベースの完全なダンプ/リロードを意味します. PostGISオブジェクトの内部ストレージが変更されていたり, ソフトアップグレードができない場合には,ハードアップグレードが必要です. 付録の Release Notes に,それぞれの版でアップグレードする際にダンプ/リロード(ハードアップグレード)が必要かの報告があります.

PostGISは,pg_dump -Fc コマンドで生成されたダンプのリストアを行うユーティリティスクリプトを提供しています. 実験版ですが,このスクリプトの出力をファイルにリダイレクトすると,問題のある場合に助けになります. 手続きは次の通りです.

アップグレードしたいデータベース("olddb"と呼ぶことにしましょう)のダンプを「カスタム書式」で作成します.

$ pg_dump -Fc olddb > olddb.dump

PostGISのアップグレードを行うダンプを,新しいデータベースにリストアします. 新しいデータベースは存在している必要はありません. postgis_restore は,ダンプファイル名の後にcreatedbパラメータを指定すると,これを受けつけます. たとえば,データベースでデフォルトでない文字コードを使っているとしても,このスクリプトを使うことができます. 新しいデータベースは newdb と呼ぶことにして,このデータベースの文字コードをUNICODEにするなら,次のようになります.

$ sh utils/postgis_restore.pl postgis.sql newdb olddb.dump -E=UNICODE > restore.log

全てのリストアしたダンプオブジェクトが本当にリストアされ, postgis.sqlで定義されたオブジェクトと矛盾しないことをチェックします.

$ grep ^KEEPING restore.log | less

PostgreSQL < 8.0 から >= 8.0 にアップグレードした際は, geometry_columns テーブルにあって,もはや必要でない attrelid, varattnum, stats の各カラムを削除したくなるかも知れません. 保持していても困りません. *本当に必要な時に削除すると困ります*!

$ 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 テーブルは,独自の追加が保持されることを保障するために,ダンプからリストアされます. しかし,ディストリビュートされた spatial_ref_sys テーブルは,変更を含んでいますので, エントリをバックアップし,テーブルを削除して,新しい spatial_ref_sys テーブルを入れるべきです. 独自の追加を作っているのでしたら, テーブルをアップグレードする前にバックアップを取る方法を知っていると仮定します. 新しいものとの入れ替えは,このように実行します.

$ psql newdb
newdb=> truncate spatial_ref_sys;
TRUNCATE
newdb=> \i spatial_ref_sys.sql

2.8. 共通の問題

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

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

    SELECT version();

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

また,コンフィギュアが正しくPostgreSQL,Proj4ライブラリ,GEOSライブラリの位置を検出したかチェックして下さい.

  1. コンフィギュアからの出力で postgis_config.h ファイルが作られます. POSTGIS_PGSQL_VERSIONPOSTGIS_PROJ_VERSIONPOSTGIS_GEOS_VERSION 変数が正しくセットされたかをチェックして下さい.

2.9. JDBC

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

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

  2. ant コマンドを実行します. postgis.jar ファイルを,Javaライブラリを保存しているところに複写します.

JDBC拡張は,ビルド実行中は現在の CLASSPATH に,PostgreSQL JDBCドライバがあるようにしておく必要があります. PostgreSQL JDBCドライバが CLASSPATH に無い場合には,個別にJDBCドライバのJARのありかを伝えます.次のようにします.

# ant -Dclasspath=/path/to/postgresql-jdbc.jar

PostgreSQL JDBCドライバは http://jdbc.postgresql.org からダウンロードできます.

2.10. ローダ/ダンパ

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

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

ローダは shp2pgsql と呼ばれ, ESRIシェープファイルを PostGIS/PostgreSQL にロードするのに適したSQLに変換します.ダンパは pgsql2shp と呼ばれ,PostGISのテーブル(またはクエリ)からESRIシェープファイルに変換します.より詳しいドキュメントをご覧になるには,オンラインヘルプとマニュアルページをご覧ください.

第3章 よくある質問

3.1. 格納できるジオメトリオブジェクトにはどのような種類がありますか?
3.2. たいへん混乱しました.ジオメトリとジオグラフィのどちらを使うべきでしょうか?
3.3. もっとジオグラフィについて聞きたいです. たとえば, 領域がどの大きさまで,ジオグラフィカラムにデータを詰め込めて,合理的な答えが得られるのでしょうか,とか. 極,全データが半球上になければならない(SQL Serber 2008はそう),速度等の制限はあるのでしょうか,とか.
3.4. GISオブジェクトをデータベースに挿入するにはどうしますか?
3.5. 空間クエリを作成するにはどうするのですか?
3.6. 大きなテーブルでの空間クエリの速度向上はどうするのですか?
3.7. なぜPostgreSQLのR-Treeインデクスをサポートしないのですか?
3.8. なぜ AddGeometryColumn() 関数と他のOpsnGIS関数を使うべきなのですか?
3.9. 半径内にあるオブジェクトを全て検索する最善の方法は何ですか?
3.10. クエリの一部として投影変換を実現するにはどうしますか?
3.11. ST_AsEWKT と ST_AsText を,かなり大きいジオメトリで実行すると,空のフィールドが返りました.どうしたら良いですか?
3.12. ST_Intersectsを使うと,二つのジオメトリがインタセクトしているのに,インタセクトしていないと言います.どうしたら良いですか?

3.1.

格納できるジオメトリオブジェクトにはどのような種類がありますか?

ポイント,ライン,ポリゴン,マルチポイント,マルチライン,マルチポリゴン,ジオメトリコレクションが格納できます.これらは Open GIS Well Known Text Format で規定されています(XYZ,XYM,XYZM拡張付き) .現在はサポートされているデータ型は2種類あります. 測量に使われる平面座標系を使用する標準OGCジオメトリデータ型と,極座標系を使用するジオグラフィデータ型です. ジオグラフィデータ型は WGS 84 極座標系 (SRID:4326) のみサポートします.

3.2.

たいへん混乱しました.ジオメトリとジオグラフィのどちらを使うべきでしょうか?

短い答: ジオグラフィは長距離の測定をサポートする新しいデータ型です. ジオグラフィを使う場合は,平面座標系についてあまり多く学習する必要がありません. 行うことが距離や長さの計測に限定され,かつ世界中からのデータを持っている場合は,一般的にジオグラフィが最善です. ジオメトリは古いデータ型で,サポートする関数が多く,サードパーティからの多大なサポートがえられます. 空間参照系に慣れているか,空間参照系 (SRID)が単一で済むような局所的なデータを扱っているか,あるいは,空間処理を多く行う必要がある場合には,ジオメトリが最善です. 現在サポートされているもの,サポートされていないものについては 「 PostGIS関数サポートマトリクス 」 を参照して下さい.

長い答: 「 ジオグラフィ型をジオメトリ型にして使用すべき時 」関数型マトリクス を参照して下さい.

3.3.

もっとジオグラフィについて聞きたいです. たとえば, 領域がどの大きさまで,ジオグラフィカラムにデータを詰め込めて,合理的な答えが得られるのでしょうか,とか. 極,全データが半球上になければならない(SQL Serber 2008はそう),速度等の制限はあるのでしょうか,とか.

その質問は相当深く複雑で,このセクションで十分に答えられません.「 ジオグラフィの高度なよくある質問 」 を参照して下さい.

3.4.

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

まず,GISデータを保持するために "geometry" または "geogprahy" カラムを持つテーブルを作成します.ジオグラフィデータ型の格納は,ジオメトリデータ型とは若干異なります.ジオグラフィの格納については 「 ジオグラフィ基礎 」 を参照して下さい.

ジオメトリ: 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', 
  ST_GeomFromText('LINESTRING(2 3,4 5,6 5,7 8)', -1)
);

他のGISオブジェクトの詳細については object reference をご覧ください.

テーブル内にあるGISデータを表示するには,次のようにします.

SELECT id, name, ST_AsText(geom) AS geom FROM gtest;

返り値は次のようなかんじになります.

 id | name           | geom
----+----------------+-----------------------------
  1 | First Geometry | LINESTRING(2 3,4 5,6 5,7 8) 
(1 row)

3.5.

空間クエリを作成するにはどうするのですか?

他のデータベースクエリを作るのと同じで,返り値,関数,テストのSQLの組み合わせです.

空間クエリでは,クエリを作成する際に心を平静に保つための重要な二つの問題があります. ひとつは,使用することができる空間インデクスがあるか.もうひとつは,多数のジオメトリを相手に計算量の多い計算を行っているか.

一般的に,フィーチャーのバウンディングボックスがインタセクト(交差)しているかをテストするインタセクト演算子(&&)を使いたくなります.&&演算子が便利な理由は,速度向上のために空間インデクスが付けられているなら,&&演算子は空間インデクスを使うからです.これによって,クエリの速度はとてもとても速くなります.

また,検索結果をより狭めるために,Distance(), ST_Intersects(), ST_Contains(), ST_Within() などといった空間関数を使うことでしょう.ほとんどの空間クエリは,インデクスのテストと空間関数のテストを含みます.インデクスのテストで,返ってくるタプルを,求める条件に合致するかもしれないタプルのみとして,タプルの数を制限します.それから,空間関数で確実な条件のテストを行います.

SELECT id, the_geom 
FROM thetable 
WHERE 
  ST_Contains(the_geom,'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');

3.6.

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

大きなテーブルの速いクエリは,空間インデクスのレゾンデートルです(トランザクションサポートもそうですが).

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

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

"USING GIST" オプションによって,サーバにGiST(Generalized Search Tree)インデクスを作るよう指示が渡ります.

[注意]

GiSTインデクスは,不可逆であると仮定します.不可逆インデクスの構築には,代理オブジェクト(空間インデクスの場合はバウンディングボックス)を使います.

PostgreSQLのクエリプランナがインデクスを作るべきかについて合理的な決定を行うよう,十分な情報を確実に持てるようにすべきです.そのために,ジオメトリテーブル上で "gather statistics" を実行しなければなりません.

PostgreSQL 8.0.x 以上では VACUUM ANALYZE コマンドを実行するだけです.

3.7.

なぜPostgreSQLのR-Treeインデクスをサポートしないのですか?

PostGISの,かつての版では,PostgreSQLのR-Treeインデクスを使っていましたが,0.6版でPostgreSQLのR-Treeは完全に捨てて,R-Tree-over-GiSTスキームによる空間インデクスを提供しています.

私たちの試験では,R-TreeとGiSTの検索速度は同程度であることが示されています.PostgreSQLのR-Treeには,GISフィーチャーで使うためには好ましくない二つの制限があります(これらの制限は現在のPostgreSQLネイティブのR-Tree実装についてであって,R-Tree一般の話ではありません).

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

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

3.8.

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

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

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

3.9.

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

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

ST_DWithin(geometry, geometry, distance) 関数は,インデクス付きの距離検索を実行する手頃な方法です.この関数は,距離半径を十分に含む大きさの検索矩形を作成して, インデクス付きの結果サブセットに対して確実な距離検索を行います.

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

SELECT * FROM geotable 
WHERE ST_DWithin(geocolumn, 'POINT(1000 1000)', 100.0);

3.10.

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

投影変換を行うには,変換元と変換先双方の座標系がSPATIAL_REF_SYSテーブルに定義されていて, かつ投影変換されるジオメトリがそのSRIDを持っている必要があります.これが行われていると,投影変換は求める変換先SRIDを参照するのと同じぐらい簡単です. 次のクエリは,ジオメトリを NAD 84 経度緯度に投影しています.このクエリは the_geom が -1 (空間参照系が定義されていない) 場合のみ動作します.

SELECT ST_Transform(the_geom,4269) FROM geotable;

3.11.

ST_AsEWKT と ST_AsText を,かなり大きいジオメトリで実行すると,空のフィールドが返りました.どうしたら良いですか?

PgAdminまたは大きなテキストを表示しないその他のツールを使用しているのかも知れません. ジオメトリが十分に大きい場合,ツールには空として表示されます.本当にWKTで見たり出力したりしなければならない場合は,PSQLを使用して下さい.

				--To check number of geometries are really blank
				SELECT count(gid) FROM geotable WHERE the_geom IS NULL;

3.12.

ST_Intersectsを使うと,二つのジオメトリがインタセクトしているのに,インタセクトしていないと言います.どうしたら良いですか?

二つの場合がよくあります.ひとつは,ジオメトリが無効な場合です.この場合 ST_IsValid を見ます.もうひとつは,ST_AsTextで数字を切り捨てて表示されている分より後にたくさんの小数が付いている場合です.

第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 = ST_AsBinary(geometry);
text WKT = ST_AsText(geometry);
geometry = ST_GeomFromWKB(bytea WKB, SRID);
geometry = ST_GeometryFromText(text WKT, SRID);

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

INSERT INTO geotable ( the_geom, the_name )
  VALUES ( ST_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情報が埋め込まれます.

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

  • 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) -- XYM with SRID

  • 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 = ST_AsEWKB(geometry);
text EWKT = ST_AsEWKT(geometry);
geometry = ST_GeomFromEWKB(bytea EWKB);
geometry = ST_GeomFromEWKT(text EWKT);

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

INSERT INTO geotable ( the_geom, the_name )
  VALUES ( ST_GeomFromEWKT('SRID=312;POINTM(-126.4 45.32 15)'), 'A Place' )

PostgreSQLの「標準的な形式」は単純なクエリ(全く関数呼び出しが無い)で表現でできていて,INSERT, UPDATE, COPYで受け付けられることが保障されるものです.PostGISの"geometory"型は次の通りです.

- 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.1.3. SQL-MM Part 3

SQLマルチメディア・アプリケーション空間仕様は,円弧補完曲線を定義したSQL仕様の拡張です.

SQL-MMの定義では,3dm,3dzと4dの座標を含みますが,SRID情報の埋め込みはできません.

WKT拡張はまだ完全にはサポートされていません.単純な曲線ジオメトリの例を次に示します.

  • CIRCULARSTRING(0 0, 1 1, 1 0)

    CIRCULARSTRING(0 0, 4 0, 4 4, 0 4, 0 0)

    CIRCULARSTRINGは基本的な曲線型で,LINESTRINGに似ています. ひとつのセグメントで,始点,終点(一つめと三つめ)と弧上の任意の点,の3点が必要です. 例外として,始点と終点が同じとなる閉曲線があります. 閉曲線では二つめの点が弧の中心,すなわち円の反対側にならなければなりません. 弧の連結では,LINESTRINGと同じように,前の弧の最後の点が次の弧の最初の点となります. よって,妥当なCIRCULARSTRINGは1以上の奇数になります.

  • COMPOUNDCURVE(CIRCULARSTRING(0 0, 1 1, 1 0),(1 0, 0 1))

    複合曲線は,曲線(円弧)セグメントと線型セグメントの両方を持つ,単一の連続した曲線です. よって,要素が的確である必要があることに加え,各要素(最終要素は除く)の終点は次の要素の始点と同じになる必要があります.

  • CURVEPOLYGON(CIRCULARSTRING(0 0, 4 0, 4 4, 0 4, 0 0),(1 1, 3 3, 3 1, 1 1))

    曲線ポリゴンの中に複合ポリゴンがある例は次の通りです. CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.6 0.4, 1.6 0.5, 1.7 1) )

    CURVEPOLYGONは外環と0以上の内環とを持つ点でPOLYGONと似ています. 異なる点は,環に曲線ストリング,線型ストリング,複合ストリングのいずれも取れる点です.

    PostGIS 1.4から,PostGISで曲線ポリゴンで複合曲線をサポートするようになりました.

  • MULTICURVE((0 0, 5 5),CIRCULARSTRING(4 0, 4 4, 8 4))

    MULTICURVEは曲線のコレクションで,線型ストリング,曲線ストリング,複合ストリングを取れます.0

  • MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(0 0, 4 0, 4 4, 0 4, 0 0),(1 1, 3 3, 3 1, 1 1)),((10 10, 14 12, 11 10, 10 10),(11 11, 11.5 11, 11 11.5, 11 11)))

    サーフェスのコレクションです.(線型)ポリゴンか曲線ポリゴンを取れます.

[注意]

PostGIS 1.4より前では,曲線ポリゴンで複合曲線をサポートしていませんでしたが, PostGIS 1.4以降は曲線ポリゴンでの複合曲線の使用をサポートするようになりました.

[注意]

SQL-MM実装での全ての浮動小数点数の比較では,所定の丸め誤差があります.現在は1E-8です.

4.2. ジオグラフィ型

ジオグラフィ型は,「地理」座標(しばしば「測地」座標,"lat/lon", "lon/lat", 緯度経度, 経度緯度 などとも呼ばれます)上で表現された空間フィーチャーのネイティブサポートするためのものです.地理座標は角度の単位(度)で合わさられる球面座標です.

PostGISのジオメトリ型の基礎は平面です.平面上の二点間の最短コースは直線になります.よって,ジオメトリ上の計算(面積,距離,長さ,インタセクション等)は,デカルト座標と線型ベクトルを使用することができます.

PostGISのジオグラフィ型の基礎は球面です.球面上での二点間の最短距離は大圏の弧です.よって,ジオグラフィ上の計算(面積,距離,長さ,インタセクション等)は,球面上で計算しなければならず,複雑な計算が必要となります.より正確な計測のためには,世界の実際の回転楕円体の形を考慮に入れなければならず,非常に複雑です.

基礎となる数学が大変に複雑なので,ジオグラフィ型用に定義された関数は,ジオメトリ型よりも少ないです.時間とともに,新しいアルゴリズムが追加されて,ジオグラフィ型の能力は拡大していくでしょう.

WGS84経度緯度(SRID:4326)のみサポートしているという制限があります. ジオグラフィと呼ばれる新しいデータ型を使用します. GEOS関数にこの新しい型をサポートする関数がありません. 回避策として,ジオメトリとジオグラフィの型変換を行うことができます.

ジオグラフィ型はPostgreSQL 8.3以上のtypmod定義書式を使います.ジオグラフィカラムを持つテーブルに1ステップで追加できます.標準OGC書式は曲線を除いてサポートします.

4.2.1. ジオグラフィ基礎

ジオグラフィ型は簡単なフィーチャーの最も簡単なもののみサポートします.標準的なジオメトリ型データで,SRIDが4326の場合は,ジオグラフィに自動でキャストされます.またEWKTとEWKBの取り決めを使うこともできます.

  • POINT: 2次元のポイントジオメトリを持つテーブルの作成は次の通りです.

    CREATE TABLE testgeog(gid serial PRIMARY KEY, the_geog geography(POINT,4326) );

    Z値を持つポイントの場合は次の通りです.

    CREATE TABLE testgeog(gid serial PRIMARY KEY, the_geog geography(POINTZ,4326) );
  • LINESTRING

  • POLYGON

  • MULTIPOINT

  • MULTILINESTRING

  • MULTIPOLYGON

  • GEOMETRYCOLLECTION

新しいジオグラフィカラムはgeometry_columnsに登録されてません.システムカタログを見るgeomgraphy_columnsという新しいビューに登録されるので,AddGeom... といった関数を使わずに,自動管理されます.

"geography_columns"ビューをチェックして,テーブルがリストされているか見て下さい.

CREATE TABLEでジオグラフィカラムを持つテーブルを作ることができます. ジオメトリと違って,AddGeometryColumns()でメタデータにカラム情報を登録する処理を別に行う必要がなくなりました.

CREATE TABLE global_points ( 
    id SERIAL PRIMARY KEY,
    name VARCHAR(64),
    location GEOGRAPHY(POINT,4326)
  );

locationカラムはGEOGRAPHY型で,二つのオプション修飾子をサポートすることにご注意ください. ひとつは,そのカラムで使用できる形状と次元を限定する型修飾子です.もうひとつは,座標参照IDを特定の数に限定するSRID修飾子です.

型修飾子で許される値は POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON です.この修飾子ではZ, M, ZM の拡張子によって次元を限定します.たとえば,'LINESTRINGM'という値では,3次元で,第3次元が計測値(measure)となります.同じように見て 'POINTZM' は,4次元となります.

SRID修飾子には,現在は4326(WGS84)の許されるという制限があります.SRIDを指定したくない場合は 0 (未定義の回転楕円体) を使います.この場合の全ての計算は,WGS84とします.

将来的には,他のSRIDによって,WGS84以外の回転楕円体に関する計算ができるようにします.

テーブルを作ったら,次のようにしてGEOGRAPHY_COLUMNSを見ることができます.

-- See the contents of the metadata view
SELECT * FROM geography_columns;

ジオメトリカラムを使うのと同じようにテーブルへのデータの挿入ができます.

-- Add some data into the test table
INSERT INTO global_points (name, location) VALUES ('Town', ST_GeographyFromText('SRID=4326;POINT(-110 30)') );
INSERT INTO global_points (name, location) VALUES ('Forest', ST_GeographyFromText('SRID=4326;POINT(-109 29)') );
INSERT INTO global_points (name, location) VALUES ('London', ST_GeographyFromText('SRID=4326;POINT(0 49)') );

ジオメトリカラムと同じ操作でインデクスを作成します. PostGISは,カラム型がGEOGRAPHYであるかを見て,GEOMETRYで使われる平面用インデクスの代わりに球面ベースのインデクスを作成します.

-- Index the test table with a spherical index
  CREATE INDEX global_points_gix ON global_points USING GIST ( location );

クエリと計測関数はメートル単位となります.そのため距離パラメータはメートル(面積の場合は平方メートル)単位となります.

-- Show a distance query and note, London is outside the 1000km tolerance
  SELECT name FROM global_points WHERE ST_DWithin(location, ST_GeographyFromText('SRID=4326;POINT(-110 29)'), 1000000);

GEOGRAPHYの威力については,シアトルからロンドンまで(LINESTRING(-122.33 47.606, 0.0 51.5))の飛行機がレイキャビク(POINT(-21.96 64.15))に最も近くなるときの距離を求めてみると分かります.

-- Distance calculation using GEOGRAPHY (122.2km)
  SELECT ST_Distance('LINESTRING(-122.33 47.606, 0.0 51.5)'::geography, 'POINT(-21.96 64.15)':: geography);

-- Distance calculation using GEOMETRY (13.3 "degrees")
  SELECT ST_Distance('LINESTRING(-122.33 47.606, 0.0 51.5)'::geometry, 'POINT(-21.96 64.15)':: geometry);

GEOGRAPHY型は,レイキャビクとシアトル-ロンドン間の飛行機の大圏コースとの間の,球面上での本当に最も近い距離を計算します.

大圏コースマップ GEOMETRY型は,平面の世界地図上にプロットされたレイキャビクとシアトル-ロンドン間の直線とのデカルト距離という意味のない値を出します.結果の名目上の単位は「度」ですが,点間の本当の角度差にあっていませんので,「度」と言うこと自体不正確です.

4.2.2. ジオグラフィ型をジオメトリ型にして使用すべき時

GEOGRAPHY型によって,経度緯度座標でデータを格納できるようになりましたが, GEOGRAPHYで定義されている関数が,GEOMETRYより少ないのと,実行にCPU時間がかかる,というところが犠牲になっています.

選択した型が,期待する領域から出ないことを条件とすべきです. 使用するデータは地球全体か,大陸か,州か,自治体か?

  • データが小さいエリア内におさまるなら,適切な投影を選択してGEOMETRYを使うのが,効率面でも機能面でも最も良い方法です.
  • データが地球全体か大陸なら,GEOGRAPHYで投影法の細かい問題を気にせずにシステムを構築できるでしょう.
  • 投影法を理解していなくて,学習したくもなくて,かつ,GEOGRAPHYで使える関数が限られていることを受け入れるのなら,GEOGRAPHYを使った方が簡単です.単にデータを経度緯度でロードして,そこから進めて下さい.

ジオグラフィとジオメトリ間のサポート状況の比較については 「 PostGIS関数サポートマトリクス 」 をご覧ください.ジオグラフィ関数の簡潔なリストと説明については 「 PostGISジオグラフィサポート関数 」 をご覧ください.

4.2.3. ジオグラフィの高度なよくある質問

4.2.3.1. 球または回転楕円体のどちらで計算するのか?
4.2.3.2. 日付変更線や極に関してはどうなっていますか?
4.2.3.3. 弧の処理の最大長はどうなりますか?
4.2.3.4. なぜヨーロッパやロシアといった大きな範囲の面積計算はとても遅いのですか

4.2.3.1.

球または回転楕円体のどちらで計算するのか?

デフォルトでは,全ての距離と面積の計算は回転楕円体で行います.局所的なエリアでの計算結果と良好な投影を施した平面での結果と比較して下さい.大きなエリアの場合は,回転楕円体計算は,投影平面上でのどの計算よりも精度が高くなります.

ジオグラフィ関数には,最後の真偽パラメータを 'FALSE' にすると球面を使った計算を行うというオプションがあります. これは,特にジオメトリが非常に単純である場合に計算を速くするためのものです.

4.2.3.2.

日付変更線や極に関してはどうなっていますか?

全ての計算に日付変更線や極の概念があるというわけではありません. 座標は球(経度/緯度)であるので,日付変更線とクロスする形状は,計算の観点からは,他のものと変わりありません.

4.2.3.3.

弧の処理の最大長はどうなりますか?

大圏の弧を2点の「補完線」として使用しています.任意の2点は,実際には2方向につながっていて,どちらの方向に行くかに依存します.PostGISの全てのコードは,大圏コースの2コースのうち*短い*方でつながっていると仮定しています.結果として,180度以上の弧を持つ形状は正しくモデル化しません.

4.2.3.4.

なぜヨーロッパやロシアといった大きな範囲の面積計算はとても遅いのですか

ポリゴンがとんでもなく大きいからです.二つの理由から,大きなエリアは悪いです.ひとつは,場生んだりボックスが大きいため,どのようなクエリを走らせても,インデクスがフィーチャーを引っ張ってくる傾向にあるためです.もうひとつは,バーテック数が巨大で,テスト(距離,包含)関数では,少なくとも1回,通常はN(Nは,もう一方のフィーチャーのバーテック数)回,バーテックを横断しなければならないためです.

GEOMETRYでは,大きなポリゴンを持っているが小さな英らのクエリを実行する時, ジオメトリデータ情報を小片に「非正常化」します.これにより,インデクスが効果的にオブジェクトの一部を問い合わせるようになり,またクエリが常にオブジェクト全体を引っ張りこむようなことがないようになります.ヨーロッパ全体を一つに*格納できる*からといって,そうすべきだというわけではありません.

4.3. OpenGIS標準を使う

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

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

4.3.1. SPATIAL_REF_SYSテーブルと空間参照系

spatial_ref_sysテーブルは,PostGISに含まれるもので,3000以上の空間参照系を持つ,OGC準拠のデータベーステーブルで,さらに言うと,空間参照系間の変換や投影変換に使われます.

PostGISのspatial_ref_sysテーブルには,projライブラリで使われる3000以上の一般に使われる空間参照系定義がありますが,全てを持っているわけではなく,proj4の構築に慣れているならカスタム投影を定義することができます.ほとんどの空間参照系は地域限定のもので,想定されている範囲の外で使うと意味が無いことにご留意ください.

PostGISのコアセットに入っていない空間参照系を探すための素晴らしい資料が http://spatialreference.org/ にあります.

よく共通的に使われる空間参照系は次の通りです. 4326 - WGS 84 経度緯度, 4269 - NAD 83 経度緯度, 3395 - WGS 84 メルカトル図法, 2163 - 米国ナショナルアトラス正積図法, NAD83, WGS84 UTM の空間参照系 - UTMゾーンは計測に最も理想的なもののひとつですが6度(訳注: 経度を指します)の領域しかカバーしません.

さまざまな米国の州の平面空間参照系(メートルまたはフィート単位) - 通常は州ごとに一つか二つあります.メートル単位のもののほとんどがPostGISのコアセットに入っていますが,多数のフィート単位のものやESRIが作ったものについては spatialreference.org から取得して下さい.

対象領域がどのUTMゾーンになるかを決めるには, utmzone PostGIS plpgsql helper function を参照して下さい.

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.opengeospatial.org/をご覧下さい. WKTの一般的な議論については,OpenGISの「座標変換サービス実装仕様」 http://www.opengeospatial.org/standards をご覧下さい.欧州石油調査グループ(European Petroleum Survey Group, EPSG)と EPSG空間参照系のデータベースに関する情報は,http://www.epsg.org をご覧下さい.

PROJ4TEXT

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

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

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

4.3.2. GEOMETRY_COLUMNSテーブル

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

CREATE TABLE geometry_columns (
  f_table_catalog    VARRCHAR(256) NOT NULL,
  f_table_schema     VARCHAR(256) NOT NULL,
  f_table_nam        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.3.3. 空間テーブルを作る

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

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

    例: CREATE TABLE ROADS_GEOM ( ID int4, NAME varchar(25) )

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

    文法は次の通りです.

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

    現在のスキーマを使う場合には次のようにします.

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

    例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    INTEGER,
  park_name  VARCHAR,
  park_date  DATE,
  park_type  VARCHAR
);
SELECT AddGeometryColumn('parks', 'park_geom', 128, 'MULTIPOLYGON', 2 );

もうひとつ,ジェネリックな"geometry"型とSRID不明を示す-1を使った例を挙げます.

CREATE TABLE roads (
  road_id INTEGER,
  road_name VARCHAR
);
SELECT AddGeometryColumn( 'roads', 'roads_geom', -1, 'GEOMETRY', 3 );

4.3.4. 手動でジオメトリカラムをgeometry_columnsに登録する

AddGeometryColumn()アプローチは,ジオメトリカラムを作成して,新しいカラムをgeometry_columnsテーブルに登録します. ソフトウェアでgeometry_columnsを使う場合には,クエリに必要なジオメトリカラムを全てこのテーブルに登録する必要があります. ジオメトリカラムをgeometry_columnsに登録したいけれどもAddGeometryColumnが使えないというケースとしては, SQLビューである場合と,巨大なデータ挿入の場合です. これらの場合はカラムをgeometry_columnsテーブルに手動で登録する必要があります.次に簡単な登録スクリプトを示します.

--次のように作ったビューがあるとしましょう
CREATE VIEW  public.vwmytablemercator AS
	SELECT gid, ST_Transform(the_geom,3395) As the_geom, f_name
	FROM public.mytable;

--このビューをgeometry_columnsに登録するには次のようにします.
INSERT INTO geometry_columns(f_table_catalog, f_table_schema, f_table_name, f_geometry_column, coord_dimension, srid, "type")
SELECT '', 'public', 'vwmytablemercator', 'the_geom', ST_CoordDim(the_geom), ST_SRID(the_geom), GeometryType(the_geom)
FROM public.vwmytablemercator LIMIT 1;


		
--巨大なデータ挿入によって派生テーブルを作ったとしましょう
SELECT poi.gid, poi.the_geom, citybounds.city_name
INTO myschema.myspecialpois
FROM poi INNER JOIN citybounds ON ST_Intersects(citybounds.the_geom, poi.the_geom);

--新しいデーブルにインデクスを作ります
CREATE INDEX idx_myschema_myspecialpois_geom_gist
  ON myschema.myspecialpois USING gist(the_geom);

--手動でこの新しいテーブルのジオメトリカラムをgeometry_columnsに登録するには,ビューの時と同じようにします.
INSERT INTO geometry_columns(f_table_catalog, f_table_schema, f_table_name, f_geometry_column, coord_dimension, srid, "type")
SELECT '', 'myschema', 'myspecialpois', 'the_geom', ST_CoordDim(the_geom), ST_SRID(the_geom), GeometryType(the_geom)
FROM public.myschema.myspecialpois LIMIT 1;



		

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

PostGISはOpen Geospatial Consortium (OGC)のOpenGIS使用に準拠しています. このように,多くのPostGISメソッドは 操作するジオメトリが単純かつ妥当である必要がある(正確に言うとそう過程します). たとえば,ポリゴンの外に穴があるようなものの面積を計算したり,単純でない境界線を持つポリゴンを作ったりするのは,意味がありません.

OGS仕様に沿うと,単純なジオメトリとは,自己インタセクトや自己接触があるような,異常な幾何点を持たないことです.主に0次元または1次元のジオメトリ([MULTI]POINT, [MULTI]LINESTRING)に適用します. 他方,ジオメトリの妥当性は,主に2次元ジオメトリ([MULTI]POLYGON))に適用し,妥当なポリゴンを特徴づける位置指定子の集合を定義します.個々のジオメトリクラスには,単純性と妥当性をさらに詳細に述べる特定の条件があります.

POINTは0次元ジオメトリオブジェクトとして常に単純です.

MULTIPOINTは,二つの座標値(POINT)が同じでないなら単純です.

LINESTRINGは2度同じPOINTを通らない(終点は除きます.この場合は線型環と呼ばれ,さらに閉じていると思われます)なら単純です.

(a)

(b)

(c)

(d)

(a)(c)は単純なLINESTRINGで,(b)(d)は単純ではありません.

MULTILINESTRINGは, 全ての要素が単純で,かつ任意の2要素のインタセクトが要素の境界であるPOINTでだけ発生する場合に限って, 単純です.

(e)

(f)

(g)

(e)(f)は単純なMULTILINESTRINGで,(g)は単純ではありません.

定義からPOLYGONは常に単純です. バウンダリ内の環(外環と内環からなる)のうち二つがクロスしていないなら妥当です. POLYGONの境界は,POINTとインタセクトするかも知れませんが,接点にしかなりません(すなわち線上にない). POLYGONは切られた線またはスパイク(訳注: ポリゴンから「スパイク」のように出た線)をもたなくても良く,内環は外環の中に完全に含まれていなければなりません.

(h)

(i)

(j)

(k)

(l)

(m)

(h)(i)は妥当なPOLYGONです.(j-m)は単一のPOLYGONとしては表現できません.(j)(m)は妥当なMULTIPOLYGONとして表現できません.

MULTIPOLYGONは,全ての要素が妥当で,ポリゴン要素のうち二つについて内環がインタセクトしていない場合のみ妥当です. ポリゴン要素の任意の二つの境界が接触してもよいですが,POINTの数は有限です.

(n)

(o)

(n)(o)は妥当なMULTIPOLYGONです.

GEOSライブラリに実装されている関数のほとんどは,ジオメトリがOpenGIS Simple Feature Specificationで定義されているように妥当であると仮定しています.ジオメトリが単純であるか,また妥当であるか,のチェックとしてST_IsSimple()ST_IsValid()が使えます.

-- 一般的に,線型のフィーチャーの妥当性のチェックは,
-- 常にTRUEを返すので意味がありません.
-- しかし,この例では,PostGISは,線型の環(開始点と終了点が同じ)が
-- 二つ以下のバーテックからなる場合はFALSEを返すように
-- OGCのIsValidの定義を拡張しています.
gisdb=# SELECT
   ST_IsValid('LINESTRING(0 0, 1 1)'),
   ST_IsValid('LINESTRING(0 0, 0 0)');

 st_isvalid | st_isvalid
------------+-----------
      t     |     f

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

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

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

[注意]

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

4.3.6. Dimensionally Extended 9 Intersection Model (DE-9IM)

代表的な空間述語(ST_Contains, ST_Crosses, ST_Intersects, ST_Touches, ...)は, 求める空間フィルタを十分に提供しきれないことがあります.

たとえば,道路網を表現する線型のデータセットがあるとします.ビジネスルールを無視しているかも知れませんが,点でクロスするだけでなく線上でクロスする道路区間を全て判別することがGIS解析者の仕事となるかも知れません.この場合,ST_Crossesでは重要な空間フィルタとして十分ではありません.線型のフィーチャーでは,点でクロスしている場合のみtrueが返ります.

空間的にインタセクトしている(ST_Intersects)と判別された二つの区間の組み合わせについての実際のインタセクト(ST_Intersection)を取り, インタセクトのST_GeometryTypeが'LINESTRING'であるかを見る ([MULTI]POINT, [MULTI]LINESTRING等からなるGEOMETRYCOLLECTIONが返ってくる場合にしっかり対処します),とい2段階の方法で解くことはできます.

よりエレガントかつ速い解法が本当に望ましいでしょう.

二つ目の[理論的な]例として,GIS解析者が全ての湖の境界に線でインタセクトする波止場やドックの全ての位置を特定しようとするとします.ここで,波止場の一端だけ陸にあるとします.言いかえると,波止場が湖の中にあるが完全に中に入りきってはいなくて,湖と線でインタセクトして,波止場の一方の端が完全に湖に入っていて,かつもう一方の端点が境界線上にあります.解析者は空間述語の組み合わせでフィーチャーの後で探索対象を引き出さなくてはならないかも知れません.

ここで,Dimensionally Extended 9 Intersection Modelまたは略してDE-9IMを見てみましょう.

4.3.6.1. 理論

OpenGIS Simple Features Implementation Specification for SQLによると「二つのジオメトリの比較の基本的なアプローチは,二つのジオメトリの内部,境界,外部のインタセクションの比較と,『インタセクション行列』の要素に基づく2ジオメトリの関係の分類です」.

境界(Boundary)

ジオメトリの境界はひとつ低い次元のジオメトリの集合です.0次元のPOINTの境界は空集合です.LINESTRINGの境界は二つの端点です.POLYGONの境界は外環と内環を形成する線です.

内部(Interior)

ジオメトリの内部は境界を取り去った際に残るジオメトリです. POINTの内部はPOINTそのものです.LINESTRINGの内部は二つの端点の間の実際の点です.POLYGONの内部はポリゴンの内側の範囲です.

外部(Exterior)

ジオメトリの外部は,内部と境界を除いた全領域です.

ジオメトリaがあり,aの内部境界外部をそれぞれI(a), B(a), E(a)とします.数学的な行列表現は次のようになります.

  内部 境界 外部
内部 dim( I(a) I(b) ) dim( I(a) B(b) ) dim( I(a) E(b) )
境界 dim( B(a) I(b) ) dim( B(a) B(b) ) dim( B(a) E(b) )
外部 dim( E(a) I(b) ) dim( E(a) B(b) ) dim( E(a) E(b) )

ここでdim(a)aの次元で,ST_Dimensionで規定されますが,{0,1,2,T,F,*}の値域を持ちます.

  • 0 => ポイント

  • 1 => ライン

  • 2 => 領域

  • T => {0,1,2}

  • F => 空集合

  • * => 何でも良い

可視化すると,二つのオーバラップするポリゴンについては,次のようになります.

 

  内部 境界 外部
内部

dim(...) = 2

dim(...) = 1

dim(...) = 2

境界

dim(...) = 1

dim(...) = 0

dim(...) = 1

外部

dim(...) = 2

dim(...) = 1

dim(...) = 2

左から右,上から下に読むと,次元行列は'212101212'と表現されます.

一つ目の例である線上での2線のインタセクトは,関係行列で'1*1***1**'となります.

-- 線上でクロスする道路区間の判別
SELECT a.id
FROM roads a, roads b
WHERE a.id != b.id 
AND a.geom && b.geom
AND ST_Relate(a.geom, b.geom, '1*1***1**');

二つ目の例である一部が湖の水涯線上にある波止場は,関係行列で'102101FF2'となります.

-- 一部が湖の水涯線上にある波止場の判別
SELECT a.lake_id, b.wharf_id
FROM lakes a, wharfs b
WHERE a.geom && b.geom
AND ST_Relate(a.geom, b.geom, '102101FF2');

これ以上の情報ついては,次のページをご覧ください.

4.4. GISデータをロードする

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

4.4.1. SQLを使う

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

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

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

データファイルは,次に示す"psql"というSQL端末モニタを使って,簡単にPostgreSQLにパイプで送られます.

psql -d [database] -f roads.sql

4.4.2. ローダを使う

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

さらに,コマンドラインローダのほとんどのオプションに対応するshp2pgsql-guiグラフィカルユーザインタフェースがあります.一度限りでスクリプト化しないロードを行う場合やPostGISに不慣れな方にとって便利になるかもしれません.これはPgAdminIIIのプラグインとし構築することもできます.

(c|a|d|p) 相互に排他的なオプション

-c

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

-a

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

-d

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

-p

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

-?

ヘルプ画面を表示します.

-D

出力データにPostgreSQLの"dump"書式を用います.このモードは -a, -c, -d が含まれます.デフォルトの"insert"によるSQL書式よりも,大変早くロードできます.大きなデータセットではこちらを使用して下さい.

-s <SRID>

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

-k

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

-i

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

-I

ジオメトリカラムにGiSTインデクスを生成します.

-w

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

-W <encoding>

入力データ(dbfファイル)の文字コードを指定します. dbfの全ての属性は指定された文字コードからUTF8に変換されます. SQL出力にSET CLIENT_ENCODING to UTF8コマンドが加えられ,バックエンドでUTF8からデータベースが内部で使用するように設定されている文字コードに再変換できます.

-N <policy>

NULLジオメトリ操作方針(insert* = 挿入, skip = スキップ, abort = 強制終了)を選択します.

-n

DBFファイルのみインポートします.対応するシェープファイルを持っていない場合, 自動的にこのモードになり,DBFファイルのみロードします. このフラグは,完全なシェープファイル群を持っていて,属性データだけが欲しくてジオメトリが欲しくない時のみ使用します.

-G

ジオメトリ型のかわりに,ジオグラフィ型で,WGS84経度緯度(SRID=4326)を使用します(経度緯度データが必要です).

ローダを使って入力ファイルを生成してデータをアップロードするセッションの例を次に示します.

# shp2pgsql -c -D -s 4269 -i -I shaperoads.shp myschema.roadstable > roads.sql
# psql -d roadsdb -f roads.sql

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

# shp2pgsql shaperoads.shp myschema.roadstable | psql -d roadsdb

4.5. GISデータを検索する

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

4.5.1. SQLを使う

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

db=# SELECT road_id, ST_AsText(road_geom) AS geom, road_name FROM roads;

road_id | geom                                    | road_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 road_id, road_name
  FROM roads
  WHERE roads_geom ~= ST_GeomFromText('LINESTRING(191232 243118,191108 243242)',-1);

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

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

SELECT road_id, road_name
FROM roads
WHERE roads_geom && ST_GeomFromText('POLYGON((...))',-1);

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

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

SELECT ST_AsText(roads_geom) AS geom
FROM roads
WHERE
  roads_geom && SetSRID('BOX3D(191232 243117,191232 243119)'::box3d,-1);

ここで,BOX3Dの投影を指定していることに注意して下さい. SRIDを-1に設定しているのは,SRIDを指定しないということを示しています.

4.5.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.6. インデクスを構築する

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

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

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

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

4.6.1. GiSTインデクス

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

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

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

CREATE INDEX [インデクス名] ON [テーブル名] USING GIST ( [ジオメトリカラム名] ); 

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

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

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

4.6.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-Treeインデクスを使うべき時に関してあなたが知っていることよりも,プランナはより良く知っています.クエリを実行したら,ENABLE_SEQSCAN設定を戻して,他のクエリでは通常通りプランナを使用することを考えるべきです.

    [注意]

    version 0.6では,ENABLE_SEQSCANでプランナにインデクスを使わせることは重要ではありません.

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

4.7. 複雑なクエリ

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

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

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

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

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

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

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

[注意] ふるまいの変更

PostGIS 1.3.0では,ST_DisjointとST_Relateの注目すべき例外がありますが,ほとんどのジオメトリ関係関数は暗黙的なバウンディングボックスオーバラップ演算子を含んでいます.

4.7.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.7.2.1. 道路の総延長はkm表記でいくらになるでしょう?
4.7.2.2. プリンスジョージ市の大きさはha表記でいくらになるでしょう?
4.7.2.3. 県内で最も大きな面積を持つ自治体はどこでしょう?
4.7.2.4. 各自治体内に含まれる道路の総延長はいくらでしょう?
4.7.2.5. プリンスジョージ市内の全ての道路からなるテーブルを作る
4.7.2.6. ビクトリア州の「ダグラス通り」の長さはkm表記でいくらになるでしょう?
4.7.2.7. 全体の中で最も大きい自治体ポリゴンはどれでしょう?

4.7.2.1.

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

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

SELECT sum(ST_Length(the_geom))/1000 AS km_roads FROM bc_roads;

km_roads
------------------
70842.1243039643
(1 row)

4.7.2.2.

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

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

SELECT
  ST_Area(the_geom)/10000 AS hectares
FROM bc_municipality
WHERE name = 'PRINCE GEORGE';

hectares
------------------
32657.9103824927
(1 row)

4.7.2.3.

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

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

SELECT
  name,
  ST_Area(the_geom)/10000 AS hectares
FROM
  bc_municipality
ORDER BY hectares DESC
LIMIT 1;

name           | hectares
---------------+-----------------
TUMBLER RIDGE  | 155020.02556131
(1 row)

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

4.7.2.4.

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

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

SELECT
  m.name,
  sum(ST_Length(r.the_geom))/1000 as roads_km
FROM
  bc_roads AS r,
  bc_municipality AS m
WHERE
  ST_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.7.2.5.

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

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

CREATE TABLE pg_roads as
SELECT
  ST_Intersection(r.the_geom, m.the_geom) AS intersection_geom,
  ST_Length(r.the_geom) AS rd_orig_length,
  r.*
FROM
  bc_roads AS r,
  bc_municipality AS m
WHERE  m.name = 'PRINCE GEORGE' AND ST_Intersects(r.the_geom, m.the_geom);

4.7.2.6.

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

SELECT
  sum(ST_Length(r.the_geom))/1000 AS kilometers
FROM
  bc_roads r,
  bc_municipality m
WHERE  r.name = 'Douglas St' AND m.name = 'VICTORIA'
	AND ST_Contains(m.the_geom, r.the_geom) ;

kilometers
------------------
4.89151904172838
(1 row)

4.7.2.7.

全体の中で最も大きい自治体ポリゴンはどれでしょう?

SELECT gid, name, ST_Area(the_geom) AS area
FROM bc_municipality
WHERE ST_NRings(the_geom) > 1
ORDER BY area DESC LIMIT 1;

gid  | name         | area
-----+--------------+------------------
12   | SPALLUMCHEEN | 257374619.430216
(1 row)

第5章 PostGISを使う: アプリケーションを構築する

5.1. MapServerを使う

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

5.1.1. 基本的な使い方

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

PostGISをMapServerで使うには,次のことが必要です.

  • PostGIS 0.6以上

  • MapServer 3.5以上

MapServerは,他のPostgreSQLクライアントのように,libpqインタフェースを使って,PostGIS/PostgreSQLデータにアクセスします.よってMapServerはPostGISサーバにアクセスするネットワークを持つ計算機にインストールでき,PostGISをデータソースとして使用することができます.システム間の接続は速いほど良いです.

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

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

    LAYER 
      CONNECTIONTYPE postgis 
      NAME "widehighways" 
      # リモートの空間電他ベースに接続
      CONNECTION "user=dbuser dbname=gisdatabase host=bigserver"
      PROCESSING "CLOSE_CONNECTION=DEFER"
      # 'road'テーブルの'geom'カラムから線を取得
      DATA "geom from roads using srid=4326 using unique gid" 
      STATUS ON
      TYPE LINE 
      # 範囲内の線のうち広い高速道路のみ描画
      FILTER "type = 'highway' and numlanes >= 4" 
      CLASS 
        # スーパー高速道路は,明るくし,2ピクセル幅にする
        EXPRESSION ([numlanes] >= 6) 
        STYLE
          COLOR 255 22 22 
          WIDTH 2 
        END
      END 
      CLASS 
        # 残りの道路は,暗くし,1ピクセル幅にする
        EXPRESSION ([numlanes] < 6) 
        STYLE
          COLOR 205 92 82
        END
      END 
    END

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

    CONNECTIONTYPE

    PostGISレイヤにするには,ここは常に"postgis"になります.

    CONNECTION

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

    user=<username> password=<password> dbname=<username> hostname=<server> port=<5432>

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

    DATA

    このパラメータの形式は"<geocolumn> from <tablename> using srid=<srid> using unique <primary key>"です.ここで,カラムは地図に描画する空間カラムで,SRIDは,カラムが使用するSRIDで,主キーはテーブルの主キー(または他の,インデクスを持つユニークな値のカラム)です.

    "using srid"と"using unique"節は省略可能です. MapServerは可能なら自動的に正しい値を決定しますが,マップを描画するたびにいくつかの追加クエリを実行するコストがかかります.

    PROCESSING

    接続を閉じずに,複数のレイヤで再利用する場合にCLOSE_CONNECTION=DEFERを設定します.これで速度が改善します.より詳しい説明については MapServer PostGIS Performance Tips を参照して下さい.

    FILTER

    フィルタは,妥当なSQL文字列でなければなりません.普通はSQLクエリ内で"WHERE"キーワードに続く論理式に沿います.たとえば,6レーン以上の道路のみをレンダリングするには,フィルタを "num_lanes >= 6" とします.

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

    CREATE INDEX [インデクス名] ON [テーブル名] USING GIST ( [ジオメトリカラム名] );
  4. MapServerを使用するレイヤのクエリ実行するなら,"using unique"節もDATAステートメントに追加しなければなりません.

    MapServerでは,クエリ実行の際には,それぞれの空間レコードを識別するためのユニークなIDが必要です.MapServerのPostGISモジュールは,ユニークなIDを提供するために,ユーザ指定のユニークな値を使います.テーブルの主キーを使うのが最も良い方法です.

5.1.2. よくある質問

5.1.2.1. EXPRESSIONをmapファイルで使う時に,値がテーブルにあるのを確認しているのに条件がtrueになりません.
5.1.2.2. シェープファイルで使っているFILTERが,同じデータを持つPostGISテーブルでは動作しません.
5.1.2.3. PostGISレイヤの描画がシェープファイルより遅くなりますが,これが普通なのでしょうか?
5.1.2.4. PostGISレイヤはちゃんと描けましたが,クエリが本当に遅いです.何が問題なのですか?
5.1.2.5. ジオグラフィカラム(PostGIS 1.5で機能追加)をMapServerのレイヤのソースとして使用できますか?

5.1.2.1.

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

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

EXPRESSION ([numlanes] >= 6)

5.1.2.2.

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

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

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

5.1.2.3.

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

一般的に,地図に描画されるフィーチャーが多くなると,PostGISはシェープファイルより遅くなります.比較的少ないフィーチャー(100台)ではPostGISの方が早く,フィーチャー密度が高くなる(1000台)と,PostGISの方が遅くなります.

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

postgis# CREATE INDEX geotable_gix ON geotable USING GIST ( geocolumn ); 
postgis# VACUUM ANALYZE;

5.1.2.4.

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

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

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

DATA "the_geom FROM geotable USING UNIQUE gid"

5.1.2.5.

ジオグラフィカラム(PostGIS 1.5で機能追加)をMapServerのレイヤのソースとして使用できますか?

できます!MapServerはジオグラフィカラムをジオメトリカラムと同じに認識します. しかし,常にSRIDを4326とします. "using srid=43426"節をDATAステートメントに入れて下さい. 他の部分はジオメトリの場合と同じです.

DATA "the_geog FROM geogtable USING SRID=4326 USING UNIQUE gid"

5.1.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 gid USING SRID=-1"
USING UNIQUE <uniqueid>

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

[注意]

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

USING SRID=<srid>

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

5.1.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 
    STYLE
      COLOR 0 0 0 
    END
  END 
END

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

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

LAYER 
  CONNECTIONTYPE postgis 
  CONNECTION "user=theuser password=thepass dbname=thedb host=theserver" 
  PROCESSING "CLOSE_CONNECTION=DEFER"
  DATA "the_geom from roads"
  MINSCALE 100000 
  STATUS ON 
  TYPE LINE 
  FILTER "road_type = 'highway'" 
  CLASS 
    COLOR 0 0 0 
  END 
END 
LAYER 
  CONNECTIONTYPE postgis 
  CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
  PROCESSING "CLOSE_CONNECTION=DEFER"
  DATA "the_geom from roads" 
  MAXSCALE 100000 
  STATUS ON 
  TYPE LINE
  CLASSITEM road_type 
  CLASS 
    EXPRESSION "highway" 
    STYLE
      WIDTH 2 
      COLOR 255 0 0  
    END
  END 
  CLASS  
    STYLE
      COLOR 0 0 0 
    END
  END 
END

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

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

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

LAYER 
  CONNECTIONTYPE postgis
  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を使用する方法も示しています.

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

Javaクライアントは,直接的にテキスト表現として,またはPostGISにバンドルされているJDBC拡張オブジェクトを使用して,PostgreSQLデータベース内にある,PostGISの"geometry"オブジェクトにアクセスできます.拡張オブジェクトを使うためには,"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");
    /* 
    * Create a statement and execute a select query. 
    */ 
    Statement s = conn.createStatement(); 
    ResultSet r = s.executeQuery("select ST_AsText(geom) as geom,id from geomtable"); 
    while( r.next() ) { 
      /* 
      * Retrieve the geometry as an object then cast it to the geometry type. 
      * Print things out. 
      */ 
      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をご覧下さい.

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

...

5.3.1. テキストカーソル

...

5.3.2. バイナリカーソル

...

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

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

6.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 ) をご覧下さい.

6.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 = ST_Envelope(ST_Force_2d(the_geom));

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

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

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

6.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
(エラー: インデクスアクセスメソッドがNULL値を扱わない場合クラスタ化できません)
HINT: You may be able to work around this by marking column "the_geom" NOT NULL.
(ヒント: 列"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制限は使えません.

6.3. 次元変換の回避

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

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

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

大きなテーブルの場合, WHERE節,およびプライマリキー若しくは他の適切な基準によってテーブルの一部へのUPDATEを制限させて,UPDATEの実行の間に単に"VACUUM;"と実行することで, UPDATEをより小さい塊に分割するのが賢いやり方かもしれません.これにより,テンポラリディスクスペースが劇的に減少します.さらに,次元混合のジオメトリを持つ場合, "WHERE dimension(the_geom)>2"でUPDATEを制限することで, 2次元で書かれているジオメトリの再書き込みをスキップさせることができます.

6.4. コンフィギュレーションのチューン

この技法は,FOSS4G 2007カンファレンスでのKevin Neufeldのプレゼンテーション「PostGISパワーユーザのための技法(Tips for the PostGIS Power User)」から得たものです. PostGISの使用(たとえば,「静的データと複雑な解析」対「よくアップデートされるデータと多数のユーザ」など)に依存して,これらの変更によって,クエリがはっきり速度向上するようになります.

詳細情報(およびよりよい書式)については,オリジナルのプレゼンテーションがhttp://2007.foss4g.org/presentations/view.php?abstract_id=117にあります.

6.4.1. スタートアップ

これらの設定はpostgresql.conf内にあります.

checkpoint_segment_size (この設定は新しいバージョンのPostgreSQLでは非推奨)は,checkpoint や WAL ではじまる多数の設定に入れ替えられました.

  • WALファイル数 = 16MBごと; デフォルトは 3

  • 書き込みが多い等大きなデータベース負荷がある場合は,データベースごとに少なくとも10か30を設定します.他の記事としてGreg Smith: Checkpoint and Background writerがあります.

  • おそらくxlogを別のディスクデバイスに格納して下さい.

constraint_exclusion

  • デフォルト: off (PostgreSQL 8.4より前,8.4以上はpartitionに設定)

  • これは一般的にテーブルパーティショニングに使われます.PostgreSQL 8.4より前の場合は,"on"を設置して,クエリプランナに対して,求めるような最適化をさせます.8.4の場合は"partition"がデフォルトです.継承された階層の中にあり,プランナに他のペナルティを与えない場合は,プランナに制限を考慮したテーブル解析を強制します.PostgreSQL 8.4以上では,こちらが理想的になります.

shared_buffers

  • デフォルト: 32MB以下

  • 使用可能なRAMの1/3から3/4程度を設定します.

6.4.2. 実行時

work_mem (ソート処理や複雑なクエリに使われるメモリ)

  • デフォルト: 1MB

  • 大きなデータベース,複雑なクエリ,RAMが多い場合には上げます.

  • 同時使用が多数,またはRAMが少ない場合には下げます.

  • 多数のRAMを持ち,開発者が少数なら,次のようにします.

                        SET work_mem TO 1200000;
                    

maintenance_work_mem (VACUUM, CREATE INDEX 等で使用)

  • デフォルト: 16MB

  • 通常では低すぎます - メモリのスワップの間,入出力を縛り,オブジェクトをロックします.

  • 32MBから256MBが推奨です. 接続ユーザ数に依存します. 多数のRAMを持ち開発者が少ない場合は次のようにします.

                        SET maintainence_work_mem TO 1200000;
                    

第7章 PostGISリファレンス

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

[注意]

PostGISは,既存の名前付け方針からSQL-MM中心の方針への切り替えを開始しています.結果として,ユーザが知っていて愛用している関数の多くが標準空間型(ST)プレフィクスを使うように名前変更されました.以前の関数はまだ有効ですが,更新された等価な関数があるものについては,この文書の一覧から外しています.これらの関数は,将来のリリースでは非推奨になりますので,*使わないでください*.

7.1. PostgreSQLのPostGIS型

概要

本節では,PostGISによってインストールされたPostgreSQLデータ型を示します. 特にユーザ定義関数をデザインする際に大変重要なキャストのふるまいを記載しています.

ある型が他の型に強制されることをキャストといいます. PostgreSQLは,ほとんどのデータベースと異なり,カスタム型のキャストとキャストのために使われる関数のためのキャストに関するふるまいを定義することができます.キャストは自動的に指定することができます.この場合は,otherfootypeでしか動作しない関数にmyfooを送った場合で,自動キャストがそこにある場合には,CAST(myfoo AS otherfootype)やmyfoo::otherfootypeというものを必要としません.

自動キャストのふるまいに頼る危険性は,関数をオーバロードするときに出てきます.たとえば,box2dを取るものとbox3dとをとるがジオメトリをとらないとします.どちらの関数とも,ジオメトリは両方に自動キャストするので,ジオメトリを使って良いです.-- しかし,あいまいな関数エラーで終わります.PostgreSQLに強制的に選択させるために,CAST(mygeom As box3d)またはmygeom::box3dを実行します.

[注意]
少なくともPostgreSQL 8.3では,全て文字列にキャストできます(おそらく,不思議な未知の型のためです).オブジェクトを文字列にキャストするために表現するキャストの定義は必要ありません.
box2d — xmin, ymin, xmax, ymaxで作られるボックス.しばしばジオメトリを囲む二次元のボックスを返すために使われます.
box3d — xmin, ymin, zmin, xmax, ymax, zmaxで作られるボックス.しばしばジオメトリやジオメトリのコレクションの三次元範囲を返します.
box3d_extent — xmin, ymin, zmin, xmax, ymax, zmaxで作られるボックス.しばしばジオメトリの範囲を返すために使われます.
geometry — 平面空間データ型
geometry_dump — geom(ジオメトリオブジェクトを保持)とpath[](ダンプされたオブジェクト内のジオメトリの位置を保持する1次元配列)の,二つのフィールドを持つ空間データ型.
geography — 回転楕円体空間データ型

名前

box2d — xmin, ymin, xmax, ymaxで作られるボックス.しばしばジオメトリを囲む二次元のボックスを返すために使われます.

説明

box2sは,ジオメトリを囲むボックスを表現するために使われる空間データ型です.PostGIS 1.4より前の版ではST_Extentはbox2dを返しました.


名前

box3d — xmin, ymin, zmin, xmax, ymax, zmaxで作られるボックス.しばしばジオメトリやジオメトリのコレクションの三次元範囲を返します.

説明

ジオメトリやジオメトリの集合を囲むボックスを表現するために使われるPostGIS空間データ型です.ST_Extent3Dはbox3dオブジェクトを返します.

キャストのふるまい

本節ではこのデータ型に許される自動キャストと明示キャストの一覧を挙げます.

キャスト先 ふるまい
box 自動
box2d 自動
geometry 自動

名前

box3d_extent — xmin, ymin, zmin, xmax, ymax, zmaxで作られるボックス.しばしばジオメトリの範囲を返すために使われます.

説明

box3d_extent は,ST_Extentが返すデータ型です.PostGIS 1.4より前では,ST_Extentはbox2dを返していました.

キャストのふるまい

本節ではこのデータ型に許される自動キャストと明示キャストの一覧を挙げます.

キャスト先 ふるまい
box2d 自動
box3d 自動
geometry 自動

名前

geometry — 平面空間データ型

説明

geometryはPostGIS空間データ型の基本で,ユークリッド座標系でのフィーチャー表現に使われます.

キャストのふるまい

本節ではこのデータ型に許される自動キャストと明示キャストの一覧を挙げます.

キャスト先 ふるまい
box 自動
box2d 自動
box3d 自動
bytea 自動
geography 自動
text 自動

名前

geometry_dump — geom(ジオメトリオブジェクトを保持)とpath[](ダンプされたオブジェクト内のジオメトリの位置を保持する1次元配列)の,二つのフィールドを持つ空間データ型.

説明

geometry_dumpはgeomフィールドで参照するジオメトリオブジェクトと1次元整数配列のpath[](1始まりで,path[1]が最初の要素)からなる複合データ型です. ST_Dump*族の関数に使われます.これらの関数は複雑なジオメトリを複数の構成部品とその位置に分解します.


名前

geography — 回転楕円体空間データ型

説明

geographyは球面座標系でのフィーチャー表現に使われる空間データ型です.

キャストのふるまい

本節ではこのデータ型に許される自動キャストと明示キャストの一覧を挙げます.

キャスト先 ふるまい
geometry 明示

7.2. 管理関数

AddGeometryColumn — ジオメトリカラムを既存の属性テーブルに追加します.
DropGeometryColumn — ジオメトリカラムを空間テーブルから除去します.
DropGeometryTable — テーブルとgeometry_columnsの当該テーブルへの参照を削除します.
PostGIS_Full_Version — 完全なPostGISのバージョン情報とコンフィギュレーション情報を報告します.
PostGIS_GEOS_Version — GEOSライブラリのバージョン番号を返します.
PostGIS_LibXML_Version — libxml2のバージョン番号を返します.
PostGIS_Lib_Build_Date — PostGISライブラリのビルド日付を返します.
PostGIS_Lib_Version — PostGISのバージョン番号を返します.
PostGIS_PROJ_Version — PROJ4のバージョン番号を返します.
PostGIS_Scripts_Build_Date — PostGISスクリプトのビルド日付を返します.
PostGIS_Scripts_Installed — このデータベースにインストールしたPostGISスクリプトのバージョン番号を返します.
PostGIS_Scripts_Released — インストールしたPostGISライブラリとともにリリースされたpostgis.sqlスクリプトのバージョン番号を返します.
PostGIS_Uses_Stats — STATS使用が有効な場合にTRUEを返します.
PostGIS_Version — PostGISバージョン番号とコンパイルオプションを返します.
Populate_Geometry_Columns — ジオメトリカラムが適切な空間制限を持ち,geometry_columnsテーブルに存在することを確実にします.
Probe_Geometry_Columns — 全てのテーブルのPostGISジオメトリ制限を走査し,geometry_columnsテーブルに存在しない場合は追加を行います.
UpdateGeometrySRID — ジオメトリカラムの全てのフィーチャーのSRID,geometry_columnsメタデータとSRIDテーブル制限を更新します.

名前

AddGeometryColumn — ジオメトリカラムを既存の属性テーブルに追加します.

概要

text AddGeometryColumn(varchar table_name, varchar column_name, integer srid, varchar type, integer dimension);

text AddGeometryColumn(varchar schema_name, varchar table_name, varchar column_name, integer srid, varchar type, integer dimension);

text AddGeometryColumn(varchar catalog_name, varchar schema_name, varchar table_name, varchar column_name, integer srid, varchar type, integer dimension);

説明

ジオメトリカラムを既存の属性テーブルに追加します. schema_nameはスキーマ名(プリスキーマ版PostgreSQLの場合は使われません) sridはSPATIAL_REF_SYSテーブルのエントリを参照する整数でなければなりません. typeは'POLYGON'や'MULTILINESTRING'といった,ジオメトリ型を示す大文字でなければなりません. 指定したスキーマが存在しない(または現在のsearch_pathからは見えない)場合,または指定したSRID,ジオメトリ型もしくは次元が不正である場合はエラーが投げられます.

[注意]

ビューや派生的に生成された空間テーブルは,geometry_columnsへの登録を手動で行う必要があります. AddGeometryColumnは既に空間カラムが存在している時に必要が無い空間カラムも追加するためです. 「 手動でジオメトリカラムをgeometry_columnsに登録する 」をご覧ください.

このメソッドは OpenGIS Simple Features Implementation Specification for SQL 1.1.を実装するものです.

この関数は三次元をサポートします.Zインデクスを削除しません.

このメソッドは曲線ストリングと曲線をサポートします.

-- 単純なPostgreSQLテーブルを生成
postgis=# CREATE TABLE my_schema.my_spatial_table (id serial);

-- "id"カラムのみ存在する単純なテーブル内容を表示
postgis=# \d my_schema.my_spatial_table
							 Table "my_schema.my_spatial_table"
 Column |  Type   |                                Modifiers
--------+---------+-------------------------------------------------------------------------
 id     | integer | not null default nextval('my_schema.my_spatial_table_id_seq'::regclass)

-- 空間カラムをテーブルに追加
postgis=# SELECT AddGeometryColumn ('my_schema','my_spatial_table','the_geom',4326,'POINT',2);

--曲線ポリゴンを追加
SELECT AddGeometryColumn ('my_schema','my_spatial_table','the_geomcp',4326,'CURVEPOLYGON',2);

-- テーブル内容の再表示して新しく"the_geom"カラムが追加されたことを確認
postgis=# \d my_schema.my_spatial_table
   Column   |   Type   |                                Modifiers

------------+----------+-------------------------------------------------------------------------
 id         | integer  | not null default nextval('my_schema.my_spatial_table_id_seq'::regclass)
 the_geom   | geometry |
 the_geomcp | geometry |
Check constraints:
	"enforce_dims_the_geom" CHECK (ndims(the_geom) = 2)
	"enforce_dims_the_geomcp" CHECK (ndims(the_geomcp) = 2)
	"enforce_geotype_the_geom" CHECK (geometrytype(the_geom) = 'POINT'::text OR
the_geom IS NULL)
	"enforce_geotype_the_geomcp" CHECK (geometrytype(the_geomcp) = 'CURVEPOLYGON
'::text OR the_geomcp IS NULL)
	"enforce_srid_the_geom" CHECK (srid(the_geom) = 4326)
	"enforce_srid_the_geomcp" CHECK (srid(the_geomcp) = 4326)

名前

DropGeometryColumn — ジオメトリカラムを空間テーブルから除去します.

概要

text DropGeometryColumn(varchar table_name, varchar column_name);

text DropGeometryColumn(varchar schema_name, varchar table_name, varchar column_name);

text DropGeometryColumn(varchar catalog_name, varchar schema_name, varchar table_name, varchar column_name);

説明

ジオメトリカラムを空間テーブルから除去します.schema_nameはgeometry_columnsテーブルの該当行のf_table_schemaフィールドと一致しなければなりませんのでご注意ください.

このメソッドは OpenGIS Simple Features Implementation Specification for SQL 1.1.を実装するものです.

この関数は三次元をサポートします.Zインデクスを削除しません.

このメソッドは曲線ストリングと曲線をサポートします.

			SELECT DropGeometryColumn ('my_schema','my_spatial_table','the_geomcp');
			----RESULT output ---
			my_schema.my_spatial_table.the_geomcp effectively removed.
		

名前

DropGeometryTable — テーブルとgeometry_columnsの当該テーブルへの参照を削除します.

概要

boolean DropGeometryTable(varchar table_name);

boolean DropGeometryTable(varchar schema_name, varchar table_name);

boolean DropGeometryTable(varchar catalog_name, varchar schema_name, varchar table_name);

説明

テーブルとgeometry_columnsの当該テーブルへの参照を削除します.スキーマ対応版PostgreSQLではスキーマが与えられない場合はcurrent_schema()を使います.

			SELECT DropGeometryTable ('my_schema','my_spatial_table');
			----RESULT output ---
			my_schema.my_spatial_table dropped.
		

名前

PostGIS_Full_Version — 完全なPostGISのバージョン情報とコンフィギュレーション情報を報告します.

概要

text PostGIS_Full_Version();

説明

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

SELECT PostGIS_Full_Version();
							   postgis_full_version
----------------------------------------------------------------------------------
 POSTGIS="1.3.3" GEOS="3.1.0-CAPI-1.5.0" PROJ="Rel. 4.4.9, 29 Oct 2004" USE_STATS
(1 row)

名前

PostGIS_GEOS_Version — GEOSライブラリのバージョン番号を返します.

概要

text PostGIS_GEOS_Version();

説明

GEOSライブラリのバージョン番号を返します.GEOSサポートが有効でない場合はNULLを返します.

SELECT PostGIS_GEOS_Version();
 postgis_geos_version
----------------------
 3.1.0-CAPI-1.5.0
(1 row)

名前

PostGIS_LibXML_Version — libxml2のバージョン番号を返します.

概要

text PostGIS_LibXML_Version();

説明

初出バージョン: 1.5

SELECT PostGIS_LibXML_Version();
 postgis_libxml_version
----------------------
 2.7.6
(1 row)

名前

PostGIS_Lib_Build_Date — PostGISライブラリのビルド日付を返します.

概要

text PostGIS_Lib_Build_Date();

説明

PostGISライブラリのビルド日付を返します.

SELECT PostGIS_Lib_Build_Date();
 postgis_lib_build_date
------------------------
 2008-06-21 17:53:21
(1 row)

名前

PostGIS_Lib_Version — PostGISのバージョン番号を返します.

概要

text PostGIS_Lib_Version();

説明

PostGISのバージョン番号を返します.

SELECT PostGIS_Lib_Version();
 postgis_lib_version
---------------------
 1.3.3
(1 row)

名前

PostGIS_PROJ_Version — PROJ4のバージョン番号を返します.

概要

text PostGIS_PROJ_Version();

説明

PROJ4のバージョン番号を返します.PROJ4サポートが有効でない場合はNULLを返します.

SELECT PostGIS_PROJ_Version();
  postgis_proj_version
-------------------------
 Rel. 4.4.9, 29 Oct 2004
(1 row)

名前

PostGIS_Scripts_Build_Date — PostGISスクリプトのビルド日付を返します.

概要

text PostGIS_Scripts_Build_Date();

説明

PostGISスクリプトのビルド日付を返します.

初出バージョン: 1.0.0RC1

SELECT PostGIS_Scripts_Build_Date();
  postgis_scripts_build_date
-------------------------
 2007-08-18 09:09:26
(1 row)

名前

PostGIS_Scripts_Installed — このデータベースにインストールしたPostGISスクリプトのバージョン番号を返します.

概要

text PostGIS_Scripts_Installed();

説明

このデータベースにインストールしたPostGISスクリプトのバージョン番号を返します.

[注意]

この関数の出力がPostGIS_Scripts_Releasedと合わない場合,既存のデータベースの確実なアップグレードに失敗しているかも知れません.詳細情報についてはアップグレードをご覧ください.

初出バージョン: 0.9.0

SELECT PostGIS_Scripts_Installed();
  postgis_scripts_installed
-------------------------
 1.5.0SVN
(1 row)

名前

PostGIS_Scripts_Released — インストールしたPostGISライブラリとともにリリースされたpostgis.sqlスクリプトのバージョン番号を返します.

概要

text PostGIS_Scripts_Released();

説明

インストールしたPostGISライブラリとともにリリースされたpostgis.sqlスクリプトのバージョン番号を返します.

[注意]

1.1.0からこの関数はPostGIS_Lib_Versionと同じ値を返すようになりました.後方互換のためです.

初出バージョン: 0.9.0

SELECT PostGIS_Scripts_Released();
  postgis_scripts_released
-------------------------
 1.3.4SVN
(1 row)

名前

PostGIS_Uses_Stats — STATS使用が有効な場合にTRUEを返します.

概要

text PostGIS_Uses_Stats();

説明

STATS使用が有効な場合にTRUEを返し,有効でない場合にFALSEを返します.

SELECT PostGIS_Uses_Stats();
 postgis_uses_stats
--------------------
 t
(1 row)

関連情報

PostGIS_Version


名前

PostGIS_Version — PostGISバージョン番号とコンパイルオプションを返します.

概要

text PostGIS_Version();

説明

PostGISバージョン番号とコンパイルオプションを返します.

SELECT PostGIS_Version();
			postgis_version
---------------------------------------
 1.3 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
(1 row)

名前

Populate_Geometry_Columns — ジオメトリカラムが適切な空間制限を持ち,geometry_columnsテーブルに存在することを確実にします.

概要

text Populate_Geometry_Columns();

int Populate_Geometry_Columns(oid relation_oid);

説明

ジオメトリカラムが適切な空間制限を持ち,geometry_columnsテーブルに存在することを確実にします. これによって,特に,テーブルに属するどのジオメトリカラムも,少なくとも次に示す三つの制限を持ちます.

  • enforce_dims_the_geom - 全てのジオメトリが同じ次元をもつようにします(ST_NDims参照).

  • enforce_geotype_the_geom - 全てのジオメトリが同じ型を持つようにします(GeometryType参照).

  • enforce_srid_the_geom - 全てのジオメトリが同じ投影法になるようにしますST_SRID()

テーブルoidが引数で渡される場合,この関数は,必要な制限を加えて,テーブル内の全てのカラムのSRID,次元,ジオメトリ型を決定しようとします.成功した場合,適切な行がgeometry_columnsに挿入されます.成功しなかった場合,例外が捕まり,問題を説明するエラー通知が上がります.

ビューのoidがテーブルoidとして引数で渡される場合,この関数は,適切な登録をgeometry_columnsに挿入して,ビュー内の全てのジオメトリのSRID,次元,ジオメトリ型を決定しようとします.しかし,制限の強制は行いません.

パラメータが無い場合は,パラメータ有りの場合のラッパで,まずgeometry_columnsテーブルの中身を消去してデータベース内のテーブルやビューの情報を集めなおします. データベース内で検出したジオメトリカラムの数とgeometry_colymnsに挿入された数のサマリが返ります. パラメータ有りの場合はgeometry_columnsテーブルに挿入された行の数だけが返ります.

初出バージョン: 1.4.0

SELECT Populate_Geometry_Columns('public.myspatial_table'::regclass);

名前

Probe_Geometry_Columns — 全てのテーブルのPostGISジオメトリ制限を走査し,geometry_columnsテーブルに存在しない場合は追加を行います.

概要

text Probe_Geometry_Columns();

説明

全てのテーブルのPostGISジオメトリ制限を走査し,geometry_columnsテーブルに存在しない場合は追加を行います.そのうえで,挿入した数,既に存在していた数,廃止された数の統計を返します. 既に

[注意]

これは通常,AddGeometryColumns()関数で追加されたレコードを取り上げるだけです. ビューは手動でgeometry_columnsテーブルに追加する必要があるため,走査しません.

SELECT Probe_Geometry_Columns();
			probe_geometry_columns
---------------------------------------
probed:6 inserted:0 conflicts:6 stale:0
(1 row)

関連情報

AddGeometryColumn


名前

UpdateGeometrySRID — ジオメトリカラムの全てのフィーチャーのSRID,geometry_columnsメタデータとSRIDテーブル制限を更新します.

概要

text UpdateGeometrySRID(varchar table_name, varchar column_name, integer srid);

text UpdateGeometrySRID(varchar schema_name, varchar table_name, varchar column_name, integer srid);

text UpdateGeometrySRID(varchar catalog_name, varchar schema_name, varchar table_name, varchar column_name, integer srid);

説明

ジオメトリカラムの全てのフィーチャーのSRID,geometry_columnsメタデータとSRIDテーブル制限を更新します. ご注意: スキーマ名が与えられていない場合,スキーマ対応版PostgreSQLではcurrent_schema()を使用します.

この関数は三次元をサポートします.Zインデクスを削除しません.

このメソッドは曲線ストリングと曲線をサポートします.

関連情報

ST_SetSRID

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

ST_BdPolyFromText — MultiLineStringのWell-Known text表現による任意の閉じたラインストリングのコレクション与えられたポリゴンを生成します.
ST_BdMPolyFromText — MultiLineStringのWell-Known text表現による任意の閉じたラインストリングのコレクション与えられたマルチポリゴンを生成します.
ST_GeogFromText — Well-Known Text表現または拡張WKTから指定したジオグラフィ値を返します.
ST_GeographyFromText — Well-Known Text表現または拡張WKTから指定したジオグラフィ値を返します.
ST_GeogFromWKB — Well-Known Binaryジオメトリ表現(WKB)または拡張WKB(EWKB)からジオグラフィインスタンスを生成します.
ST_GeomCollFromText — ジオメトリのコレクションをWKTのコレクションと与えられたSRIDから生成します.SRIDが与えられていない場合は-1とします.
ST_GeomFromEWKB — 拡張Well-Known Binary表現(EWKB)から指定したST_Geometry値を返します.
ST_GeomFromEWKT — 拡張Well-Known Text表現(EWKT)から指定されたST_Geometry値を返します.
ST_GeometryFromText — Well-Knwon Text表現(WKT)から指定したST_Geometry値を返します.これはST_GeomFromTextの別名です.
ST_GeomFromGML — ジオメトリのGML表現を入力とし,PostGISジオメトリオブジェクトを出力します.
ST_GeomFromKML — ジオメトリのKML表現の入力をとり,PostGISジオメトリオブジェクトを出力します.
ST_GMLToSQL — GML表現から指定したST_Geometry値を返します.これはST_GeomFromGMLの別名です.
ST_GeomFromText — Well-Known Text表現(WKT)から指定したST_Geometryを返します.
ST_GeomFromWKB — Well-Knwon Binaryジオメトリ表現(WKB)とSRIDオプションからジオメトリインスタンスを生成します.
ST_LineFromMultiPoint — LINESTRINGをMULTIPOINTから生成します.
ST_LineFromText — WKT表現と与えられたSRIDからジオメトリを生成します.SRIDが与えられていない場合は-1(不明)となります.
ST_LineFromWKB — WKB表現と与えられたSRIDからLINESTRINGを生成します.
ST_LinestringFromWKB — WKB表現と与えられたSRIDからジオメトリを生成します.
ST_MakeBox2D — 与えられたポイントジオメトリから定義されるBOX2Dを生成します.
ST_MakeBox3D — 与えられた三次元ポイントジオメトリから定義されるBOX3Dを生成します.
ST_MakeLine — ポイントジオメトリからラインストリングを生成します.
ST_MakeEnvelope — 与えられた最小値と最大値から長方形ポリゴンを生成します.入力値はSRIDで指定されたSRSでなければなりません.
ST_MakePolygon — 与えられた環で形成されるポリゴンを生成します.入力ジオメトリは閉じたラインストリングでなければなりません.
ST_MakePoint — 二次元,XYZの三次元,四次元のポイントジオメトリを生成します.
ST_MakePointM — X, Y, M座標を持つポイントジオメトリを生成します.
ST_MLineFromText — WKT表現から指定したST_MultiLineString値を返します.
ST_MPointFromText — Well-Known Text(WKT)表現と与えられたSRIDからジオメトリを生成します.SRIDを与えない場合は-1(不明)となります.
ST_MPolyFromText — Well-Known Text(WKT)表現と与えられたSRIDからマルチポリゴンを生成します.SRIDを与えない場合は-1(不明)となります.
ST_Point — 与えられた座標値のST_Pointを返します.ST_MakePointのOGC別名です.
ST_PointFromText — WKTと与えられたSRIDからポイントジオメトリを生成します.SRIDが与えられていない場合は-1(不明)とします.
ST_PointFromWKB — WKBと与えられたSRIDからジオメトリを生成します.
ST_Polygon — 指定されたラインストリングとSRIDからポリゴンを生成します.
ST_PolygonFromText — WKTと与えられたSRIDからジオメトリを生成します.SRIDが与えられていない場合は-1(不明)とします.
ST_WKBToSQL — Well-Known Binary表現(WKB)からST_Geometry値を生成します.これはSRIDを取らないST_GeomFromWKBの別名です.
ST_WKTToSQL — Well-Known Text表現(WKT)からST_Geometry値を生成します.これはSRIDを取らないST_GeomFroTextの別名です.

名前

ST_BdPolyFromText — MultiLineStringのWell-Known text表現による任意の閉じたラインストリングのコレクション与えられたポリゴンを生成します.

概要

geometry ST_BdPolyFromText(text WKT, integer srid);

説明

MultiLineStringのWell-Known text表現による任意の閉じたラインストリングのコレクション与えられたポリゴンを生成します.

[注意]

WKTがMULTILINESTRINGでない場合エラーが投げられます.出力がMULTIPOLYGONの場合エラーが投げられますが,この場合はST_BdMPolyFromTextを使うかPostGIS独特のアプローチとしてST_BuildArea()をご覧ください.

このメソッドは OpenGIS Simple Features Implementation Specification for SQL 1.1.を実装するものです. s3.2.6.2

初出バージョン: 1.1.0 - GEOS >= 2.1.0 が必要です.

Forthcoming

名前

ST_BdMPolyFromText — MultiLineStringのWell-Known text表現による任意の閉じたラインストリングのコレクション与えられたマルチポリゴンを生成します.

概要

geometry ST_BdMPolyFromText(text WKT, integer srid);

説明

MultiLineStringのWell-Known text表現による任意の閉じたラインストリングのコレクション与えられたマルチポリゴンを生成します.

[注意]

WKTがMULTILINESTRINGでない場合エラーが投げられます.出力が単一のポリゴンであってもマルチポリゴンに強制されます.単一のポリゴンが返って欲しい場合はST_BdPolyFromTextを使うかPostGIS独特のアプローチとしてST_BuildArea()をご覧ください.

このメソッドは OpenGIS Simple Features Implementation Specification for SQL 1.1.を実装するものです. s3.2.6.2

初出バージョン: 1.1.0 - GEOS >= 2.1.0 が必要です.

Forthcoming

名前

ST_GeogFromText — Well-Known Text表現または拡張WKTから指定したジオグラフィ値を返します.

概要

geography ST_GeogFromText(text EWKT);

説明

Well-Known Text表現または拡張WKTから指定したジオグラフィ値を返します.SRID 4326を仮定します.この関数はST_GeographyFromTextの別名です.


名前

ST_GeographyFromText — Well-Known Text表現または拡張WKTから指定したジオグラフィ値を返します.

概要

geography ST_GeographyFromText(text EWKT);

説明

Well-Known Text表現または拡張WKTから指定したジオグラフィ値を返します.SRID 4326を仮定します.

関๩