PostGIS 3.4.0dev マニュアル

DEV (Sun 02 Oct 2022 02:04:41 AM UTC rev. 23c99aa )

PostGIS開発グループ

Abstract

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

本マニュアルは、3.4.0dev版のマニュアルです。

この作品はクリエイティブ・コモンズ 表示 - 継承 3.0 非移植 ライセンスの下に提供されています。好きなようにこの材料を使うことができますが、PostGIS Project のクレジット提示を求めます。また可能な限りhttp://postgis.netへのリンクを求めます。


Table of Contents
1. 導入
1.1. プロジェクト運営委員会
1.2. 現在の中核貢献者
1.3. 過去の中核貢献者
1.4. 他の貢献者
2. PostGISインストール
2.1. 簡略版
2.2. ソースからのコンパイルとインストール
2.2.1. ソースの取得
2.2.2. インストール要件
2.2.3. コンフィギュレーション
2.2.4. ビルド
2.2.5. PostGISエクステンションのビルドとデプロイ
2.2.6. テスト
2.2.7. インストール
2.3. PAGC住所標準化ツールのインストールと使用
2.3.1. Regex::Assembleのインストール
2.4. Tigerジオコーダのインストールとアップグレードとデータロード
2.4.1. TigerジオコーダをPostGISデータベースで有効にする: エクステンションを使用
2.4.2. TigerジオコーダをPostGISデータベースで有効にする: エクステンション不使用
2.4.3. TigerジオコーダをPostGISデータベースで有効にする: エクステンションを使用
2.4.4. Tigerデータのロード
2.4.5. Tigerジオコーダのアップグレード
2.5. 共通の問題
3. PostGIS管理
3.1. パフォーマンスチューニング
3.1.1. 起動時
3.1.2. 実行時
3.2. ラスタ機能の設定
3.3. 空間データベースの作成
3.3.1. エクステンションを使って空間データベースを有効にする
3.3.2. エクステンションを使わずに空間データベースを有効にする (お勧めできません)
3.3.3. 空間データベースをテンプレートから生成する
3.4. 空間データベースのアップグレード
3.4.1. ソフトアップグレード
3.4.2. ハードアップグレード
4. データ管理
4.1. 空間データ モデル
4.1.1. OGC ジオメトリ
4.1.2. SQL/MM Part 3 - 曲線
4.1.3. WKTとWKB
4.2. ジオメトリデータタイプ
4.2.1. PostGIS EWKBとEWKT
4.3. ジオグラフィデータタイプ
4.3.1. ジオグラフィテーブルの生成
4.3.2. ジオグラフィテーブルの使用
4.3.3. ジオグラフィ型を使用すべき時
4.3.4. ジオグラフィに関する高度なよくある質問
4.4. ジオメトリ検証
4.4.1. 単純ジオメトリ
4.4.2. 妥当なジオメトリ
4.4.3. 妥当性の管理
4.5. 空間参照系
4.5.1. SPATIAL_REF_SYSテーブル
4.5.2. ユーザ定義空間参照系
4.6. 空間テーブル
4.6.1. 空間テーブルを作る
4.6.2. GEOMETRY_COLUMNSビュー
4.6.3. 手動でジオメトリカラムをgeometry_columnsに登録する
4.7. 空間データのロード
4.7.1. SQLを使ってロードする
4.7.2. シェープファイルローダを使う
4.8. 空間データの抽出
4.8.1. SQLを使ってデータを抽出する
4.8.2. ダンパを使う
4.9. 空間インデックス
4.9.1. GiSTインデックス
4.9.2. BRINインデックス
4.9.3. SP-GiSTインデックス
4.9.4. インデックス使用のチューニング
5. 空間クエリ
5.1. 空間関係の決定
5.1.1. Dimensionally Extended 9-Intersection Model
5.1.2. 名前付き空間関係
5.1.3. 一般的な空間関係
5.2. 空間インデックスを使う
5.3. 空間SQLの例
6. 性能向上に関する技法
6.1. 大きなジオメトリを持つ小さなテーブル
6.1.1. 問題の説明
6.1.2. 応急処置
6.2. ジオメトリインデクスでCLUSTERを実行する
6.3. 次元変換の回避
7. アプリケーションのビルド
7.1. MapServerを使う
7.1.1. 基本的な使い方
7.1.2. よくある質問
7.1.3. 踏み込んだ使用法
7.1.4. 例
7.2. Javaクライアント (JDBC)
7.3. Cクライアント (libpq)
7.3.1. テキストカーソル
7.3.2. バイナリカーソル
8. PostGISリファレンス
8.1. PostGIS Geometry/Geography/Box データ型
8.2. テーブル管理関数
8.3. ジオメトリ コンストラクタ
8.4. ジオメトリアクセサ
8.5. ジオメトリエディタ
8.6. ジオメトリ検証
8.7. 空間参照系関数
8.8. ジオメトリ入力
8.8.1. Well-Known Text (WKT)
8.8.2. Well-Known Binary (WKB)
8.8.3. その他の書式
8.9. ジオメトリ出力
8.9.1. Well-Known Text (WKT)
8.9.2. Well-Known Binary (WKB)
8.9.3. その他の書式
8.10. 演算子
8.10.1. バウンディングボックス演算子
8.10.2. 距離演算子
8.11. 空間関係関数
8.11.1. トポロジ関係関数
8.11.2. 距離関係関数
8.12. 計測関数
8.13. 重ね合わせ関数
8.14. ジオメトリ処理関数
8.15. アフィン変換
8.16. クラスタリング関数
8.17. バウンディングボックス関数
8.18. 線型参照
8.19. トラジェクトリ関数
8.20. SFCGAL関数
8.21. ロングトランザクション機能
8.22. バージョン関数
8.23. Grand Unified Custom変数 (GUC)
8.24. トラブルシューティング関数
9. PostGIS よくある質問
10. トポロジ
10.1. トポロジ型
10.2. トポロジドメイン
10.3. トポロジ管理とTopoGeometry管理
10.4. トポロジ統計管理
10.5. トポロジコンストラクタ
10.6. トポロジエディタ
10.7. トポロジアクセサ
10.8. トポロジ処理
10.9. TopoGeometryコンストラクタ
10.10. TopoGeometryエディタ
10.11. TopoGeometryアクセサ
10.12. TopoGeometry出力
10.13. トポロジ空間関係関数
10.14. トポロジのインポートとエクスポート
10.14.1. トポロジエクスポータの使用
10.14.2. トポロジインポータの使用
11. ラスタデータの管理、クエリ、アプリケーション
11.1. ラスタのロードと生成
11.1.1. raster2pgsqlを使ってラスタをロードする
11.1.2. PostGISラスタ関数を用いたラスタの生成
11.1.3. 「データベース外」クラウドラスタの使用
11.2. ラスタカタログ
11.2.1. ラスタカラムカタログ
11.2.2. ラスタオーバビュー
11.3. PostGISラスタを使ったカスタムアプリケーションの構築
11.3.1. ST_AsPNG を他の関数とあわせて使った PHP 出力例
11.3.2. ST_AsPNGを他の関数とあわせて使ったASP.NET C#出力例
11.3.3. rasterクエリを画像ファイルで出力するJavaコンソールアプリケーション
11.3.4. PLPython を使って SQL を介して画像をダンプする
11.3.5. PSQLでラスタを出力する
12. ラスタ リファレンス
12.1. ラスタサポートデータ型
12.2. ラスタ管理
12.3. ラスタコンストラクタ
12.4. ラスタアクセサ
12.5. ラスタバンドアクセサ
12.6. ラスタピクセルアクセサとセッター
12.7. ラスタエディタ
12.8. ラスタバンドエディタ
12.9. ラスタバンド統計情報と解析
12.10. ラスタ入力
12.11. 出力
12.12. ラスタ処理: 地図代数
12.13. 組み込み地図代数コールバック関数
12.14. ラスタ処理: DEM (標高)
12.15. ラスタ処理: ラスタからジオメトリ
12.16. ラスタ演算子
12.17. ラスタとラスタバンドの空間関係関数
12.18. ラスタに関する技法
12.18.1. データベース外ラスタ
13. PostGISラスタ よくある質問
14. PostGIS追加機能
14.1. 住所標準化
14.1.1. パーサの動作
14.1.2. 住所標準化の型
14.1.3. 住所標準化テーブル
14.1.4. 住所標準化関数
14.2. Tigerジオコーダ
15. PostGIS Special Functions Index
15.1. PostGIS Aggregate Functions
15.2. PostGIS Window Functions
15.3. PostGIS SQL-MM Compliant Functions
15.4. PostGIS Geography Support Functions
15.5. PostGIS Raster Support Functions
15.6. PostGIS Geometry / Geography / Raster Dump Functions
15.7. PostGIS Box Functions
15.8. PostGIS Functions that support 3D
15.9. PostGIS Curved Geometry Support Functions
15.10. PostGIS Polyhedral Surface Support Functions
15.11. PostGIS Function Support Matrix
15.12. New, Enhanced or changed PostGIS Functions
15.12.1. PostGIS Functions new or enhanced in 3.3
15.12.2. PostGIS Functions new or enhanced in 3.2
15.12.3. PostGIS Functions new or enhanced in 3.1
15.12.4. PostGIS Functions new or enhanced in 3.0
15.12.5. PostGIS Functions new or enhanced in 2.5
15.12.6. PostGIS Functions new or enhanced in 2.4
15.12.7. PostGIS Functions new or enhanced in 2.3
15.12.8. PostGIS Functions new or enhanced in 2.2
15.12.9. PostGIS functions breaking changes in 2.2
15.12.10. PostGIS Functions new or enhanced in 2.1
15.12.11. PostGIS functions breaking changes in 2.1
15.12.12. PostGIS Functions new, behavior changed, or enhanced in 2.0
15.12.13. PostGIS Functions changed behavior in 2.0
15.12.14. PostGIS Functions new, behavior changed, or enhanced in 1.5
15.12.15. PostGIS Functions new, behavior changed, or enhanced in 1.4
15.12.16. PostGIS Functions new in 1.3
16. 問題を報告する
16.1. ソフトウェアのバグを報告する
16.2. 文書の問題を報告する
A. 付録
A.1. PostGIS 3.3.0
A.2. PostGIS 3.3.0rc2
A.3. PostGIS 3.3.0rc1
A.4. PostGIS 3.3.0beta2
A.5. PostGIS 3.3.0beta1
A.6. PostGIS 3.3.0alpha1
A.7. PostGIS 3.2.0 (Olivier Courtin版)
A.8. PostGIS 3.2.0beta3
A.9. リリース 3.2.0beta2
A.10. リリース 3.2.0beta1
A.11. リリース 3.2.0alpha1
A.12. リリース 3.1.0beta1
A.13. リリース 3.1.0alpha3
A.14. リリース 3.1.0alpha2
A.15. リリース 3.1.0alpha1
A.16. リリース 3.0.0
A.17. リリース 3.0.0rc2
A.18. リリース 3.0.0rc1
A.19. リリース 3.0.0beta1
A.20. リリース 3.0.0alpha4
A.21. リリース 3.0.0alpha3
A.22. リリース 3.0.0alpha2
A.23. リリース 3.0.0alpha1
A.24. リリース 2.5.0
A.25. リリース 2.4.5
A.26. リリース 2.4.4
A.27. リリース 2.4.3
A.28. リリース 2.4.2
A.29. リリース 2.4.1
A.30. リリース 2.4.0
A.31. リリース 2.3.3
A.32. リリース 2.3.2
A.33. リリース 2.3.1
A.34. リリース 2.3.0
A.35. リリース 2.2.2
A.36. リリース 2.2.1
A.37. リリース 2.2.0
A.38. リリース 2.1.8
A.39. リリース 2.1.7
A.40. リリース 2.1.6
A.41. リリース 2.1.5
A.42. リリース 2.1.4
A.43. リリース 2.1.3
A.44. リリース 2.1.2
A.45. リリース 2.1.1
A.46. リリース 2.1.0
A.47. リリース 2.0.5
A.48. リリース 2.0.4
A.49. リリース 2.0.3
A.50. リリース 2.0.2
A.51. リリース 2.0.1
A.52. リリース 2.0.0
A.53. リリース 1.5.4
A.54. リリース 1.5.3
A.55. リリース 1.5.2
A.56. リリース 1.5.1
A.57. リリース 1.5.0
A.58. リリース 1.4.0
A.59. リリース 1.3.6
A.60. リリース 1.3.5
A.61. リリース 1.3.4
A.62. リリース 1.3.3
A.63. リリース 1.3.2
A.64. リリース 1.3.1
A.65. リリース 1.3.0
A.66. リリース 1.2.1
A.67. リリース 1.2.0
A.68. リリース 1.1.6
A.69. リリース 1.1.5
A.70. リリース 1.1.4
A.71. リリース 1.1.3
A.72. リリース 1.1.2
A.73. リリース 1.1.1
A.74. リリース 1.1.0
A.75. リリース 1.0.6
A.76. リリース 1.0.5
A.77. リリース 1.0.4
A.78. リリース 1.0.3
A.79. リリース 1.0.2
A.80. リリース 1.0.1
A.81. リリース 1.0.0
A.82. リリース 1.0.0RC6
A.83. リリース 1.0.0RC5
A.84. リリース 1.0.0RC4
A.85. リリース 1.0.0RC3
A.86. リリース 1.0.0RC2
A.87. リリース 1.0.0RC1

Chapter 1. 導入

PostGISは、PostgreSQLリレーショナルデータベースの空間拡張です。Refractions Research Incが、空間データベース技術の研究プロジェクトとして作成しました。Refractionsはカナダ・ブリティッシュコロンビア州・ビクトリアにある、データインテグレーションとカスタムソフトウェア開発に特化した、GISとデータベースのコンサルティング会社です。

PostGISは、現在ではOSGeo財団のプロジェクトです。多数のFOSS4G開発者とPostGISの機能と多彩さから大きな利益を得る世界中の企業が、PostGISの開発と資金提供を行っています。

PostGISプロジェクトの開発グループは、PostGISが、OGCとSQL/MM空間標準の領域における重要なGIS機能、高度なトポロジ構築 (カバレッジ、サーフェス、ネットワーク)、GISデータの表示と編集を行うデスクトップユーザインタフェースツールのデータソース、およびウェブベースのアクセスツールのためのデータソースに、より良く対応するよう、サポートと機能強化を行う予定です。

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

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

Raúl Marín Rodríguez

MVT機能、誤り修正、パフォーマンスと安定性の向上、GitHubキュレーション、PostGISとPostgreSQLのリリースの調整

Regina Obe

Buildbotのメンテナンス、Windows版と試験版のビルド、ドキュメンテーション、PostgreSQLとの調整、X3D対応、Tiger Geocoder機能、関数管理。

Darafei Praliaskouski

インデックス改善、誤り修正とジオメトリ/ジオグラフィ関数の改善、SFCGAL、ラスタ、GitHubキュレーション、Botのメンテナンス。

Paul Ramsey (委員長)

PostGISプロジェクトの副創始者。総合的なバグフィクス、ジオグラフィ機能、ジオグラフィとジオメトリのインデックス機能 (2次元,、3次元、n次元インデクスとあらゆる空間インデクス)、ジオメトリ内部構造、GEOS機能の統合とGEOSリリースとの調整、PostgreSQLのリリースとの調整、ローダ/ダンパ、シェープファイルGUIローダ。

Sandro Santilli

誤り修正とメンテナンス、ビルドボットのメンテナンス、gitミラーの管理、関数管理、GEOSの新機能の統合、GEOSリリースとの調整、トポロジ機能、ラスタフレームワークと低水準API関数。

1.2. 現在の中核貢献者

Nicklas Avén

距離関数の強化 (3次元距離、関係関数を含む)と追加、Tiny WKB出力書式(TWKB)と一般的なユーザサポート。

Dan Baston

ジオメトリクラスタリング関数の追加、他のジオメトリアルゴリズムの強化、GEOSの強化、および全体のユーザ対応

Martin Davis

GEOS機能強化と文書

Björn Harrtell

MapBox Vector Tile関数とGeoBuf関数、Gogsの試験とGitLabの実験。

Aliaksandr Kalenik

ジオメトリ処理、PostgreSQL GiST、共通部の誤り修正

1.3. 過去の中核貢献者

Bborie Park

以前のPSCメンバ。ラスタ開あh津、GDALとの統合、ラスタローダ、ユーザ対応、共通部の誤り修正、様々なOS (Slackware、Mac、Windows等多数)での試験

Mark Cave-Ayland

以前のPSCメンバ。誤り修正とメンテナンスの活動、空間インデックス選択性とバインディング、ローダ/ダンパ、およびシェープファイルGUIローダの調整、新機能の統合と強化。

Jorge Arévalo

ラスタ開発、GDALドライバ機能、ローダ。

Olivier Courtin

(名誉) XML (KML, GML)/GeoJSON入出力関数と3次元対応と誤り修正。

Chris Hodgson

以前のPSCメンバ。一般的な開発、サイトとBuildbotのメンテナンス、OSGeoインキュベーション管理。

Mateusz Loskot

CMakeのPostGISへの対応、Python版のオリジナルのラスタローダと低級ラスタAPI関数の構築。

Kevin Neufeld

以前のPSCメンバ。文書と文書補助ツール、Buildbotのメンテナンス、PostGISニュースグループでの高度なユーザサポート、PostGISメンテナンス機能の強化。

Dave Blasby

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

Jeff Lounsbury

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

Mark Leslie

中核機能の、継続的なメンテナンスと開発。曲線機能の強化。シェープファイルGUIローダ。

Pierre Racine

PostGISラスタ実装の設計。ラスタ全体のアーキテクチャ、プロトタイプ作成、プログラミング補助

David Zwarg

ラスタ開発 (ほとんど地図代数解析関数)。

1.4. 他の貢献者

個人

Alex BodnaruGreg TroxelMatt Bretl
Alex MayrhoferGuillaume LelargeMatthias Bay
Andrea PeriGiuseppe BroccoloMaxime Guillaud
Andreas Forø TollefsenHan WangMaxime van Noppen
Andreas NeumannHaribabu KommiMichael Fuhr
Andrew GierthHavard TveiteMike Toews
Anne GhislaIIDA TetsushiNathan Wagner
Antoine BajoletIngvild NystuenNathaniel Clay
Arthur LesuisseJackie LengNikita Shulga
Artur ZakirovJames MarcaNorman Vine
Barbara PhillipotJan KatinsPatricia Tozer
Ben JubbJason SmithRafal Magda
Bernhard ReiterJeff AdamsRalph Mason
Björn EsserJim JonesRémi Cura
Brian HamlinJoe ConwayRichard Greenwood
Bruce RindahlJonne SavolainenRoger Crew
Bruno Wolff IIIJose Carlos Martinez LlariRon Mayer
Bryce L. NordgrenJörg HabenichtSebastiaan Couwenberg
Carl AndersonJulien RouhaudSergei Shoulbakov
Charlie SavageKashif RasulSergey Fedoseev
Christoph BergKlaus FoersterShinichi Sugiyama
Christoph Moench-TegederKris JurkaShoaib Burq
Dane SpringmeyerLaurenz AlbeSilvio Grosso
Dave FuhryLars RoessigerStefan Corneliu Petrea
David GarnierLeo HsuSteffen Macke
David SkeaLoïc BartolettiStepan Kuzmin
David TecherLoic DacharyStephen Frost
Dmitry VasilyevLuca S. PercichSteven Ottens
Eduin CarrilloLucas C. Villa RealTalha Rizwan
Eugene AntimirovMaria Arias de ReynaTom Glancy
Even RouaultMarc DucobuTom van Tilburg
Frank WarmerdamMark SondheimVincent Mora
George SilvaMarkus SchaberVincent Picavet
Gerald FenoyMarkus WannerVolf Tomáš
Gino LucreziMatt Amos 

企業

これらは、PostGISプロジェクトに開発者の時間、ホスティング、または直接の資金提供のいずれかの貢献をした企業です。アルファベット順:

クラウドファンディングキャンペーン

クラウドファンディングキャンペーンは、PostGIS開発チームが走らせているキャンペーンです。欲しくて仕方ない機能に資金を与えて、多数の人々にサービスを提供できるようにするためのものです。それぞれのキャンペーンでは、特定の機能または機能の集合に焦点があてられます。それぞれのスポンサーは、必要な資金提供のうち少しだけを提供し、十分な人/組織の寄付で、たくさんの助けになる作業に支払う基金を持ちます。他の多くの人が寄付に協力してくれそうな機能に関するアイデアがありましたら、PostGIS newsgroupに、その考えを投稿して下さい。一緒に実現できます。

PostGIS 2.0.0はこの戦略を実施する最初のリリースです。PledgeBankを使い、2件のキャンペーンが成功しました。

postgistopology - 10以上のスポンサーがTopoGeometry機能の構築と2.0.0でのトポロジ対応強化とのために、それぞれ250米ドルを寄付しました。

postgis64windows - 20のスポンサーが、Windows上でのPostGIS 64ビット版に必要な作業のために、それぞれ100米ドルを寄付しました。

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

ジオメトリ演算ライブラ GEOS

地理空間データ抽象化ライブラリGDALは、PostGIS 2で導入されたラスタ機能の多くに使われています。また、GDALのPostGIS対応に必要な改善でGDALプロジェクトに貢献しています。

地図投影ライブラリPROJ

最後ですがおろそかにできないのがPostgreSQLです。PostGISはこの巨人に立っています。PostGISの速度と柔軟性は、PostgreSQLが提供する拡張性、優れたクエリプランナ、GiSTインデックス、多数のSQL機能があって初めて成り立ちます。

Chapter 2. PostGISインストール

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

2.1. 簡略版

全ての依存がパスに入っているとする場合、次のようにコンパイルします。

tar -xvfz postgis-3.4.0dev.tar.gz
cd postgis-3.4.0dev
./configure
make
make install

PostGISをインストールした後は、利用したいデータベース個々内で利用可能にする (Section 3.3, “空間データベースの作成”)か、アップグレード (Section 3.4, “空間データベースのアップグレード”)する必要があります。

2.2. ソースからのコンパイルとインストール

[Note]

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

本節では、一般的なコンパイル手順を示します。Windows用や他のOS用等にコンパイルするなら、PostGIS User contributed compile guidesPostGIS Dev Wikiで、より詳細な助けが見つかるかも知れません。

多くのOS用のビルド済みパッケージの一覧はPostGIS Pre-built Packagesにあります。

Windowsユーザの場合は、スタックビルダか、PostGIS Windows download siteから安定版を得ることができます。また、週に1回か2回のビルドと刺激的なことがあった時の随時ビルドとを行っているvery bleeding-edge windows experimental buildsもあります。これらはPostGISの進行中のリリースでの試験に使用します。

PostGISモジュールは、PostgreSQLバックエンドサーバの拡張です。PostGIS 3.4.0devでは、コンパイルのために、完全なPostgreSQLサーバヘッダが必要です。PostgreSQL 12 - 15の間でビルドできます。古い版のPostgreSQLはサポートされません

PostgreSQLをインストールしていないならPostgreSQLインストールガイドを参照して下さい。http://www.postgresql.org/にあります。

[Note]

GEOS機能を有効にするために、PostgreSQLをインストール時に明示的に標準C++ライブラリに対する明示的なリンクが必要になる場合があります。

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

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

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

2.2.1. ソースの取得

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

wget http://postgis.net/stuff/postgis-3.4.0dev.tar.gz
tar -xvzf postgis-3.4.0dev.tar.gz
cd postgis-3.4.0dev

これで、カレントディレクトリの下にpostgis-3.4.0devができます。

もしくは git レポジトリ https://git.osgeo.org/gitea/postgis/postgis/ からチェックアウトします。

git clone https://git.osgeo.org/gitea/postgis/postgis.git postgis
cd postgis
sh autogen.sh
    

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

./configure

2.2.2. インストール要件

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

必須

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

    完全なPosgreSQL/PostGIS対応表とPostGIS/GEOS対応表についてはhttp://trac.osgeo.org/postgis/wiki/UsersWikiPostgreSQLPostGISをご覧ください。

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

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

  • 投影変換ライブラリProj。Proj 4.9以上が必要です。Projライブラリは、PostGISの座標系投影変換機能に使われます。Projは https://proj.org/ からダウンロードできます。

  • ジオメトリライブラリGEOS、3.6版以降が必要ですが、新しい関数と機能の最大限に活用するためには3.9以上をお勧めします。GEOSは http://trac.osgeo.org/geos/ からダウンロード可能です。

  • LibXML2, 2.5.x以上。現在は、LibXML2はインポート関数 (ST_GeomFromGMLとST_GeomFromKML)で使われています。LibXML2はhttps://gitlab.gnome.org/GNOME/libxml2/-/releasesからダウンロードできます。

  • JSON-C 0.9以上。JSON-Cは現在、ST_GeomFromGeoJsonによるGeoJSONの取り込みに使われます。JSON-Cはhttps://github.com/json-c/json-c/releases/からダウンロード可能です。

  • GDAL, version 2以上が必要で以上が好ましいです。ラスタ機能に必要です。https://gdal.org/download.html

  • PostgreSQL+JITでコンパイルする場合には、LLVM 6版以上が必要です。https://trac.osgeo.org/postgis/ticket/4125を参照して下さい。

オプション

  • GDAL (擬似的任意)。ラスタが必要ない場合に限り不要です。Section 3.2, “ラスタ機能の設定”の説明に従って使用したいドライバを有効にしてください。

  • GTK (GTK+2.0, 2.8+が必要)。シェープファイルのローダであるshp2pgsql-guiのコンパイル用です。http://www.gtk.org/にあります。

  • SFCGAL, 1.3.1以上、1.4.1以上が推奨されます。SFCGALは追加的な2次元と3次元の高度な解析機能をPostGISに提供します。Section 8.20, “SFCGAL関数”を参照して下さい。両方のバックエンドから提供される2次元関数 (たとえばST_IntersectionやST_Areaなど)でGEOSでなくSFCGALを使うこともできます。SFCGALがインストールされている場合には、PostgreSQLのpostgis.backendコンフィギュレーション値で、エンドユーザがどのバックエンドを使うかを制御することができます (デフォルトはGEOS)。ご注意: SFCGAL 1.2には少なくともCGAL 4.3とBoost 1.54が必要です (https://oslandia.gitlab.io/SFCGAL/dev.html参照)。https://gitlab.com/Oslandia/SFCGAL/

  • Section 14.1, “住所標準化”をビルドするには、PCRE http://www.pcre.org (Unix系システムには通常はインストール済みです)も必要です。parseaddress-stcities.h内のエンコードしたデータを再構築したい場合には、Perl CPANのRegex::Assembleパッケージのみ必要です。Section 14.1, “住所標準化”は、PCREライブラリを検出するか、コンフィギュレーションで適切に--with-pcre-dir=/path/to/pcreを指定すると、自動的にビルドされます。

  • ST_AsMVTを有効にするには、protobuf-cライブラリ (実行時)とprotoc-cコンパイラ (ビルド時)が必要です。protobuf-cの正しい最小版を確認するには、pkg-configが必要です。protobuf-cをご覧下さい。デフォルトでは、PostGISは、MVTポリゴンを高速に評価するためにWagyuを使用していますが、C++11コンパイラが必要です。CXXFLAGSを使って、PostgreSQLインストールに使ったのと同じコンパイラを使います。これを無効化してGEOSを代わりに使う場合には、コンフィギュレーション時に--without-wagyuを指定します。

  • CUnit (CUnit)。レグレッションテストに必要です。http://cunit.sourceforge.net/にあります。

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

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

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

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

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

./configure

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

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

--with-library-minor-version

PostGIS 3.0以降では、デフォルトではライブラリファイルのファイル名にマイナーバージョンが入らなくなりました。PostGIS 3のライブラリはpostgis-3で終わります。pg_upgradeを簡単にするために実施された変更ですが、サーバにPostGIS 3シリーズは一つのマイナーバージョンのものだけしかインストールできません。postgis-3.0といったようにマイナーバージョンをファイル名に含む古い振る舞いにしたいなら、コンフィギュレーション実行の際に次のスイッチを追加します。

--prefix=PREFIX

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

[Caution]

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

--with-pgconfig=FILE

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

--with-gdalconfig=FILE

必須ライブラリであるGDALは、ラスタ機能に必要な機能を提供します。GDALには、インストール先ディレクトリをインストールスクリプトに伝えるgdal-configがあります。PostGISのビルドに使う特定のGDALを手動で指定する場合に、このパラメータ (--with-gdalconfig=/path/to/gdal-config)を使います。

--with-geosconfig=FILE

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

--with-xml2config=FILE

LibXMLはGeomFromKML/GML処理を行うのに必須のライブラリです。通常はlibxmlをインストールしているなら発見されますが、発見できない場合や特定の版を使用したい場合は、xml2-configを指定してインストールスクリプトにLibXMLのインストール先ディレクトリを伝えます。PostGISのビルドに使う特定のLibXMLを手動で指定する場合に、このパラメータ ( >--with-xml2config=/path/to/xml2-config)を使います。

--with-projdir=DIR

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

--with-libiconv=DIR

iconvのインストール先ディレクトリを指定します。

--with-jsondir=DIR

JSON-Cは、MITライセンスのJSONライブラリで、PostGISのST_GeomFromJSONに必須です。PostGISのビルドに使う特定のJSON-Cを手動で指定する場合に、このパラメータ (--with-jsondir=/path/to/jsondir)を使います。

--with-pcredir=DIR

PCREは、BSDライセンスのPerl互換正規表現ライブラリです。住所標準化エクステンションに必須です。PostGISのビルド対象としている特定のPCREを手動で指定する場合に、このパラメータ (--with-pcredir=/path/to/pcredir)を使います。

--with-gui

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

--without-raster

ラスタ機能なしでコンパイルします。

--without-topology

トポロジ対応を無くしてコンパイルします。トポロジに必要なロジックは全てpostgis-3.4.0devライブラリ内に作られるので、関連ライブラリはありません。

--with-gettext=no

デフォルトでは、gettextの検出とこれを用いたコンパイルを試みますが、ローダ破損を引き起こす非互換性問題のもとで実行する場合には、このコマンドで無効にできます。これを使ったコンフィギュレーションによって解決する問題の例はhttp://trac.osgeo.org/postgis/ticket/748にあります。ご注意: これを切ることで多くの機能がなくなるわけではありません。まだ文書化されていなくて試験段階であるGUIローダにおける内部のヘルプ/ラベル機能に使われています。

--with-sfcgal=PATH

デフォルトでは、このスイッチなしではSFCGAL対応でインストールされません。PATHは、sfcgal-configへのパスを指定することができる追加的な引数です。

--without-phony-revision

Gitレポジトリの現在のHEADに一致するように、postgis_revision.hの更新を無効にします。

[Note]

PostGISをコードレポジトリから得る場合には、はじめに次のスクリプトを実行します。

./autogen.sh

このスクリプトによってconfigureスクリプトが生成されます。これはPostGISのインストールに関するカスタマイズに使われます。

PostGISをアーカイブファイルで入手する場合には、configureが既に生成されているので./autogen.shは不要です。

2.2.4. ビルド

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

make

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

PostGIS 1.4.0版からは、全ての関数に文書から生成されるコメントが付きます。これらのコメントを後からインストールするには、次のコマンドを実行しますが、docbookが必要です。アーカイブファイルからインストールする場合は、postgis_comments.sql, raster_comments.sql, topology_comments.sqlは、docフォルダにあるので、コメントを作成する必要はありません。コメントはCREATE EXTENSIONによるインストールの一部として取り込まれます。

make comments

PostGIS 2.0で導入されました。早見表にも、また学習中の方のハンドアウトにも適しているHTMLチートシートを生成します。xsltprocが必要で、topology_cheatsheet.html, tiger_geocoder_cheatsheet.html, raster_cheatsheet.html, postgis_cheatsheet.htmlの4ファイルが生成されます。

HTMLとPDFのビルド済みのものはPostGIS / PostgreSQL Study Guidesにあります。

make cheatsheets

2.2.5. PostGISエクステンションのビルドとデプロイ

PostgreSQL 9.1以上を使用している場合は、PostGISエクステンションが自動的にビルド、インストールされます。

ソースレポジトリからビルドしている場合は、関数の記述を最初にビルドする必要があります。これらは、docbookがインストールされている時にビルドされます。手動でインストールするには次のようにします。

make comments

アーカイブファイルからのビルドの場合は、ビルド済みのものがあるので、コメントのビルドは必須ではありません。

PostgreSQL 9.1を対象にビルドしている場合は、エクステンションは自動的にmake install処理の一部としてビルドするべきです。必要ならextensionsフォルダからビルドできますし、他のサーバで必要ならファイルの複製ができます。

cd extensions
cd postgis
make clean
make
export PGUSER=postgres # psql変数の上書き
make check #to test before install
make install
# extensionsのテスト
make check RUNTESTFLAGS=--extension
[Note]

make checkは、テスト実行のためにpsqlを使用し、psql環境変数を使用します。一般的なpsql環境変数で上書きすると便利なのが PGUSER,PGPORT, and PGHOSTです。環境変数を参照して下さい。

エクステンションファイルは、常に、OSに関係なく同じ版のPostGISでは同じです。PostGISバイナリを既にインストールしている限りは、エクステンションファイルをあるOSから別のものに複写して大丈夫です。

開発用と異なる別のサーバでエクステンションを手動でインストールしたい場合は、サーバにない時に必要となる通常のPostGISのバイナリだけでなく、次のファイルをextensionsフォルダからPostgreSQLインストール先のPostgreSQL / share / extensionフォルダに複写します。

  • 指定されていない場合のインストールするエクステンションの版等の情報を示す制御ファイpostgis.control, postgis_topology.control

  • エクステンションごとの/sqlフォルダにあるファイル全て。extensions/postgis/sql/*.sql, extensions/postgis_topology/sql/*.sqlはPostgreSQL share/extensionフォルダの最上位に複写する必要があることに注意して下さい。

以上を実行すると、PgAdmin -> extensionでpostgis, postgis_topologyが有効なエクステンションとして見えます。

psqlを使う場合は、次のクエリを実行してエクステンションがインストールされていることを確認できます。

SELECT name, default_version,installed_version
FROM pg_available_extensions WHERE name LIKE 'postgis%' or name LIKE 'address%';

             name             | default_version | installed_version
------------------------------+-----------------+-------------------
 address_standardizer         | 3.4.0dev         | 3.4.0dev
 address_standardizer_data_us | 3.4.0dev         | 3.4.0dev
 postgis                      | 3.4.0dev         | 3.4.0dev
 postgis_raster               | 3.4.0dev         | 3.4.0dev
 postgis_sfcgal               | 3.4.0dev         |
 postgis_tiger_geocoder       | 3.4.0dev         | 3.4.0dev
 postgis_topology             | 3.4.0dev         |
(6 rows)

クエリを行ったデータベースにエクステンションがインストールされている場合は、installed_versionカラムに記載が見えます。レコードが返ってこない場合は、PostGIS EXTENSIONがインストールされていないことになります。PgAdmin III 1.14以上では、データベースブラウザツリーのextensionsセクションで提供されていて、右クリックでアップグレードまたアンインストールできます。

有効なエクステンションがある場合、pgAdminエクステンションインタフェースまたは次のSQLの実行によって、選択したデータベースにPostGISエクステンションをインストールできます。

CREATE EXTENSION postgis;
CREATE EXTENSION postgis_raster;
CREATE EXTENSION postgis_sfcgal;
CREATE EXTENSION fuzzystrmatch; -- postgis_tiger_geocoderに必要
-- postgis_tiger_geocoderで使用されるか単独で使われます
CREATE EXTENSION address_standardizer;
CREATE EXTENSION address_standardizer_data_us;
CREATE EXTENSION postgis_tiger_geocoder;
CREATE EXTENSION postgis_topology;

psqlでは、どの版が、どのスキーマにインストールされているかを見ることができます。

\connect mygisdb
\x
\dx postgis*
List of installed extensions
-[ RECORD 1 ]-------------------------------------------------
Name        | postgis
Version     | 3.4.0dev
Schema      | public
Description | PostGIS geometry, geography, and raster spat..
-[ RECORD 2 ]-------------------------------------------------
Name        | postgis_raster
Version     | 3.0.0dev
Schema      | public
Description | PostGIS raster types and functions
-[ RECORD 3 ]-------------------------------------------------
Name        | postgis_tiger_geocoder
Version     | 3.4.0dev
Schema      | tiger
Description | PostGIS tiger geocoder and reverse geocoder
-[ RECORD 4 ]-------------------------------------------------
Name        | postgis_topology
Version     | 3.4.0dev
Schema      | topology
Description | PostGIS topology spatial types and functions
[Warning]

エクステンションのテーブルspatial_ref_sys, layer, topologyは、明示的にバックアップできません。それぞれのpostgisまたはpostgis_topologyエクステンションがバックアップされる時のみバックアップできます。これは、データベース全体のバックアップの時のみ行われます。PostGIS 2.0.1の時点では、データベースがバックアップされる際に、PostGISでパッケージ化されていないsridレコードのみバックアップされます。パッケージに入っているsridの変更は巡回せず、変更はそこにあるものと期待されます。PostGIS 2.0.1の時点では、データベースがバックアップされるときにPostGISに入っていないsridのレコードだけがバックアップされます。PostGISに入っていて後に変更されたsridの変更については巡回しません。問題が見られたら、チケットを発行して下さい。エクステンションテーブルの構造はCREATE EXTENSIONで生成されるので、バックアップを行いません。エクステンションの与えられた版と同じものであると仮定されます。この挙動は現在のPostgreSQL エクステンションモデルに組み込まれているため、これについては何もできません。

素晴らしいエクステンション機構を使わずに3.4.0devをインストールした場合には、それぞれのエクステンションが持つ関数をパッケージするためのコマンドを実行して、エクステンションに基づくように変更できます。PostgreSQL 13では、パッケージしない方法でのインストールは削除されましたので、PostgreSQL 13にアップグレードする前にエクステンションをビルドするように変更するべきです。

CREATE EXTENSION postgis FROM unpackaged;
CREATE EXTENSION postgis_raster FROM unpackaged;
CREATE EXTENSION postgis_topology FROM unpackaged;
CREATE EXTENSION postgis_tiger_geocoder FROM unpackaged;

2.2.6. テスト

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

make check

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

[Note]

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

[Caution]

現在のところmake checkは、チェックを行う際に 環境変数PATHPGPORTによっています。コンフィギュレーションパラメータ--with-pgconfigを使って特定したPostgreSQLではありません。PATHを編集して、コンフィギュレーションの際に検出したPostgreSQLと一致するようにして下さい。もしくは、間もなく襲ってくる頭痛の準備をしておいて下さい。

成功したなら、make checkで約500個のテストを生成します。結果は次のようなかんじになります (かなりの行を省略しています)。

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

        .
        .
        .

Run Summary:    Type  Total    Ran Passed Failed Inactive
              suites     44     44    n/a      0        0
               tests    300    300    300      0        0
             asserts   4215   4215   4215      0      n/a
Elapsed time =    0.229 seconds

        .
        .
        .

Running tests

        .
        .
        .

Run tests: 134
Failed: 0


-- if you build with SFCGAL

        .
        .
        .

Running tests

        .
        .
        .

Run tests: 13
Failed: 0

-- if you built with raster support

        .
        .
        .

Run Summary:    Type  Total    Ran Passed Failed Inactive
              suites     12     12    n/a      0        0
               tests     65     65     65      0        0
             asserts  45896  45896  45896      0      n/a


        .
        .
        .

Running tests

        .
        .
        .

Run tests: 101
Failed: 0

-- topology regress

.
.
.

Running tests

        .
        .
        .

Run tests: 51
Failed: 0

-- if you built --with-gui, you should see this too

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

        .
        .
        .

Run Summary:    Type  Total    Ran Passed Failed Inactive
              suites      2      2    n/a      0        0
               tests      4      4      4      0        0
             asserts      4      4      4      0      n/a

postgis_tiger_geocoderaddress_standardizerエクステンションは、現在は、標準的なPostgreSQLインストールチェックにのみ対応しています。これらをテストするには、次のようにします。ご注意: PostGISコードフォルダのルートでmake installを既に行っている場合には、make installは重要ではありません。

address_standardizer用:

cd extensions/address_standardizer
make install
make installcheck
          

出力は次のようなかんじになります。

============== dropping database "contrib_regression" ==============
DROP DATABASE
============== creating database "contrib_regression" ==============
CREATE DATABASE
ALTER DATABASE
============== running regression test queries        ==============
test test-init-extensions     ... ok
test test-parseaddress        ... ok
test test-standardize_address_1 ... ok
test test-standardize_address_2 ... ok

=====================
 All 4 tests passed.
=====================

Tiger Geocodeを使う場合には、使用するPostgreSQLインスタンス内にPostGISとfuzzystrmatchのエクステンションが必要です。PostGISをaddress_standardizer機能付きでビルドした場合は、address_standardizerのテストも行います。

cd extensions/postgis_tiger_geocoder
make install
make installcheck
          

出力は次のようなかんじになります。

============== dropping database "contrib_regression" ==============
DROP DATABASE
============== creating database "contrib_regression" ==============
CREATE DATABASE
ALTER DATABASE
============== installing fuzzystrmatch               ==============
CREATE EXTENSION
============== installing postgis                     ==============
CREATE EXTENSION
============== installing postgis_tiger_geocoder      ==============
CREATE EXTENSION
============== installing address_standardizer        ==============
CREATE EXTENSION
============== running regression test queries        ==============
test test-normalize_address   ... ok
test test-pagc_normalize_address ... ok

=====================
All 2 tests passed.
=====================

2.2.7. インストール

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

make install

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

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

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

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

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

make comments-install

[Note]

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

2.3. PAGC住所標準化ツールのインストールと使用

address_standardizerエクステンションは、別途ダウンロードする必要がある別パッケージとしていました。PostGIS 2.2からは同梱されています。address_standardizeの追加情報、できること、および、コンフィギュレーション方法については、Section 14.1, “住所標準化”をご覧下さい。

標準化エクステンションは、Normalize_Addressの後継で、PostGISに入っているTigerジオコーダエクステンションに使うことができます。この場合の使い方についてはSection 2.4.3, “TigerジオコーダをPostGISデータベースで有効にする: エクステンションを使用”を参照して下さい。また、ユーザ自身がつくるジオコーダの要素として使用したり、住所の比較を簡単にするために住所を標準化するために使うことができます。

住所標準化エクステンションはPCREに依存しています。PCREは多くのUNIX系システムにインストールされていますが、http://www.pcre.orgから最新版をダウンロードできます。Section 2.2.3, “コンフィギュレーション”の際にPCREを発見すると、住所標準化エクステンションが自動的にビルドされます。使用したいPCREのインストールが独自なものである場合は、configureに--with-pcredir=/path/to/pcreを渡します。/path/to/pcreは、PCREのincludeとlibのあるルートフォルダです。

Windowsでは、PostGIS 2.1以上に住所標準化エクステンションが同梱されているので、コンパイルを行わずに、すぐにCREATE EXTENSIONに行くことができます。

インストールしたら、対象データベースに接続して次のSQLが実行できます。

CREATE EXTENSION address_standardizer;

次のテストでは、rules, gaz, lexテーブルは必要ありません。

SELECT num, street, city, state, zip
 FROM parse_address('1 Devonshire Place PH301, Boston, MA 02109');

出力は次のようになります。

num |         street         |  city  | state |  zip
-----+------------------------+--------+-------+-------
 1   | Devonshire Place PH301 | Boston | MA    | 02109

2.3.1. Regex::Assembleのインストール

PerlのRegex::Assembleは、ソースツリーの一部がこれで作られていますが、住所標準化エクステンションではもはや不要です。ただし、usps-st-city-orig.txtまたはusps-st-city-orig.txt usps-st-city-adds.txを編集する必要がある場合は、parseaddress-stcities.hのリビルドでRegex:Assembleが必要です。

cpan Regexp::Assemble

Ubuntu / Degianの場合には、次のようにしなければならないかも知れません。

sudo perl -MCPAN -e "install Regexp::Assemble"

2.4. Tigerジオコーダのインストールとアップグレードとデータロード

Tigerジオコーダのような拡張機能はPostGISディストリビューションに同梱されていません。Tigerジオコーダエクステンションが無かったり、インストールしているものより新しい版のものが欲しい場合には、Windows Unreleased VersionsでPostgreSQLの版に合ったパッケージにあるshare/extension/postgis_tiger_geocoder.*ファイルを使います。これらのパッケージはWindows用ですが、postgis_tige_geocoderエクステンションファイルは、SQLとPL/pgSQLだけですので、他のOSでも動作します。

2.4.1. TigerジオコーダをPostGISデータベースで有効にする: エクステンションを使用

PostgreSQL 9.1以上とPostGIS 2.1.0を使用している場合は、Tigerジオコーダのインストールで、新しいエクステンションモデルの利点を得ることができます。次のようにします。

  1. まず、通常の方法で、PostGIS 2.1.0のバイナリを取得するか、コンパイルしてインストールします。これにより重要なエクステンションファイルとTigerジオコーダのファイルがインストールされます。

  2. psql、pgAdminまたは他のツールでデータベースに接続して、次のSQLコマンドを実行します。既にPostGISを持っているデータベースにインストールする場合は、一つ目の手順は不要です。fuzzystrmatchエクステンションが既にインストールされている場合は、二つ目の手順は不要です。

    CREATE EXTENSION postgis;
    CREATE EXTENSION fuzzystrmatch;
    CREATE EXTENSION postgis_tiger_geocoder;
    -- 規則を基にした住所標準化 (pagc_normalize_address)を使いたい場合の任意実行
    CREATE EXTENSION address_standardizer;

    既にpostgis_tiger_geocoderエクステンションをインストールしていて、最新版に更新するだけの場合には、次を実行します。

    ALTER EXTENSION postgis UPDATE;
    ALTER EXTENSION postgis_tiger_geocoder UPDATE;

    独自のエントリを生成した場合や、tiger.loader_platformtiger.loader_variablesに変更を加えた場合には、これらをアップデートしなければならないことがあります。

  3. 正しくインストールされたかを確認するために、インストール対象データベース内で次のSQLを実行します。

    SELECT na.address, na.streetname,na.streettypeabbrev, na.zip
            FROM normalize_address('1 Devonshire Place, Boston, MA 02109') AS na;

    出力は次のようになります。

    address | streetname | streettypeabbrev |  zip
    ---------+------------+------------------+-------
               1 | Devonshire | Pl               | 02109
  4. tiger.loader_platformテーブルの、実行ファイルやサーバのパスを持つ新しいレコードを生成します。

    shコンベンションのあとにdebbieというプロファイルを生成する例として、次のコマンドを実行します。

    INSERT INTO tiger.loader_platform(os, declare_sect, pgbin, wget, unzip_command, psql, path_sep,
                       loader, environ_set_command, county_process_command)
    SELECT 'debbie', declare_sect, pgbin, wget, unzip_command, psql, path_sep,
               loader, environ_set_command, county_process_command
      FROM tiger.loader_platform
      WHERE os = 'sh';

    それから、declare_sectカラム内のパスを編集して、Debbieのpg, unzip, shp2pgsql, psql他のパス位置に適応するようにします。

    loader_platformテーブルを編集しない場合は、一般的なアイテムの位置を持っているので、スクリプトが生成された後で、スクリプトを編集しなければなりません。

  5. PostGIS 2.4.1からは、ZTCA5 (Zip Code 5 digit Tabulation Area)のロード手順が変更され、有効になった時にLoader_Generate_Nation_Scriptの一部として現在のZCTA5データをロードするようになりました。デフォルトでは切られています。ロードにかなりの時間 (20から60分)が取られ、かなりのディスクスペースを占有するのに、そんなに頻繁には使わないためです。

    有効にするには、次のようにします。

    UPDATE tiger.loader_lookuptables SET load = true WHERE table_name = 'zcta520';

    境界のフィルタが追加され、ちょうど境界内のZIPに制限された場合に、Geocode関数は、ZCTA5が存在するなら使います。Reverse_Geocode関数は、返された住所にZIPコードが無い場合に (しばしば高速道路での逆ジオコーディングで発生します)、これを使います。

  6. サーバまたはローカル (サーバへのネットワーク接続が早い場合)のルートにgisdataというフォルダを作成します。このフォルダはTigerファイルがダウンロードされ、処理される場所です。サーバのルートにフォルダを作ると不幸になる場合や、単に他のフォルダに移したい場合には、tiger.loader_variablesテーブルのstaging_foldフィールドを編集します。

  7. gisdataフォルダ内にtempというフォルダを作成します。もしくは、staging_foldで示されたフォルダを作成します。ローダがダウンロードしたTigerデータを展開する場所です。

  8. そして、SQL関数Loader_Generate_Nation_Scriptを実行して、独自のプロファイルの名前を使うか確認し、.shまたは.batファイルにスクリプトを複写します。たとえば、新しいプロファイルで国のロードを行う場合には、次のようにします。

    psql -c "SELECT Loader_Generate_Nation_Script('debbie')" -d geocoder -tA 
    > /gisdata/nation_script_load.sh
  9. 生成された国データをロードするコマンドラインスクリプトを実行します。

    cd /gisdata
    sh nation_script_load.sh
  10. 国スクリプトを実行した後、tiger_dataスキーマに三つのテーブルが作られ、データが格納されています。次のクエリをpsqlかpgAdminから実行して、確認します。

    SELECT count(*) FROM tiger_data.county_all;
    count
    -------
      3233
    (1 row)
    SELECT count(*) FROM tiger_data.state_all;
    count
    -------
        56
    (1 row)
    
  11. デフォルトではbg, tract, tabblockに対応するテーブルはロードされません。ジオコーダはこれらのテーブルを使いませんが、一般に、人口統計に使います。州データのロードの一部としてロードするには、次の手続きを実行して有効にします。

    UPDATE tiger.loader_lookuptables SET load = true WHERE load = false AND lookup_name IN('tract', 'bg', 'tabblock');

    もしくは、Loader_Generate_Census_Scriptを使って州のデータをロードした後に、これらのテーブルだけをロードできます。

  12. データをロードしたい州ごとに、Loader_Generate_Scriptで州スクリプトを作ります。

    [Warning]

    国データのロードを完了する前に*州スクリプトを作ってはなりません*。州スクリプトは国スクリプトでロードされる国リストを利用するためです。

  13. psql -c "SELECT Loader_Generate_Script(ARRAY['MA'], 'debbie')" -d geocoder -tA 
    > /gisdata/ma_load.sh
  14. 生成されたコマンドラインスクリプトを実行します。

    cd /gisdata
    sh ma_load.sh
  15. 全てのデータのロードが完了するか中断ポイントに達した後に、全てのtigerテーブルに対してanalyzeを実行して、(継承されたものも含めて)状態を更新するのは良いことです。

    SELECT install_missing_indexes();
    vacuum (analyze, verbose) tiger.addr;
    vacuum (analyze, verbose) tiger.edges;
    vacuum (analyze, verbose) tiger.faces;
    vacuum (analyze, verbose) tiger.featnames;
    vacuum (analyze, verbose) tiger.place;
    vacuum (analyze, verbose) tiger.cousub;
    vacuum (analyze, verbose) tiger.county;
    vacuum (analyze, verbose) tiger.state;
    vacuum (analyze, verbose) tiger.zip_lookup_base;
    vacuum (analyze, verbose) tiger.zip_state;
    vacuum (analyze, verbose) tiger.zip_state_loc;

2.4.1.1. Tigerジオコーダ通常インストールのエクステンションモデルへの変換

エクステンションモデルを使わずにTigerジオコーダをインストールしている場合に、次のようにして、エクステンションモデルに変換できます。

  1. Section 2.4.5, “Tigerジオコーダのアップグレード”の指示に従って非エクステンションモデルのアップグレードを行います。

  2. psqlまたはpgAdminでデータベースに接続して、次のコマンドを実行します。

    CREATE EXTENSION postgis_tiger_geocoder FROM unpackaged;

2.4.2. TigerジオコーダをPostGISデータベースで有効にする: エクステンション不使用

まず、上述の手順でPostGISをインストールします。

extrasフォルダが無い場合、http://postgis.net/stuff/postgis-3.4.0dev.tar.gzをダウンロードします。

tar xvfz postgis-3.4.0dev.tar.gz

cd postgis-3.4.0dev/extras/tiger_geocoder

tiger_loader_2015.sql (違う年のものをロードしたくないならば最新のローダファイル)をあなたの実行サーバ等のパスに編集します。もしくはloader_platformがインストールされた後に一度これを更新します。このファイルもloader_platformも編集しない場合には、一般的なアイテムの位置を持っているだけなので、Loader_Generate_Nation_ScriptLoader_Generate_Scriptを実行した後に、生成されたスクリプトを編集しなければなりません。

初めてTigerジオコーダをインストールする場合は、Windowsではcreate_geocode.batを、またLinux/Unix/Mac OSXではcreate_geocode.shを、使用するPostgreSQLにとって独自の設定に変更したうえで、コマンドラインから対応するスクリプトを実行します。

データベースにtigerスキーマがあることを確認します。もし無い場合は、次の行を参考に、コマンドを実行します。

ALTER DATABASE geocoder SET search_path=public, tiger;

住所正規化機能は、トリッキーな住所を除いて、大体データなしで動作します。テストを実行して次のように見えることを確認して下さい。

SELECT pprint_addy(normalize_address('202 East Fremont Street, Las Vegas, Nevada 89101')) As pretty_address;
pretty_address
---------------------------------------
202 E Fremont St, Las Vegas, NV 89101
                        

2.4.3. TigerジオコーダをPostGISデータベースで有効にする: エクステンションを使用

皆さんが問題と思われるの多くのことのひとつに、ジオコーディング前の準備に住所を正規化する関数Normalize_Addressがあります。住所正規化は万全と言うにはほど遠く、パッチをあてようとすると膨大な資源を費やします。よって、より良い住所標準化エンジンを持つ他のプロジェクトに統合しました。この新しい住所標準化を使うには、Section 2.3, “PAGC住所標準化ツールのインストールと使用”で記述するようにエクステンションをコンパイルし、使用するデータベースにインストールします。

このエクステンションをpostgis_tiger_geocoderをインストールしているデータベースにインストールすると、Pagc_Normalize_Addressを、Normalize_Addressの代わりに使うことができます。このエクステンションはTigerジオコーダからは見えないので、国際的な住所といった他のデータソースでも使えます。Tigerジオコーダエクステンションは、その版の規則テーブル (tiger.pagc_rules), gaz table (tiger.pagc_gaz), lexテーブル (tiger.pagc_lex)を同梱しています。これらは、必要に応じて標準化の改善のために追加や更新ができます。

2.4.4. Tigerデータのロード

データロードの説明の詳細はextras/tiger_geocoder/tiger_2011/READMEにあります。これは一般的な手順を示しています。

ロードプロセスによって、米センサスウェブサイトから個々の国ファイル、リクエストされた州のデータをダウンロードし、ファイルを展開し、個別の州をそれぞれの州テーブルの集合にロードします。各州のテーブルは、tigerスキーマで定義されたテーブルを継承しているので、これらのテーブルに対して全てのデータにアクセスするためのクエリを出すことができますし、州の再読み込みが必要となったり、州が必要ない場合には、Drop_State_Tables_Generate_Scriptで、いつでも州テーブルの集合を削除するクエリを出すことができます。

データのロードを可能にするためには次のツールが必要です。

  • センサスウェブサイトから取得するZIPファイルを展開するツール。

    Unix系システムでは、unzip実行ファイルです。通常は、ほとんどのUnix系プラットフォームで既にインストールされています。

    Windowsでは7-zipです。http://www.7-zip.org/からダウンロードできる無償の圧縮解凍ツールです。

  • shp2pgsqlコマンド。PostGISインストール時にデフォルトでインストールされます。

  • wgetコマンド。通常はほとんどのUnix/Linuxシステムにインストールされている、ウェブ取得ツールです。

    Windows用については、コンパイル済みのバイナリをhttp://gnuwin32.sourceforge.net/packages/wget.htmから取得できます。

tiger_2010からアップグレードする場合には、最初にDrop_Nation_Tables_Generate_Scriptを生成、実行する必要があります。州データをロードする前に、Loader_Generate_Nation_Scriptで国データをロードする必要があります。これによって、環境に合ったローダスクリプトが生成されます。Loader_Generate_Nation_Scriptは、一度の操作で、(2010からの)アップグレードと、新しいインストールが行われます。

州データをロードするには、Loader_Generate_Scriptを参照して、手持ちのプラットフォームで動作する、求める州データをロードするデータロードスクリプトを生成します。州データはひとつずつダウンロードできることに注意して下さい。一度に必要な州の全てについてデータをロードする必要はありません。必要なだけダウンロードできます。

求める州データをロードした後は、Install_Missing_Indexesに示すように、

SELECT install_missing_indexes();

を実行するようにして下さい。

行うべきことができたかをテストするために、Geocodeを使用する州の中の住所についてジオコーダを実行してみます。

2.4.5. Tigerジオコーダのアップグレード

2.0以上に含まれるTigerジオコーダがインストールされている場合には、どうしても必要な訂正があるときは、いつでも臨時のアーカイブファイルからでも機能のアップグレードができます。 これは、エクステンションでインストールされていないTigerジオコーダで動作します。

extrasフォルダが無い場合、http://postgis.net/stuff/postgis-3.4.0dev.tar.gzをダウンロードします。

tar xvfz postgis-3.4.0dev.tar.gz

cd postgis-3.4.0dev/extras/tiger_geocoder/tiger_2011

Windowsの場合はupgrade_geocoder.batスクリプト、Linux/Unix/MacOS Xの場合はupgrade_geocoder.shスクリプトの位置を特定します。 PostGISデータベースの資格情報を持つように編集します。

2010または2011からアップグレードする場合には、確実にローダスクリプトのコメントアウトを消すと、2012データのロードのための最新のスクリプトを得ます。

対応するスクリプトをコマンドラインから実行します。

次に、全ての国テーブルを削除し、新しい国テーブルをロードします。Drop_Nation_Tables_Generate_Scriptに詳細がある通り、このSQLステートメントを使った削除スクリプトを生成します。

SELECT drop_nation_tables_generate_script();

生成した削除SQLステートメントを実行します。

Loader_Generate_Nation_Scriptに詳細がある通り、このSELECTステートメントを使った削除スクリプトを生成します。

Windows向け

SELECT loader_generate_nation_script('windows'); 

Unix/Linux向け

SELECT loader_generate_nation_script('sh');

生成したスクリプトの実行方法に関する説明は、Section 2.4.4, “Tigerデータのロード”を参照して下さい。これは一度だけ実行する必要があります。

[Note]

2010/2011州テーブルを混在させることができ、それぞれの州について個別にアップグレードできます。2011にアップグレードする前に、まず、Drop_State_Tables_Generate_Scriptを使って、2010州テーブルを削除します。

2.5. 共通の問題

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

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

    SELECT version();

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

  2. アップグレードに失敗する場合、既にPostGISがインストールされているデータベースにリストアしているか確認して下さい。

    SELECT postgis_full_version();

また、コンフィギュアが正しくPostgreSQL、Proj4ライブラリ、GEOSライブラリのインストール先を検出したかチェックして下さい。

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

Chapter 3. PostGIS管理

3.1. パフォーマンスチューニング

PostGISの調整はPostgreSQLの作業量の調整と非常に似ています。ジオメトリとラスタは重く、メモリ関連の最適化は他のPostgreSQLクエリと比べて影響が大きい点だけは留意して下さい。

PostgreSQLの最適化に関する一般的な詳細は、 Tuning your PostgreSQL Serverをご覧ください。

PostgreSQL 9.4以上では、ALTER SYSTEMを使うことで、postgresql.confpostgresql.auto.confを触ることなくサーバレベルで設定できます。

ALTER SYSTEM SET work_mem = '256MB';
-- 起動時設定でない設定を強制します。新規接続に影響を与えます。
SELECT pg_reload_conf();
-- 現在の設定値を表示
-- 全ての設定を見るにはSHOW ALLを使います
SHOW work_mem;

PostgreSQLの設定に加えて、PostGISには Section 8.23, “Grand Unified Custom変数 (GUC)”で挙げる独自設定があります。

3.1.1. 起動時

次に示す設定はpostgresql.confにあります。

constraint_exclusion

  • デフォルト: partition

  • 一般的にテーブルのパーティショニングに使われます。デフォルトとして"partition"に設定されています。継承階層内にあり、プランナにペナルティ以外を払わないなら、クエリプランナにテーブルの制約条件の解析だけを行わせるので、PostgreSQL 8.4以上ではこれが理想的です。

shared_buffers

  • デフォルト: PostgreSQL 9.6では128MB以下

  • 利用可能なRAMの25%から40%を設定します。Windowsでは高く設定することができないかも知れません。

max_worker_processes これは、PostgreSQL 9.4以上で有効です。PostgreSQL 9.6以上では、パラレルクエリ処理に使うプロセス数の最大値の制御で、さらに重要なものとなっています。

  • デフォルト: 8

  • システムが対応できるバックグラウンドプロセスの最大値を設定します。このパラメータはサーバ起動時のみ設定できます。

3.1.2. 実行時

work_mem - 並べ替えや複雑なクエリに使われるメモリのサイズの設定

  • デフォルト: 1-4MB

  • 大きなデータベースの場合や、複雑なクエリの場合、RAMが多い場合は値を大きくするように調整します。

  • 同時接続ユーザ数が多い場合や、RAMが少ない場合には値を小さくするように調整します。

  • たくさんのRAMを持ち、少数の開発者しかいない場合は次のようにします。

    SET work_mem TO '256MB';

maintenance_work_mem - VACUUM, CREATE INDEX等で使われるメモリのサイズ

  • デフォルト: 16-64MB

  • 一般的には低すぎます - メモリスワップの間、入出力が拘束され、オブジェクトがロックされます。

  • たくさんのRAMを持つ本番サーバでは32MBから1GBが推奨ですが、同時接続ユーザ数に依存します。たくさんのRAMを持ち、少数の開発者しかいない場合は次のようにします。

    SET maintenance_work_mem TO '1GB';

max_parallel_workers_per_gather

この設定はPostgreSQL 9.6以上で使用でき、並列クエリに対応しているPostGIS 2.3以上に影響は限られます。0より大きい値に設定すると、ST_Intersectsといった関係関数を含むクエリで、複数プロセッサが使われるようにできます。その時、2倍を超える速度が出る可能性があります。予備のプロセッサが多数ある場合には、この値をプロセッサ数に変更するべきです。また、max_worker_processesをこの値と同じにするようにします。

  • デフォルト: 0

  • 単一のGatherノードが開始できるワーカの最大数を設定します。並列ワーカは、max_worker_processesで確立されたプロセスのプールから取得されます。要求したワーカ数は、実際には実行可能になっていない場合があることに注意して下さい。これが発生する場合には、想定より少ないワーカでプランが実行され、非効率になります。これの値を0 (デフォルト値)にすると、パラレルクエリ実行が無効になります。

3.2. ラスタ機能の設定

ラスタ機能を有効にしたら、下に示す確実な設定方法を読んだ方がいいです。

PostGIS 2.1.3以降では、データベース外ラスタと全てのラスタドライバは、デフォルトでは無効になっています。これらを有効にするには、サーバ上で、環境変数 POSTGIS_GDAL_ENABLED_DRIVERSPOSTGIS_ENABLE_OUTDB_RASTERSを設定します。PostGIS 2.2では、Section 8.23, “Grand Unified Custom変数 (GUC)”に従って設定する、クロスプラットフォームな手法があります。

データベース外ラスタを有効にするには次のようにします。

POSTGIS_ENABLE_OUTDB_RASTERS=1

他の値を入れたり、値を入れない場合には、データベース外ラスタは無効になります。

インストールしたGDALのドライバを有効にするには、次の環境変数を設定します。

POSTGIS_GDAL_ENABLED_DRIVERS=ENABLE_ALL

一部のドライバのみ有効にしたい場合には、環境変数を次のように設定します。

POSTGIS_GDAL_ENABLED_DRIVERS="GTiff PNG JPEG GIF XYZ"
[Note]

Windows上の場合は、ドライバリストに引用符をつけないで下さい。

環境変数の設定はOSによって異なります。UbuntuまたはDebian上でapt-postgresqlを経由したPostgreSQLのインストールについては、/etc/postgresql/10/main/environmentを編集するのが好ましい方法です。 ここで、10はPostgreSQLのバージョンを指し、mainはクラスタを指します。

Windowsでサービスとして実行している場合には、システム変数で設定します。Windows 7では、コンピュータを右クリックしてプロパティをクリックするか、エクスプローラの検索バーにコントロール パネル\すべてのコントロール パネル項目\システムを指定します。 システムの詳細設定 -> 詳細設定 -> 環境変数 を順にクリックして、新しいシステム環境変数を追加します。

環境変数を設定した後は、設定を反映させるために、PostgreSQLサービスの再起動が必要です。

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

3.3.1. エクステンションを使って空間データベースを有効にする

PostgreSQL 9.1以上を使っていて、エクステンションのPostGISモジュールをコンパイル、インストールしている場合には、エクステンションというメカニズムを使用して、データベースを空間データベースに切り替えることができます。

中核となるPostGISエクステンションには、ジオメトリ、ジオグラフィ、spatial_ref_sysおよび全ての関数とコメントが含まれています。ラスタとトポロジは別のエクステンションになっています。

空間データベースにしたいデータベース上で次のSQLを実行します。

CREATE EXTENSION IF NOT EXISTS plpgsql;
      CREATE EXTENSION postgis;
      CREATE EXTENSION postgis_raster; -- OPTIONAL
      CREATE EXTENSION postgis_topology; -- OPTIONAL

3.3.2. エクステンションを使わずに空間データベースを有効にする (お勧めできません)

[Note]

これは、通常はPostgreSQLのエクステンションのディレクトリ内にPostGISをインストールできないか、したくない場合 (たとえばテスト中や開発中、または制限のある環境内)にのみ必要となります。

ビルドの際に指定した[prefix]/share/contrib内にある様々なSQLファイルをロードしてPostGISオブジェクトと関数の定義をデータベースに追加します。

中核のPostGISオブジェクト (ジオメトリ型とジオグラフィ型、これらに対応する関数)はpostgis.sqlスクリプトにあります。ラスタオブジェクトはrtpostgis.sqlスクリプトにあります。トポロジオブジェクトはtopology.sqlスクリプトにあります。

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

PostGIS関数にコメントを追加したい場合には、postgis_comments.sqlスクリプト内のコメントが見つかると思います。コメントはpsqlのターミナルウィンドウから単に\dd [関数名]と打ち込むだけで見ることができます。

ターミナルで次のシェルコマンドを実行します。

DB=[データベース名]
    SCRIPTSDIR=`pg_config --sharedir`/contrib/postgis-3.1/

    # 中核
    psql -d ${DB} -f ${SCRIPTSDIR}/postgis.sql
    psql -d ${DB} -f ${SCRIPTSDIR}/spatial_ref_sys.sql
    psql -d ${DB} -f ${SCRIPTSDIR}/postgis_comments.sql # 任意

    # ラスタ機能 (任意)
    psql -d ${DB} -f ${SCRIPTSDIR}/rtpostgis.sql
    psql -d ${DB} -f ${SCRIPTSDIR}/raster_comments.sql # 任意

    # トポロジ機能 (任意)
    psql -d ${DB} -f ${SCRIPTSDIR}/topology.sql
    psql -d ${DB} -f ${SCRIPTSDIR}/topology_comments.sql # 任意

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

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

シェルからの実行は次の通りです。

# createdb -T template_postgis my_spatial_db

SQLからの実行は次の通りです。

postgres=# CREATE DATABASE my_spatial_db TEMPLATE=template_postgis

3.4. 空間データベースのアップグレード

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

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

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

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

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

エクステンションを使ってデータベースをインストールした場合には、エクステンションモデルでアップグレードしなければなりません。 古いSQLスクリプトを使ってインストールした場合には、SQLスクリプトは既にサポートされていませんので、エクステンションに切り替えるべきです。

3.4.1.1. 9.1以上でエクステンションを使ったソフトアップグレード

エクステンションを使ってPostGISをインストールした場合には、エクステンションを使ってアップグレードする必要があります。エクステンションを使ったマイナーアップグレードはかなり楽です。

PostGIS 3以上を実行している場合には、PostGIS_Extensions_Upgrade関数を使ってインストールしているもののうち最新の版にアップグレードすべきです。

SELECT postgis_extensions_upgrade();

PostGIS 2.5以前を実行している場合には、次のようにします。

ALTER EXTENSION postgis UPDATE;
SELECT postgis_extensions_upgrade();
-- 二回目の実行はpostgis_rasterエクステンションの再構築に必要です。
SELECT postgis_extensions_upgrade();

インストールされたPostGISに複数のバージョンがあり、最新版にアップグレードしたくない場合には、明示的なバージョンの指定ができます。次のようにします。

ALTER EXTENSION postgis UPDATE TO "3.4.0dev";
ALTER EXTENSION postgis_topology UPDATE TO "3.4.0dev";

次のようなエラー通知が表示されることがあります。

No migration path defined for … to 3.4.0dev

この場合は、データベースをバックアップして、 Section 3.3.1, “エクステンションを使って空間データベースを有効にする” に記述されているように新しいデータベースを生成し、バックアップを新しいデータベースにリストアしなければなりません。

次のようなメッセージを得ることがあります。

Version "3.4.0dev" of extension "postgis" is already installed

この場合は、全てアップデートされていて、安全に無視できます。SVN版から次版 (新しい版番号を得ていないもの)にアップグレードしようとしない限り、"next"を版文字列に追加できます。ただし、次回に"next"を削除する必要があります。

ALTER EXTENSION postgis UPDATE TO "3.4.0devnext";
ALTER EXTENSION postgis_topology UPDATE TO "3.4.0devnext";
[Note]

PostGISをバージョン指定なしにインストールした場合には、 しばしば再格納の前のPostGIS EXTENSIONの再インストールをとばすことができます。 バックアップはCREATE EXTENSION postgisだけで、リストアの間に最新版になります。

[Note]

PostGISエクステンションを3.0.0より前からアップグレードする場合には、ラスタ機能が不要なら、安全に削除できる新しい postgis_rasterエクステンションを持つことになります。次のようにします。

DROP EXTENSION postgis_raster;

3.4.1.2. 9.1より前またはエクステンションを使わないソフトアップグレード

PostGISをエクステンションを使わずにインストールした人向けです。エクステンションを使っていてこの方法を使うと、次のようなメッセージが現れます。

can't drop ... because postgis extension depends on it

ご注意: PostGIS 1.*またはr7429以前のPostGIS 2.*へ移行する場合には、この手続きを使うことができませんが、ハードアップグレードを実行する必要があります。

コンパイルとインストール (make install)の実行後に、インストール先フォルダ内にある*_upgrade.sqlのファイルの集合を見つけておくべきです。次のコマンドで一覧を得られます。

ls `pg_config --sharedir`/contrib/postgis-3.4.0dev/*_upgrade.sql

postgis_upgrade.sqlから順番に全てをロードします。

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

同じ手続きをラスタ、トポロジ、SFCGALエクステンションに適用します。それぞれのファイル名はrtpostgis_upgrade.sql, topology_upgrade.sql, sfcgal_upgrade.sqlになります。次のように実行します。

psql -f rtpostgis_upgrade.sql -d [データベース名]
psql -f topology_upgrade.sql -d [データベース名]
psql -f sfcgal_upgrade.sql -d [データベース名]

エクステンションによるインストールに変更した方が良いです。次のようにします。

psql -c "SELECT postgis_extensions_upgrade();"
[Note]

求める版へのアップグレードに使う特定のpostgis_upgrade.sqlが発見できない場合には、ソフトアップグレードを実行するにはあまりに前の版を使っています。ハードアップグレードが必要です。

PostGIS_Full_Version関数の"procs need upgrade"というメッセージで、この種のアップグレードを実行する必要性についての情報が得られます。

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

ハードアップグレードとは、PostGISで利用可能なデータの完全なダンプ/リロードを意味します。PostGISオブジェクトの内部格納状態が変更される場合や、ソフトアップグレードができない場合に、ハードアップグレードが必要です。付録のリリースノートに、版ごとについて、ダンプ/リロード (ハードアップグレード)の要否を記載しています。

ダンプ/リロード作業はpostgis_restore.plスクリプトが補助します。このスクリプトは、PostGIS (古いものを含む)に属する定義を全て飛ばすように注意します。また、重複シンボルエラーや非推奨オブジェクトを持越すことなく、スキーマとデータをPostGISをインストールしたデータベースにリストアできます 。

Windows用に関する追加情報は Windows Hard upgradeにあります。

手続きは次の通りです。

  1. アップグレードしたデータベース (olddbと呼ぶことにしましょう)の「カスタム書式」のダンプを、バイナリBLOBデータを含めたダンプを指定して (-b)、verboseモード (-v)で生成します。ユーザはデータベースのオーナーになることができ、PostgreSQLのスーパーユーザである必要はありません。

    pg_dump -h localhost -p 5432 -U postgres -Fc -b -v -f "/somepath/olddb.backup" olddb
  2. 新しいデータベースにPostGISを、PostGISが無い状態からインストールします。このデータベースをnewdbと呼ぶことにします。この作業に関する説明についてはSection 3.3.2, “エクステンションを使わずに空間データベースを有効にする (お勧めできません)”Section 3.3.1, “エクステンションを使って空間データベースを有効にする”とを参照して下さい。

    ダンプにあるspatial_ref_sysは、リストアされますが、既にあるspatial_ref_sysを上書きしません。リストア対象のデータベースに公式データセットの訂正が確実に伝わるようにするためです。標準のエントリを上書きしたい場合は、newdbを生成する際にspaltial_ref_sys.sqlファイルをロードしないだけです。

    データベースが本当に古く、ビューや関数に、長く非推奨になっている関数があるような場合には、関数やビューを使えるようにするlegacy.sqlをロードする必要があるでしょう。ただし、本当に必要な場合に限ります。可能なら、ビューや関数をダンプせずにアップグレードすることを検討して下さい。非推奨関数は、uninstall_legacy.sqlで後から削除することができます。

  3. バックアップを新しいnewdbデータベースにリストアするには、postgis_restore.plを使います。psqlが予期せぬエラーを標準エラー出力に出すことがあります。これらのログを保存しておいて下さい。

    perl utils/postgis_restore.pl "/somepath/olddb.backup" | psql -h localhost -p 5432 -U postgres newdb 2
    > errors.txt

エラーは次の場合に起こりえます。

  1. ビューまたは関数の中に非推奨のPostGISオブジェクトを使っているものがある場合。これの訂正には、リストア前にlegacy.sqlスクリプトのロードを試してみることができます。非推奨オブジェクトをまだ持っている版のPostGISにリストアして、コードを作り替えた後に再び移動させることもできます。legacy.sqlを利用する場合は、非推奨関数を使うのをやめたコードに訂正して、uninstall_legacy.sqlをロードするのを忘れないでください。

  2. ダンプファイル内のspatial_ref_sysにあるカスタムレコードが不正なSRIDになっていることがあります。妥当なSRID値は0より大きく999000より小さくなります。999000から999999の間は内部利用のための予約領域ですが、999999より大きい値は一切使用できません。全ての不正なSRIDを持つ独自レコードは、予約領域に移動しても保持されます。しかし、spatial_ref_sysテーブルから、値が保持されるように設定されているチェック制約が外れます。場合によっては (複数の不正なSRIDが同じ予約領域のSRID値に変換されるとき)、主キーも外れます。

    これを修正するために、独自のSRSを妥当な値 (910000..910999の範囲)のSRIDに複写し、全てのテーブルを新しいSRIDに変更 (UpdateGeometrySRID参照)し、spatial_ref_sysから不正なエントリを削除します。そして、次のようにチェック制約を再構築します。

    ALTER TABLE spatial_ref_sys ADD CONSTRAINT spatial_ref_sys_srid_check check (srid > 0 AND srid < 999000 );

    ALTER TABLE spatial_ref_sys ADD PRIMARY KEY(srid));

    フランス IGN 地図を含む古いデータベースをアップグレードする場合には、おそらくSRIDが範囲外になり、データベースのインポート時に次のような問題に遭遇します。

     WARNING: SRID 310642222 converted to 999175 (in reserved zone)

    この場合には、次のステップを試すことができます。最初にpostgis_restore.plから出たIGNをSQLから完全に破棄します。そのために次のコマンドを実行します。

    perl utils/postgis_restore.pl "/somepath/olddb.backup" 
    > olddb.sql

    さらに、次のコマンドを実行します。

    grep -v IGNF olddb.sql 
    > olddb-without-IGN.sql

    その後、新しいデータベースを生成し、必要なPostGISエクステンションを有効化して、 このスクリプト で確実にフランスIGNの系を挿入します。これらの処理の後、次のようにデータのインポートを行います。

    psql -h localhost -p 5432 -U postgres -d newdb -f olddb-without-IGN.sql  2
    > errors.txt

Chapter 4. データ管理

4.1. 空間データ モデル

4.1.1. OGC ジオメトリ

Open Geospatial Consortium (OGC)は、地理空間データのモデルを提供するためにSimple Features Access (SFA)標準を開発しました。これは、ジオメトリ (Geometry)の基本的な空間タイプを、空間解析処理実行のための操作や変換といった演算に沿って定義します。PostGISは空間解析タスクを実現するためにOGCジオメトリモデル値をPostgreSQLデータ型のgeometrygeographyとして実装しています。

ジオメトリは抽象的なタイプです。ジオメトリ値は複数ある具体的なサブタイプの一つに属します。サブタイプは様々な種類の様々な次元のジオメトリの形状を表現するものです。これらには原子的なタイプであるポイント (Point)ラインストリング (LineString)リニアリング (LinearRing)ポリゴン (Polygon)があります。また、コレクション (collection) (訳注: 「マルチ系」と書いている場合があります)タイプのマルチポイント (MultiPoint)マルチラインストリング (MultiLineString)マルチポリゴン (MultiPolygon)ジオメトリコレクション (GeometryCollection)があります。 Simple Features Access - Part 1: Common architecture v1.2.1では多面体サーフェス (PolyhedralSurface)三角形 (Triangle)TINが追加されています。

ジオメトリは2次元デカルト平面上の形状をモデル化しています。多面体サーフェス、三角形、TINは3次元空間内の形状を表現することもできます。形状のサイズと位置は座標によって指定されます。それぞれの座標は、平面上で位置を判定するXとYの座標軸値を持っています。形状はポイントと線分から構築され、ポイントは単一の座標で定められ、線分は二つの座標値から定められます。

座標は任意軸ZとMを持つことができます。Z軸はしばしば標高を示すために使われます。M軸は計測値が入りますが、計測値は時間であったり距離であったりします。Z値またはM値はジオメトリ値の中にあり、ジオメトリの各ポイントで定義されているものです。ジオメトリがZ値またはM値を持っている場合には座標次元は三次元です。Z値とM値の両方を持っている場合には四次元です。

ジオメトリ値は、そのジオメトリが組み込まれている座標系を示す空間参照系に関連付けられます。空間参照系はジオメトリのSRID番号で識別されます。X軸とY軸の単位は空間参照系によって決まります。平面参照系では伝統的にX座標値とY座標値が東、北をそれぞれ示します。地理参照系では、経度と緯度を表現しています。SRIDが0の場合には、軸の単位が無い、無限の直交平面を表します。Section 4.5, “空間参照系”を参照して下さい。

ジオメトリの次元は、ジオメトリタイプのプロパティです。ポイントタイプは0次元、ラインタイプは1次元、ポリゴンタイプは2次元、コレクションは要素の次元の最大値、となります。

ジオメトリ値はemptyになることがあります。空値とは、非マルチ系ジオメトリの場合は頂点を持っていないという意味で、コレクションでは要素を持っていないという意味です。

ジオメトリ値の重要なプロパティは範囲 (extent)またはバウンディングボックス (bounding box)です。OGCモデルではエンベロープ (envelope)と呼ばれています。これは、ジオメトリの座標を囲む2次元または3次元のボックスです。ジオメトリの座標空間内の範囲を表現するための、また、二つのジオメトリの相互関係をチェックするための、効率の良い方法です。

ジオメトリモデルでは、Section 5.1.1, “Dimensionally Extended 9-Intersection Model”に示されている通り、トポロジ空間関係を評価することができます。これに対応するために、内部 (interior)境界 (boundary)外部 (exterior)の概念が、ジオメトリタイプ毎に定義されます。ジオメトリはトポロジ的に閉じていて、常に境界を持っています。境界の次元はジオメトリの次元より1小さくなります。

OGCジオメトリモデルは、ジオメトリタイプ毎に妥当性規則が定義されています。これらの規則によって、ジオメトリ値が現実的な状況を示すようになります (たとえば、外部に穴を持つポリゴンを指定できますが、ジオメトリ的に無意味であり、よって不正とします)。PostGISは不正なジオメトリ値を格納、操作することができます。これによって、必要なら修正できることになります。Section 4.4, “ジオメトリ検証”を参照して下さい。

4.1.1.1. ポイント (Point)

ポイントは、座標空間内の一つの位置を表現する0次元ジオメトリです。

POINT (1 2)
POINT Z (1 2 3)
POINT ZM (1 2 3 4)

4.1.1.2. ラインストリング (LineString)

ラインストリングは連続する一連の線分で形成される1次元のラインです。線分はそれぞれ2点で定義付けられ、ある線分の終点は次の線分の始点を形成します。OGC妥当なラインストリングには、0または2以上のポイントがあります。ただしPostGISはラインストリングの一つのポイントを許容します。ラインストリングは、自身とクロスする場合があります (自己交差)。始端と終端とが同じ場合にはラインストリングは閉じたことになります。自己交差しない場合には、ラインストリングは単純です。

LINESTRING (1 2, 3 4, 5 6)

4.1.1.3. リニアリング (LinearRing)

リニアリングは閉じていて、かつ単純なラインスリングです。始端と終端は同じでなければなりませんし、ラインは自己交差してはなりません。

LINEARRING (0 0 0, 4 0 0, 4 4 0, 0 4 0, 0 0 0)

4.1.1.4. ポリゴン (Polygon)

ポリゴンは2次元平面領域です。一つの外側の境界 (殻)と0個以上の内の境界 (穴)とで区切られています。それぞれの境界はリニアリングです。

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))

4.1.1.5. マルチポイント (MultiPoint)

マルチポイントはポイントのコレクションです。

MULTIPOINT ( (0 0), (1 2) )

4.1.1.6. マルチラインストリング (MultiLineString)

マルチラインストリングはラインストリングのコレクションです。各要素が閉じている場合には、そのマルチラインストリングは閉じています。

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

4.1.1.7. マルチポリゴン (MultiPolygon)

マルチポリゴンは相互にオーバラップも隣接もしていないポリゴンのコレクションです。コレクション内のポリゴンの接触は有限数のポイントでのみ可能です。

MULTIPOLYGON (((1 5, 5 5, 5 1, 1 1, 1 5)), ((6 5, 9 1, 6 1, 6 5)))

4.1.1.8. ジオメトリコレクション (GeometryCollection)

ジオメトリコレクションは、ジオメトリの異種 (混合)のコレクションです。

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

4.1.1.9. 多面体サーフェス (PolyhedralSurface)

多角形はサーフェスは、パッチまたはエッジを共有する面の隣接するコレクションです。それぞれのパッチは平面ポリゴンです。ポリゴンがZ値を持つ場合には、サーフェスは3次元になります。

POLYHEDRALSURFACE Z (
  ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),
  ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),
  ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),
  ((1 1 0, 1 1 1, 1 0 1, 1 0 0, 1 1 0)),
  ((0 1 0, 0 1 1, 1 1 1, 1 1 0, 0 1 0)),
  ((0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1)) )

4.1.1.10. 三角形 (Triangle)

三角形は三つの異なる非共線頂点で定義されるポリゴンです。三角形はポリゴンですので、四つの座標で指定され、一つ目と四つ目は同じです。

TRIANGLE ((0 0, 0 9, 9 0, 0 0))

4.1.1.11. TIN

TINはTriangulated Irregular Networkを表現する、オーバラップしない三角形のコレクションです。

TIN Z ( ((0 0 0, 0 0 1, 0 1 0, 0 0 0)), ((0 0 0, 0 1 0, 1 1 0, 0 0 0)) )

4.1.2. SQL/MM Part 3 - 曲線

ISO/IEC 13249-3 SQL Multimedia - Spatial標準 (SQL/MM) は、OGC SFAを拡張して、曲線ジオメトリを含むサブタイプを定義しています。SQL/MMタイプはXYM, XYZ, XYZMに対応します。

[Note]

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

4.1.2.1. 曲線ストリング (CircularStringCircularString)

曲線ストリングは、基本的な曲線タイプです。線形の世界のラインストリングに似ています。単一の円弧線分は、始点、終点 (1番目と3番目)、弧の他の点の三つの点で定義されます。閉じた円を指定するには、開始点と終了点を同じにし、中間点を対称点 (円弧の中心)に置きます。連続する円弧では、前の円弧の終端と次の円弧の始端とが同じです。よって曲線ストリングは1以上の奇数個のポイントを持つことになります。

CIRCULARSTRING(0 0, 1 1, 1 0)

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

4.1.2.2. 複合曲線 (CompoundCurve)

複合曲線は、曲線区間と直線区間の両方を含むことができる単一の連続した曲線です。このことは、整形された要素を持つことに加えて、全ての要素の最後のポイントは次の要素の最初のポイントでなければならないことを意味します。

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

4.1.2.3. 曲線ポリゴン (CurvePolygon)

曲線ポリゴンは、外側の輪がひとつで0以上の内側のリングがある点はポリゴンに似ています。違いは、ポリゴンのリングはラインストリングですが曲線ポリゴンのリングは曲線ストリングまたは複合ストリングである点です。

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

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

例: CIRCULARSTRINGとLINESTRINGからなるCOMPOUNDCURVEで定義される外殻を持ち、CIRCULARSTRINGで定義される穴を持つCURVEPOLYGON

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) )

4.1.2.4. マルチ曲線 (Multicurve)

マルチ曲線は曲線のコレクションで、ラインストリング、曲線ストリング、複合曲線を含むことができます。

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

4.1.2.5. マルチサーフェス (MultiSurface)

マルチサーフェスはサーフェスのコレクションです。サーフェスは(線形)ポリゴンまたは曲線ポリゴンとなることができます。

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)))

4.1.3. WKTとWKB

OGC SFA仕様では、ジオメトリ値を外部で使用するための表現として二つの標準書式が定義されています。Well-Known Text (WKT)とWell-Known Binary (WKB)です。WKTとWKBは両方ともそのオブジェクトを定義するタイプと座標に関する情報を含んでいます。

Well-Known Text (WKT)で空間データの標準的な文字表現が可能です。空間オブジェクトのWKT表現の例を次に挙げます。

  • POINT(0 0)

  • POINT Z (0 0 0)

  • POINT ZM (0 0 0 0)

  • POINT EMPTY

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

  • LINESTRING EMPTY

  • 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))

  • MULTIPOINT Z ((0 0 0),(1 2 3))

  • MULTIPOINT EMPTY

  • 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))

  • GEOMETRYCOLLECTION EMPTY

WKTの入出力は関数ST_AsTextST_GeomFromTextによって提供されます。

text WKT = ST_AsText(geometry);
geometry = ST_GeomFromText(text WKT, SRID);

例えば、WKTとSRIDからの空間オブジェクトの生成と挿入のステートメントは次の通りです。

INSERT INTO geotable ( geom, name )
  VALUES ( ST_GeomFromText('POINT(-126.4 45.32)', 312), 'A Place');

Well-Known Binary (WKB)は、空間データのバイナリデータ (バイト列)で、移植可能かつ正確な表現です。空間オブジェクトのWKB表現を次に挙げます。

  • WKT: POINT(1 1)

    WKB: 0101000000000000000000F03F000000000000F03

  • WKT: LINESTRING (2 2, 9 9)

    WKB: 0102000000020000000000000000000040000000000000004000000000000022400000000000002240

WKBの入出力は関数ST_AsBinaryST_GeomFromWKBが提供されています。次のように使います。

bytea WKB = ST_AsBinary(geometry);
geometry = ST_GeomFromWKB(bytea WKB, SRID);

たとえば、WKBから空間オブジェクトの生成、挿入は次のようにします。

INSERT INTO geotable ( geom, name )
  VALUES ( ST_GeomFromWKB('\x0101000000000000000000f03f000000000000f03f', 312), 'A Place');

4.2. ジオメトリデータタイプ

PostGISは、geometryというPostgreSQIデータ型を定義して、OGC Simple Features model を実装しています。これで、内部タイプコード (GeometryTypeST_GeometryType参照)で全てのジオメトリのサブタイプを表現します。これにより、カラム型で定義されたテーブルの行として、空間地物をモデリングすることが可能となります。

geometryデータ型は透過です。ジオメトリ値に関する関数から全てにアクセスできることを意味します。関数によって、ジオメトリオブジェクトの生成、全ての内部フィールドへのアクセスと更新、新しいジオメトリ値の計算が可能です。PostGISは、OGC Simple feature access - Part 2: SQL option (SFS)仕様で定義されている全ての関数に、他の多数の関数とあわせて対応しています。関数の完全な一覧はChapter 8, PostGISリファレンスをご覧下さい。

[Note]

PostGISは、空間関数にプリフィクス"ST_"を付けて、SFA標準に従っています。これは、"Spatial and Temporal (空間と時間)"を示していますが、標準の時間の部分はまだ開発していません。その代わりに"Spatial Type (空間タイプ)"と解釈できます。

SFA標準は、空間オブジェクトは空間参照系識別子 (SRID)を含むと規程しています。SRIDは、空間オブジェクトをデータベースに挿入するために生成した時に求められます (デフォルトとして0になるかも知れません)。ST_SRIDSection 4.5, “空間参照系”をご覧下さい。

ジオメトリのクエリを効率的にするため、PostGISでは様々な種類の空間インデクスを定義しています。詳細についてはSection 4.9, “空間インデックス”Section 5.2, “空間インデックスを使う”をご覧下さい。

4.2.1. PostGIS EWKBとEWKT

OGC SFA仕様は、まず2次元ジオメトリのみに対応しました。また、入出力表現にジオメトリのSRIDは取り入れていまません。OGC SFA仕様 1.2.1 (ISO 19125標準に準拠)では3次元 (XYZ)とM値 (XYMとXYZM)座標に対応するようになりましたが、SIRD値の取り込みは依然行われていません。

これらの制限のため、PostGISでは拡張書式であるEWKBとEWKTを定義しました。3次元 (XYZ, XYM)と4次元 (XYZN)座標系に対応し、SRID情報を取り込めるようにしました。すべてのジオメトリ情報を含めたので、PostGISはEWKBを格納用書式 (DUMPファイル等)として使えるようになりました。

PostGISデータオブジェクトの「カノニカルな形式」のためにEWKBとEWKTを使います。入力では、バイナリデータのカノニカルな形式はEWKB、テキストデータについてはEWKBかEWKTが受け付けられます。これにより、HEXEWKBまたはEWKTのテキスト値から::geometryを使用してキャストを行い、ジオメトリ値が生成できるようになりました。出力では、バイナリのカノニカルな形式はEWKBで、テキストはHEXEWKB (HEXエンコードを施したEWKB)です。

たとえば、この手続きでは、EWKTテキスト値からのキャストでジオメトリを生成して、HEXWKBのカノニカルな形式を使った出力を行います。

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

PostGIS EWKT出力はOGC WKTと次の通り相違点があります。

  • XYZジオメトリでZ修飾子が省略されます。

    OGC: POINT Z (1 2 3)

    EWKT: POINT (1 2 3)

  • M値を含むXYMジオメトリ:

    OGC: POINT M (1 2 3)

    EWKT: POINTM (1 2 3)

  • 4次元ジオメトリでZM修飾子を省略:

    OGC: POINT ZM (1 2 3 4)

    EWKT: POINT (1 2 3 4)

EWKTは、次のようにOGC/ISO書式で発生しうる過剰次元と不整合を回避しています。

  • POINT ZM (1 1)

  • POINT ZM (1 1 1)

  • POINT (1 1 1 1)

[Caution]

PostGISの拡張書式はOGC書式の上位互換であり、全ての妥当なOGC WKB/WKTは妥当なEWKB/EWKTでもあります。しかし、OGCがPostGISの定義と衝突する方法で書式を拡張した場合には、将来的に書式を変更する可能性があります。ゆえに、この互換性に*頼るべきではありません*!

空間オブジェクトのEWKTテキスト表現の例:

  • POINT(0 0 0) -- XYZ

  • SRID=32632;POINT(0 0) -- SRID付きXY

  • 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) )

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

  • POLYHEDRALSURFACE( ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)), ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)), ((1 1 0, 1 1 1, 1 0 1, 1 0 0, 1 1 0)), ((0 1 0, 0 1 1, 1 1 1, 1 1 0, 0 1 0)), ((0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1)) )

  • TRIANGLE ((0 0, 0 10, 10 0, 0 0))

  • TIN( ((0 0 0, 0 0 1, 0 1 0, 0 0 0)), ((0 0 0, 0 1 0, 1 1 0, 0 0 0)) )

これらの書式を使う入出力は次の関数を使うと有効です。

バイト配列 EWKB = ST_AsEWKB(geometry);
テキスト EWKT = ST_AsEWKT(geometry);
ジオメトリ = ST_GeomFromEWKB(bytea EWKB);
ジオメトリ = ST_GeomFromEWKT(text EWKT);

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

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

4.3. ジオグラフィデータタイプ

geographyデータタイプによって地理座標 ("geographic", "geodetic", "lat/lon", "lon/lat"など)上の空間地物表現にネイティブに対応できます。地理座標系は角度 (度)単位で表現される球面座標系です。

PostGISジオメトリ型の基礎は平面です。平面上の2点間の最短経路は直線です。ジオメトリに関する関数 (面積、距離、長さ、インタセクション等)は直線ベクトルとデカルト平面を使って計算しています。これで実装が簡単になり実行速度も上がりますが、地球の球面の上にあるデータについては不正確になります。

PostGISジオグラフィというデータ型は球面モデルに基づいています。球面上の2点の最短経路は大円の弧にあたります。ジオグラフィの関数 (面積、距離、長さ、インタセクション等)は球面上の弧を使います。球面上の世界の形状を考慮に入れるので、より正確な結果が得られます。

基礎となる数学はより複雑になるため、ジオグラフィ型で定義された関数はジオメトリ型で定義された関数よりも少なくなります。時間が経つにつれて新しいアルゴリズムが追加されて、ジオグラフィの機能が拡大していきます。回避策として、ジオメトリ型とジオグラフィ型との相互変換が可能です。

ジオグラフィ型は、ジオメトリ型のように、空間参照系識別子 (SRID)を介して空間参照系と関連付けられます。spatial_ref_sysテーブルで定義されているあらゆる地理空間参照系 (経度/緯度を使う)が使えます (PostGIS 2.2より前ではジオグラフィ型はWGS 84地理座標系 (SRID:4326)にのみ対応していました)。Section 4.5.2, “ユーザ定義空間参照系”に書いている通り、独自の空間参照系を追加することもできます。

計測関数 (例 ST_DistanceST_LengthST_PerimeterST_Area)によって返されるものの単位と、ST_DWithinの引数で与えられる距離との、空間参照系の単位は、メートルです。

4.3.1. ジオグラフィテーブルの生成

ジオグラフィデータを格納するテーブルは、SQLステートメントCREATE TABLEgeography型のカラムを付けることで生成することができます。2次元ラインストリングをWGS84地理座標系 (SRID 4326)で保存するジオグラフィカラムを持つテーブルを生成する例を次に示します。

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

二つの任意の型修飾子に対応するジオグラフィ型:

  • 空間の型修飾子は、カラム内で許される形状の種類や次元を規制します。値によって空間型はPOINT、LINESTRING、POLYGON、MULTIPOINT、MULTILINESTRING、MULTIPOLYGON、GEOMETRYCOLLECTIONが可能です。ジオグラフィ型は曲線や三角形、多面体サーフェスに対応していません。型修飾子に後置詞Z、M、ZMを付けることで、座標次元の制約に対応しています。たとえば、'LINESTRINGM'は、3次元で3番目の軸はMであるラインストリングのみを許します。同様に'POINTZM'では4次元 (XYZM)データが求められます。

  • SRID修飾子は空間参照系(SRID)を特定の数値になるよう制約します。省略した場合には、デフォルトは4326 (WGS84地理座標系)となり、全ての計算はWGS84を使ったものになります。

ジオグラフィカラムを持つテーブルの生成の例を次に挙げます。

  • SRIDがデフォルトの4326 (WGS84 経度/緯度)である2次元ポイントジオグラフィを持つテーブルの生成:

    CREATE TABLE ptgeogwgs(gid serial PRIMARY KEY, geog geography(POINT) );
  • NAD83緯度/経度の2次元ポイントジオグラフィを持つテーブルの生成:

    CREATE TABLE ptgeognad83(gid serial PRIMARY KEY, geog geography(POINT,4269) );
  • SRIDを4326で明示した3次元 (XYZ)ポイントジオグラフィを持つテーブルの生成:

    CREATE TABLE ptzgeogwgs84(gid serial PRIMARY KEY, geog geography(POINTZ,4326) );
  • SRIDがデフォルトの4326である2次元ラインストリングジオグラフィを持つテーブルの生成:

    CREATE TABLE lgeog(gid serial PRIMARY KEY, geog geography(LINESTRING) );
  • SRIDがデ4326 (NAD 1927 経度/緯度)である2次元ポリゴンジオグラフィを持つテーブルの生成:

    CREATE TABLE lgeognad27(gid serial PRIMARY KEY, geog geography(POLYGON,4267) );

ジオグラフィカラムはgeography_columnsシステムビューに登録されます。geography_columnsビューにクエリを出してテーブルを見るには、次の通りにします。

SELECT * FROM geography_columns;

空間インデックスはジオメトリカラムと同じように機能します。PostGISは、カラム型がジオグラフィであると通知したうえで、ジオメトリに使う通常の平面用インデックスでなく、球面を基にした適切なインデックスを生成します。

-- testテーブルに球面インデックスを作成
CREATE INDEX global_points_gix ON global_points USING GIST ( location );

4.3.2. ジオグラフィテーブルの使用

ジオメトリと同じ方法でジオグラフィテーブルにデータを挿入できます。ジオメトリデータは、SRID 4326の場合には、ジオグラフィ型に自動キャストされます。EWKTとEWKB書式はジオグラフィ値を指定するために使うことができます。

-- testテーブルにデータを追加する
INSERT INTO global_points (name, location) VALUES ('Town', 'SRID=4326;POINT(-110 30)');
INSERT INTO global_points (name, location) VALUES ('Forest', 'SRID=4326;POINT(-109 29)');
INSERT INTO global_points (name, location) VALUES ('London', 'SRID=4326;POINT(0 49)');

spatial_ref_sysテーブルにある地理 (経度/緯度)参照系は、ジオグラフィのSRIDとして指定することができます。非地理座標系を使うとエラーが発生します。

-- NAD 83 経度/緯度
SELECT 'SRID=4269;POINT(-123 34)'::geography;
                    geography
----------------------------------------------------
 0101000020AD1000000000000000C05EC00000000000004140
-- NAD27 経度/緯度
SELECT 'SRID=4267;POINT(-123 34)'::geography;
                    geography
----------------------------------------------------
 0101000020AB1000000000000000C05EC00000000000004140
-- NAD83 UTM zone メートル単位 - メートル単位の平面投影法なのでエラーが発生します
SELECT 'SRID=26910;POINT(-123 34)'::geography;

ERROR:  Only lon/lat coordinate systems are supported in geography.

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

-- 1000km範囲の距離に関するクエリ
SELECT name FROM global_points WHERE ST_DWithin(location, 'SRID=4326;POINT(-110 29)'::geography, 1000000);

シアトルからロンドンへの (LINESTRING(-122.33 47.606, 0.0 51.5))大円航路を行く航空機がレイキャビク (POINT(-21.96 64.15)) にどれだけ近づくかを計算することで、ジオグラフィの力を見ことができます (航路の地図表示)。

ジオグラフィ型は、レイキャビクとシアトル-ロンドン間の大円航路との距離について、球面上で122.235 kmという本当の最短距離を計算します。

-- GEOGRAPHYを使った距離計算
SELECT ST_Distance('LINESTRING(-122.33 47.606, 0.0 51.5)'::geography, 'POINT(-21.96 64.15)'::geography);
   st_distance
-----------------
 122235.23815667

ジオメトリ型では、平面の世界地図上で見て、レイキャビクとシアトル-ロンドン間の直線とのデカルト距離が計算され、意味がありません。計算結果の名目上の単位は「度」ですが、点間の本当の角度差に応じるものではなく、「度」と呼ぶこと自体が不正確です。

-- GEOMETRYを使った距離計算
SELECT ST_Distance('LINESTRING(-122.33 47.606, 0.0 51.5)'::geometry, 'POINT(-21.96 64.15)'::geometry);
      st_distance
--------------------
 13.342271221453624

4.3.3. ジオグラフィ型を使用すべき時

ジオグラフィ型によって、経度緯度座標でデータを格納できるようになりましたが、ジオグラフィで定義されている関数が、ジオメトリより少ないのと、実行にCPU時間がかかる、というところが犠牲になっています。

選択した型が、期待する領域から出ないことを、ジオメトリ型にして使用する条件とすべきです。使用するデータは地球全体か、大陸か、州か、自治体か?

  • データが小さいエリア内におさまるなら、適切な投影を選択してジオメトリを使うのが、効率面でも機能面でも最も良い方法です。

  • データが地球全体か大陸なら、ジオグラフィで投影法の細かい問題を気にせずにシステムを構築できるでしょう。経度/緯度のデータを保存して、ジオグラフィで定義された関数使います。

  • 投影法を理解していなくて、学習したくもなくて、かつ、ジオグラフィで使える関数が限られていることを受け入れるのなら、ジオグラフィを使った方が簡単です。単純にデータを経度/緯度でロードして、そこから進めて下さい。

ジオグラフィとジオメトリ間のサポート状況の比較についてはSection 15.11, “PostGIS Function Support Matrix”をご覧下さい。ジオグラフィ関数の簡潔なリストと説明についてはSection 15.4, “PostGIS Geography Support Functions”をご覧下さい。

4.3.4. ジオグラフィに関する高度なよくある質問

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

4.3.4.1.

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

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

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

4.3.4.2.

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

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

4.3.4.3.

処理できる最も長い弧はどうなりますか?

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

4.3.4.4.

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

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

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

4.4. ジオメトリ検証

PostGISはOpen Geospatial Consortium (OGC)のSimple Feature Specificationに準拠しています。この標準では、単純なジオメトリと妥当なジオメトリの概念が定義されています。これらの定義によって、Simple Featureのジオメトリモデルが一貫性があって、かつ明確な方法で空間オブジェクトを表現することができ、効率的な計算を助けます (OGC Simple FeatureとSQL/MMとにおいては、単純性と妥当性について同じ定義です)。

4.4.1. 単純ジオメトリ

単純なジオメトリは、自己交差や自己接触といった異常な幾何学上のポイントを持たないジオメトリです。

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

MULTIPOINTは、任意の二つの座標値 (POINT)が同じでないなら単純です。

LINESTRINGは、同じポイントを二回通過しないものが単純です。単純なラインストリングの端点が同一の場合には、閉じているとされ、線形リングと呼ばれます。

(a)(c)は単純なLINESTRINGです。(b)(d)は単純ではありません。(c)は閉じた線形リングです。

(a)

(b)

(c)

(d)

MULTILINESTRINGは、要素が全て単純で、かつ、全ての要素同士のインタセクションが要素の境界上でのみ出現する場合には、単純です。

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

(e)

(f)

(g)

POLYGONは線形リングから形成されるので、妥当なポリゴンジオメトリは常に単純です。

ジオメトリが単純かどうかを試すにはST_IsSimple関数を使います。次のようにします。

SELECT
   ST_IsSimple('LINESTRING(0 0, 100 100)') AS straight,
   ST_IsSimple('LINESTRING(0 0, 100 100, 100 0, 0 100)') AS crossing;

 straight | crossing
----------+----------
 t        | f

一般的にPostGIS関数は引数ジオメトリの単純性を求めていません。単純性は主にジオメトリの妥当性を定義するための基礎として用いられます。空間データモデルによっては要件としていることもあります (たとえば、線形ネットワークはしばしばクロスを認めません)。マルチポイントと線形ジオメトリはST_UnaryUnionを使って単純にできます。

4.4.2. 妥当なジオメトリ

ジオメトリの妥当性は主に2次元ジオメトリ (POLYGONMULTIPOLYGON)に適用されます。妥当性はポリゴンジオメトリが平面領域を明確にモデル化できる規則によって定義されます。

POLYGONは次の条件では妥当です。

  1. ポリゴン境界リング (外側の殻リングと内側の穴リング)が単純 (交差も自己接触もしていない)であること。これによりポリゴンは切断線、トゲ、循環を持つことができなくなります。これは、ポリゴンの穴を外側のリングの自己接触 (いわゆる "inverted hole" (逆穴))でなく、内側のリングとして表現されなけれならないことを意味します。

  2. 境界リングがクロスしないこと

  3. 境界リングは点で接触したとしても接点として接触すること (線上にあってはなりません)

  4. 内側リングは外側リング内にあること

  5. ポリゴン内部は単純に接続されていること (リングはポリゴンを複数に分割するように接触してはなりません)

(h)(i)は妥当なPOLYGONです。(j-m)は不正です。(j)は妥当なMULTIPOLYGONとして表すことができます。

(h)

(i)

(j)

(k)

(l)

(m)

MULTIPOLYGONは次の条件では妥当です。

  1. 要素となるPOLYGONが妥当であること

  2. 要素がオーバラップしない (内部同士がインタセクトしない)こと

  3. 要素同士の接触が点でけである (線に沿って接触しない)こと

(n)は妥当なMULTIPOLYGONです。(o)(p)は不正です。

(n)

(o)

(p)

これらの規則は妥当なポリゴンジオメトリも単純であることも示しています。

線ジオメトリについては、LINESTRINGが少なくとも二つのポイントを持ち、長さが0でない (少なくとも二つの異なるポイントを持つことと同じ)、というのが唯一の妥当性規則です。単純でない (自己交差がある)ラインは妥当です。

SELECT
   ST_IsValid('LINESTRING(0 0, 1 1)') AS len_nonzero,
   ST_IsValid('LINESTRING(0 0, 0 0, 0 0)') AS len_zero,
   ST_IsValid('LINESTRING(10 10, 150 150, 180 50, 20 130)') AS self_int;

 len_nonzero | len_zero | self_int
-------------+----------+----------
 t           | f        | t

POINTMULTIPOINTは妥当性規則を持っていません。

4.4.3. 妥当性の管理

PostGISは妥当なジオメトリも不正なジオメトリも、生成も格納もできます。このため、不正なジオメトリを検出し、フラグを付け、訂正することができます。OGC妥当性規則が求める規則 (長さが0のラインストリングや逆穴を持つポリゴン等)よりも厳格であることもあります。

PostGISが提供する関数の多くは、引数ジオメトリが妥当であるとの仮定によっています。たとえば、ポリゴンの外部に穴があるポリゴンの面積を計算しても意味がありませんし、単純でない境界線からポリゴンを形成するのも意味がありません。妥当なジオメトリ入力を仮定することで、トポロジ的に正しいことを確認する必要がなくなるので、関数がより効率的に動作することができます (例外として、長さ0のラインと反転したポリゴンは一般的に正しく取り扱われます)。また、ほとんどのPostGIS関数は、入力ジオメトリが妥当な場合には、妥当なジオメトリ出力を生成します。これにより、PostGIS関数を安全に連鎖させられます。

PostGIS関数を呼ぶときに予期しないエラーメッセージ ("GEOS Intersection() threw an error!"等)に遭遇する場合には、まず関数の引数が妥当かどうかを確認します。妥当でないなら、次に示す方法のいずれかによる、処理中のデータの妥当性の確認を検討して下さい。

[Note]

関数が妥当な入力でエラーを報告する場合には、PostGISまたは使用しているライブラリの一つの中にエラーがあるのを発見することがありますが、その際はPostGISプロジェクトに報告して下さい。PostGIS関数が妥当な入力から不正なジオメトリを返す場合も同様です。

ジオメトリが妥当かをテストするにはST_IsValid関数を使います。次のようにします。

SELECT ST_IsValid('POLYGON ((20 180, 180 180, 180 20, 20 20, 20 180))');
-----------------
 t

ジオメトリの不正性の性質と位置に関する情報はST_IsValidDetail関数で得られます。次のようにします。

SELECT valid, reason, ST_AsText(location) AS location
    FROM ST_IsValidDetail('POLYGON ((20 20, 120 190, 50 190, 170 50, 20 20))') AS t;

 valid |      reason       |                  location
-------+-------------------+---------------------------------------------
 f     | Self-intersection | POINT(91.51162790697674 141.56976744186045)

不正なジオメトリを自動的に訂正することが望ましいような状況があります。その際はST_MakeValid関数を使います (ST_MakeValidは不正な入力を許す特別な関数です)。

複雑なジオメトリの不正性テストには多大なCPU時間を取ることになるため、デフォルトでは、ジオメトリのロード時にPostGISは妥当性の確認をしません。データソースが信用できない場合には、チェック制約を使って、テーブル上で妥当性を強制的に確認することができます。次のようにします。

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

4.5. 空間参照系

空間参照系 (Spatial Reference System, SRS) (座標参照系、Coordinate Reference System, CRSとも呼ばれます)は、ジオメトリが地表上の位置をどのように参照するかを定義しています。SRSには次の通り三種あります。

  • 測地 (geodetic) 空間参照系は、地表に直接対応付けられる極座標系 (経度と緯度)を使います。

  • 投影 (projected)空間参照系は、回転楕円体面を「平面にする」ための数学的な投影変換を使います。距離、面積、角度といった量を直接計測することが可能な位置座標系です。この座標系はデカルト座標系ですので、原点と二つの直交軸 (通常は来北と東方向)が定義されています。個々の投影座標系は、定まった距離単位 (通常はメートルかフィート)を使います。投影座標系は、歪みを避けて定義された座標範囲に納めるために、適応範囲を制限してもいいことになっています。

  • 局所 (local)座標系は、地表への参照がないデカルト座標系です。PostGISではSRID値を0に指定します。

使用されている空間参照系には多数の相違点があります。一般的空間参照系は欧州石油調査グループ (European Petroleum Survey Group)のEPSG databaseで標準化されています。利便性向上のためPostGIS (と多くの空間系)はSRIDと呼ぶ整数を使って空間参照系の定義を参照します。

ジオメトリは、SRID値で空間参照系に関連付けられています。SRID値の取得にはST_SRIDを使います。ジオメトリのSRIDの設定にはST_SetSRIDを使います。ジオメトリ構築関数の中には、SRIDを与えられるものもあります (ST_PointST_MakeEnvelope等)。EWKT書式はSRID=n;を前置することでSRIDに対応できます。

二つのジオメトリを処理する空間関数 (オーバレイ関数空間関係関数等)では、入力ジオメトリが同じ空間参照系でなければなりません (同じSRID値を持たなければなりません)。ジオメトリデータはST_Transformを使うと異なる空間参照系に変換できます。関数から返されるジオメトリは入力ジオメトリと同じ空間参照系を持ちます。

4.5.1. SPATIAL_REF_SYSテーブル

PostGISが使用するSPATIAL_REF_SYSテーブルは利用可能な空間参照系を定義するOGC準拠のデータベーステーブルです。このテーブルは、数値でSRIDを持ち、文字列で座標系の記述を持っています。

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)
)

カラムは次の通りです。

srid

データベース内のSpatial Reference System (SRS, 空間参照系)で一意に識別される整数コードです。

auth_name

この参照系に引用されている標準の名前もしくは標準そのものです。たとえば「EPSG」は妥当なauth_nameです。

auth_srid

空間参照系のIDはauth_nameに引用される機関によって定義されます。ここが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]
]

SRS WKTの詳細については、OGC標準のWell-known text representation of coordinate reference systemsをご覧下さい。

proj4text

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

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

詳細情報についてはPROJウェブサイトをご覧下さい。spatial_ref_sys.sqlファイルには、全てのEPSG投影について、srtextproj4textの定義があります。

投影変換で空間参照系の定義を使用する場合には、次の戦略を取ります。

  • auth_nameauth_sridがある (NULLでない)場合には、これに基づいてPROJSRSを使います (存在する場合)。

  • srtextがある場合には、可能ならそれを使用してSRSを生成します。

  • proj4textがある場合には、可能ならこれを使用してSRSを生成します。

4.5.2. ユーザ定義空間参照系

PostGISspatial_ref_sysテーブルにはPROJ投影ライブラリで処理される最も一般的な空間参照系定義3000件以上があります。しかし、そこに無い多くの座標系があります。空間参照系に関する必要な情報がある場合は、SRS定義をテーブルに追加できます。PROJに詳しいなら独自の空間参照系を定義することもできます。ほとんどの空間参照系は地域的なものであり、目的の範囲外で使用する場合は意味を持たない点に注意してください。

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

一般的に使用される空間参照系には4326 - WGS 84経度緯度4269 - NAD 83 経度緯度3395 - WGS 84 メルカトル2163 - 米国ナショナルアトラス正積図法、60個のWGS84 UTMゾーンがあります。UTMゾーンは計測に最適ですが、6度 (訳注: 経度)の領域のみをカバーします (対象地域に使用するUTMゾーンを決定するにはutmzone PostGIS plpgsql helper functionを参照してください)。

米国の州では、州平面空間参照系 (メートルまたはフィート単位)を使用します。この空間参照系は州ごとに一つか二つ存在します。ほとんどのメートル単位のものはコアのセットに存在しますが、フィート単位の多数のものやESRIが作成したものはspatialreference.orgからロードする必要があります。

地球外の座標系でさえも定義することができます。たとえばMars 2000です。この火星の座標系は非平面 (回転楕円体の度)ですが、geography型で、度でなくメートル単位で長さや近接測定値を取得することができます。

割当外のSRIDとPROJ定義を使って米国中央のランベルト正角円錐図法の独自座標系をロードする例を次に示します。

INSERT INTO spatial_ref_sys (srid, proj4text)
VALUES ( 990000,
  '+proj=lcc  +lon_0=-95 +lat_0=25 +lat_1=25 +lat_2=25 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs'
);

4.6. 空間テーブル

4.6.1. 空間テーブルを作る

geometry型のカラムを付けたCREATE TABLE SQLステートメントでジオメトリデータを保存するテーブルを生成することができます。次の例では、BC-アルベルス座標系 (SRID 3005)の2次元 (XY)ラインストリングを保存するジオメトリカラムを持つテーブルを生成します。

CREATE TABLE roads (
    id SERIAL PRIMARY KEY,
    name VARCHAR(64),
    geom geometry(LINESTRING,3005)
  );

geometry型は、次の通り、二つの任意指定型修飾子に対応しています。

  • 空間タイプ修飾子はカラムで許される形状と次元の種類を制約するものです。値は、対応しているジオメトリタイプ (POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION等)なら全て可能です。空間タイプ修飾子は、後置詞 Z, M, ZMを付け加えることで座標次元の制約に対応します。例えば、`LINESTRINGM`修飾子では、3次元で3番目がM軸となるラインストリングだけを許します。同様に、'POINTZM'では4次元 (XYZM)データが求められます。

  • SRID修飾子空間参照系のSRIDを特定の数値に制約します。省略した場合には、デフォルトは0となります。

ジオグラフィカラムを持つテーブルの生成の例を次に挙げます。

  • デフォルトSRIDであらゆる種類のジオメトリを保持するテーブルの生成:

    CREATE TABLE geoms(gid serial PRIMARY KEY, geom geometry );
  • 2次元ポイントでSRIDがデフォルトのテーブル作成:

    CREATE TABLE pts(gid serial PRIMARY KEY, geom geometry(POINT) );
  • 3次元 (XYZ)ポイントでSRIDが3005のテーブル作成:

    CREATE TABLE pts(gid serial PRIMARY KEY, geom geometry(POINTZ,3005) );
  • 4次元 (XYZM)ラインストリングでSRIDがデフォルトのテーブル作成:

    CREATE TABLE lines(gid serial PRIMARY KEY, geom geometry(LINESTRINGZM) );
  • 2次元ポリゴンでSRIDが4276 (NAD 1927地理座標系)のテーブル作成:

    CREATE TABLE polys(gid serial PRIMARY KEY, geom geometry(POLYGON,4267) );

一つのテーブルが一つ以上のジオメトリカラムを持つことができます。テーブル生成時に指定するか、ALTER TABLE SQLステートメントを使って追加するかで実現できます。次に3次元ラインストリングを格納するカラムを追加する例を示します。

ALTER TABLE roads ADD COLUMN geom2 geometry(LINESTRINGZ,4326);

4.6.2. GEOMETRY_COLUMNSビュー

OGC Simple Features Specification for SQLは、ジオメトリテーブル構造を記述するためのGEOMETRY_COLUMNSメタデータテーブルを定義しています。PostGISではgeometry_columnsは、データベースのシステムカタログテーブルから読み取るビューです。これによって、空間メタデータ情報が常に現在定義されているテーブルやビューと矛盾しなくなります。

\d geometry_columns
View "public.geometry_columns"
      Column       |          Type          | Modifiers
-------------------+------------------------+-----------
 f_table_catalog   | character varying(256) |
 f_table_schema    | character varying(256) |
 f_table_name      | character varying(256) |
 f_geometry_column | character varying(256) |
 coord_dimension   | integer                |
 srid              | integer                |
 type              | character varying(30)  |

カラムは次の通りです。

f_table_catalog, f_table_schema, f_table_name

ジオメトリカラムを持っている地物テーブルの完全修飾名。PostgreSQLには"catalog"の類似カラムが無いので、このカラムは空白のままです。"schema"についてはPostgreSQLスキーマ名が使われます (デフォルトはpublicです)。

f_geometry_column

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

coord_dimension

カラムの座標次元 (2, 3, 4)。

srid

このテーブルのジオメトリの座標系として使用される座標系空間参照系のIDです。spatial_ref_sysテーブルを参照する外部キーです (Section 4.5.1, “SPATIAL_REF_SYSテーブル”を参照して下さい)。

type

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

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

これが必要になる事例に、SQLビューとバルクインサートの二つがあります。バルクインサートの場合には、カラムに制約を与えるか、ALTER TABLEを実行することで、geometry_columnsテーブル内の登録を訂正することができます。ビューの場合には、CAST演算を使用します。カラムが型修飾子に基づく場合には、生成処理によって正しく登録されるので、何も行う必要がありません。ジオメトリに適用する空間関数を持たないビューも、基礎となるテーブルのジオメトリカラムと同じように登録されます。

-- 次のようなビューがあるとします
CREATE VIEW public.vwmytablemercator AS
        SELECT gid, ST_Transform(geom, 3395) As geom, f_name
        FROM public.mytable;

-- 正しく登録するには、
-- ジオメトリをキャストします。
--
DROP VIEW public.vwmytablemercator;
CREATE VIEW  public.vwmytablemercator AS
        SELECT gid, ST_Transform(geom, 3395)::geometry(Geometry, 3395) As geom, f_name
        FROM public.mytable;

-- ジオメトリタイプが確実に2次元ポリゴンだと知っているなら
-- 次のようにできます。
DROP VIEW public.vwmytablemercator;
CREATE VIEW  public.vwmytablemercator AS
        SELECT gid, ST_Transform(geom,3395)::geometry(Polygon, 3395) As geom, f_name
        FROM public.mytable;
-- 次のように、バルクインサートで派生テーブルを生成したとしましょう
SELECT poi.gid, poi.geom, citybounds.city_name
INTO myschema.my_special_pois
FROM poi INNER JOIN citybounds ON ST_Intersects(citybounds.geom, poi.geom);

-- 新しいテーブルに2次元インデックスを作ります
CREATE INDEX idx_myschema_myspecialpois_geom_gist
  ON myschema.my_special_pois USING gist(geom);

-- ポイントが3次元ポイントであったり、XYMポイントであったりした場合には、
-- 次のように、2次元インデックスでなくN次元インデックスを作ることになるかも
-- 知れません。
CREATE INDEX my_special_pois_geom_gist_nd
        ON my_special_pois USING gist(geom gist_geometry_ops_nd);

-- 新しいテーブルのジオメトリカラムをgeometry_columnsに手動登録するには、
-- 次のようにします。
-- カラムを型修飾子ベースにするために、基礎となるテーブル構造も変更することに
-- 注意して下さい。
SELECT populate_geometry_columns('myschema.my_special_pois'::regclass);

-- PostGIS 2.0を使っていて、何らかの理由で古い制約をもとにした定義を行う
-- (派生テーブルが同じタイプやSRIDを持たないといった場合)ことが必要な場合には、
-- 新しい任意変数use_typemodをfalseにします。
SELECT populate_geometry_columns('myschema.my_special_pois'::regclass, false); 

古い制約を基にした手法は現在も対応していますが、制約を基にしたジオメトリカラムで直接的にビューで使われている場合は、型修飾子のようには正しくgeometry_columnsに登録されません。次の例では、型修飾子を使ったカラム定義と、制約に基づくカラムの定義とを行っています。

CREATE TABLE pois_ny(gid SERIAL PRIMARY KEY, poi_name text, cat text, geom geometry(POINT,4326));
SELECT AddGeometryColumn('pois_ny', 'geom_2160', 2160, 'POINT', 2, false);

psqlで次を実行します。

\d pois_ny;

型修飾子と制約に基づくのとでは異なった定義になっているのが見えます。

Table "public.pois_ny"
  Column   |         Type          |                       Modifiers

-----------+-----------------------+------------------------------------------------------
 gid       | integer               | not null default nextval('pois_ny_gid_seq'::regclass)
 poi_name  | text                  |
 cat       | character varying(20) |
 geom      | geometry(Point,4326)  |
 geom_2160 | geometry              |
Indexes:
    "pois_ny_pkey" PRIMARY KEY, btree (gid)
Check constraints:
    "enforce_dims_geom_2160" CHECK (st_ndims(geom_2160) = 2)
    "enforce_geotype_geom_2160" CHECK (geometrytype(geom_2160) = 'POINT'::text
        OR geom_2160 IS NULL)
    "enforce_srid_geom_2160" CHECK (st_srid(geom_2160) = 2160)

geometry_columnsでは、両方とも正しく登録されています。

SELECT f_table_name, f_geometry_column, srid, type
        FROM geometry_columns
        WHERE f_table_name = 'pois_ny';
f_table_name | f_geometry_column | srid | type
-------------+-------------------+------+-------
pois_ny      | geom              | 4326 | POINT
pois_ny      | geom_2160         | 2160 | POINT

しかし、次のようにビューを作ろうとします。

CREATE VIEW vw_pois_ny_parks AS
SELECT *
  FROM pois_ny
  WHERE cat='park';

SELECT f_table_name, f_geometry_column, srid, type
        FROM geometry_columns
        WHERE f_table_name = 'vw_pois_ny_parks';

型修飾子によるgeomのビューカラムは正しく登録されますが、制約に基づくものは正しく登録されません。

f_table_name   | f_geometry_column | srid |   type
------------------+-------------------+------+----------
 vw_pois_ny_parks | geom              | 4326 | POINT
 vw_pois_ny_parks | geom_2160         |    0 | GEOMETRY

これは、将来的にPostGISの版で変更されるかもしれませんが、今のところは、制約に基づくビューカラムを正しく登録させるには、次のようにします。

DROP VIEW vw_pois_ny_parks;
CREATE VIEW vw_pois_ny_parks AS
SELECT gid, poi_name, cat,
  geom,
  geom_2160::geometry(POINT,2160) As geom_2160
  FROM pois_ny
  WHERE cat = 'park';
SELECT f_table_name, f_geometry_column, srid, type
        FROM geometry_columns
        WHERE f_table_name = 'vw_pois_ny_parks';
f_table_name   | f_geometry_column | srid | type
------------------+-------------------+------+-------
 vw_pois_ny_parks | geom              | 4326 | POINT
 vw_pois_ny_parks | geom_2160         | 2160 | POINT

4.7. 空間データのロード

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

4.7.1. SQLを使ってロードする

空間データを文字表現 (WKTかWKB)に変換できたら、SQLを使うのがPostGISにデータを持たせる最も簡単です。SQLユーティリティのpsqlを使用して、SQLのINSERTステートメントのテキストファイルをロードすると、データをPostGIS/PostgreSQLに一括読み込みできます。

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

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

SQLファイルのPostgreSQLへのロードはpsqlを使います。次のようにします。

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

4.7.2. シェープファイルローダを使う

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

グラフィカルユーザインタフェースを持つshp2pgsql-guiもあります。コマンドラインローダのオプションのほとんどが使えます。これは、スクリプト化されていない1回限りのロードの場合や、PostGIS初心者がロードする場合に、簡単に使用できます。PgAdminIIIのプラグインとすることもできます。

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

-c

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

-a

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

-d

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

-p

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

-?

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

-D

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

-s [<FROM_SRID>:]<SRID>

指定したSRIDを持つジオメトリテーブルの生成や追加を行います。FROM_SRIDが与えられた場合には、入力シェープファイルに、これを使います 。この場合には、ジオメトリは変更先SRIDに投影変換します。

-k

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

-i

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

-I

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

-m

-m a_file_nameで、長いカラム名を10文字のDBFカラム名に対応付けるファイルを指定します。ファイルは、1以上の行を持ちます。各行は空白区切りで二つの名前を持ち、行頭行末に空白を入れません。例を次に示します。

COLUMNNAME DBFFIELD1
AVERYLONGCOLUMNNAME DBFFIELD2

-S

マルチ系ジオメトリの替りに単一ジオメトリを生成します。全てのジオメトリが実際に単一である (たとえば単一の外環でなるMULTIPOLYGONや単一の頂点でなるMULTIPOINT)場合にのみ成功します。

-t <次元>

出力ジオメトリが特定の次元を持つよう強制します。次元は、2D, 3DZ, 3DM, 4Dの文字列を使います。

入力の次元が出力より小さい場合には、出力では0が入ります。入力の次元が大きい場合には、外されます。

-w

出力書式をWKBでなくWKTにします。精度が低下して、座標変動が発生しうることに注意が必要です。

-e

トランザクションを使わずに、ステートメントごとに実行するようにします。エラーの元となる不良なジオメトリがいくつか含んでいる時に、大半の良好なデータのロードが可能にするものです。ダンプ書式ではトランザクションを常に使うので、-Dフラグを指定している場合には使えません。

-W <エンコーディング>

入力データ (dbfファイル)のエンコーディングを指定します。全てのdbfの属性は指定されたエンコーディングからUTF8に変換されます。SQL出力結果には SET CLIENT_ENCODING to UTF8が含まれるようになり、バックエンドはUTF-8からデータベースが内部利用のために設定したエンコーディングに再変換できます。

-N <方針>

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

-n

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

-G

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

-T <tablespace>

新しいテーブルのテーブル空間を指定します。 -Xパラメータが使われない場合には、インデックスはデフォルトのテーブル空間を使用します。PostgreSQL文書には、テーブル空間を用いるべき時に関する良い文書があります。

-X <tablespace>

新しいテーブルのインデックスで使われるテーブル空間を指定します。 主キーインデックスに適用され、-Iが合わせて使われている場合にはGiST空間インデックスにも適用されます。

-Z

このフラグをこれを使う時、ANALYZE手続きの生成を防ぎます。-Zフラグが無い (デフォルトの振る舞い)場合には、ANALYZE手続きが生成されます。

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

# 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.8. 空間データの抽出

空間データはSQLかシェープファイルダンパを使うと抽出できます。SQLの節では空間テーブルで比較とクエリに使用できる関数を示します。

4.8.1. 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文を使います。空間に制限をかけるには次の関数を使います。

ST_Intersects

この関数は、二つのジオメトリが空間を共有しているかどうかをテストします。

=

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

次に、これらの演算子をクエリで使うことができます。SQLコマンドラインからジオメトリとボックスの指定を行うときは、明示的に文字列表現をジオメトリに変換しなければならないことに注意して下さい。たとえば、次のようになります。ただし312は架空の空間参照系番号で、ここでのデータに合致しています。

SELECT road_id, road_name
  FROM roads
  WHERE roads_geom='SRID=312;LINESTRING(191232 243118,191108 243242)'::geometry;

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

道路がポリゴンで定義した面を通過するかどうかをチェックするには次のようにします。

SELECT road_id, road_name
FROM roads
WHERE ST_Intersects(roads_geom, 'SRID=312;POLYGON((...))');

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

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

次に示すクエリのように、フレームにBOX3Dオブジェクトを使います。

SELECT ST_AsText(roads_geom) AS geom
FROM roads
WHERE
  roads_geom && ST_MakeEnvelope(191232, 243117,191232, 243119,312);

エンベロープの投影を指定するためにSRID 312を使っていることに注意して下さい。

4.8.2. ダンパを使う

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

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

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

-f <ファイル名>

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

-h <ホスト>

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

-p <ポート>

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

-P <パスワード>

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

-u <ユーザ名>

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

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

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

-b

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

-r

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

-m ファイル名

識別名を10文字名に再割り当てします。 ファイルの中身は、一つの空白で区切られ、前と後に空白が無い二つのシンボルの行からなります。VERYLONGSYMBOL SHORTONE ANOTHERVERYLONGSYMBOL SHORTER等となります。

4.9. 空間インデックス

インデックスによって巨大データセットの空間データベースの使用が可能となります。インデックス無しでは、地物の検索を行う際に、データベースの全てのレコードに対するシーケンシャルスキャンが必要となります。インデックスによって、レコード探索のために早く移動できる構造を構築するので、検索速度が向上します。

一般的に属性データに使われるインデックス手法でありB木は、空間データではあまり有用ではありません。1次元データの格納とクエリにだけしか対応していないためです。ジオメトリのような2次元以上の次元を持つデータでは、全ての次元の範囲を指定できるインデックス手法が求められます。PostgreSQLの空間データ処理に関する主要な利点の一つに、多次元データで上手く動作するGiST、BRIN、SP-GiSTの複数のインデックス手法を提供していることです。

  • GiST (Generalized Search Tree)インデックスは、データを「一方にあるもの」「オーバラップするもの」「内部にあるもの」に分解するもので、GISデータを含む幅広い範囲で使えます。PostGISはGiSTインデックス空間データをR木インデックス実装のベースにています。GiSTは最も一般的に使われ、多目的なインデックス手法で、非常に良好な問い合わせ効率を提供しています。

  • BRIN (Block Range Index)インデックスは、空間範囲を集計することで動作します。探索は範囲のスキャンを通して行われます。BRINは一部の種類 (空間的にソートされ、更新がほぼ無いか全く無い)のデータだけに適切です。しかし、インデックス生成時間は非所に早く、インデックスサイズは非常に小さくなります。

  • SP-GiST (Space-Partitioned Generalized Search Tree)は4分木、kd木、基数木 (トライ木)のような部分木探索に対応する一般的なインデックス手法です。

空間インデックスはジオメトリのバウンディングボックスだけを格納します。空間クエリはインデックスは初期フィルタとして使用して、クエリ条件に一致する可能性のあるジオメトリを早く求めます。ほとんどの空間クエリでは、空間述語関数を使って特定の空間条件をテストする二次フィルタが必要です。空間述語関数を使ったクエリの詳細情報についてはSection 5.2, “空間インデックスを使う”をご覧下さい。

また、PostGIS Workshop section on spatial indexesPostgreSQL manualもご覧下さい。

4.9.1. GiSTインデックス

GiSTは「汎用検索木 (Generalized Search Tree)」の意味で、多次元データのインデックスの一般化された形式です。PostGISはGiST上で実装しているR木インデックスをを空間データのインデックスに使用しています。GiSTは最も一般的に使われ、多目的なインデックス手法で、クエリ能率を非常に良くします。他のGiSTの実装は、通常のB木インデックスに従わない全ての種類の不規則なデータ構造 (整数配列, スペクトラルデータ等)の検索速度を向上させるために使います。詳細情報についてはPostgreSQL manualをご覧ください。

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

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

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

上の文では常に2次元インデックスを構築します。n次元インデックスをジオメトリ型で使うには、次の文でインデックスを生成できます。

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

空間インデックスの構築は、計算量を集中させて行われます。また、この時には、テーブルへの書き込みアクセスがブロックされます。そのため、本番システムではより遅いCONCURRENTLYを選択するかも知れません。次のようにします。

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

インデックス構築後に、時々PostgreSQLにテーブルの統計情報を集めさせると助かります。クエリプランの最適化に使われます。

VACUUM ANALYZE [テーブル名] [(カラム名)];

4.9.2. BRINインデックス

BRINは"Block Range Index"の略です。PostgreSQL 9.5で導入された汎用インデックス手法です。BRINは不可逆インデックス手法であり、レコードが与えた検索条件に合致することを確認する二番目のチェックが必要であることを意味しています (全ての空間インデックスで言えます)。非常に速いインデックス作成、非常に小さいインデックスサイズで、合理的な読み込み効率を持ちます。主目的は、非常に大きいテーブルのテーブル内の物理位置と関係があるカラムにインデックスを作ることに対応するためです。空間インデックスに加えて、BRINは様々な種類の属性データ構造 (整数、配列等)で速度向上させることができます。詳細情報についてはPostgreSQL manualをご覧ください。

空間テーブルが、ひとたび数千行を超えると、データの空間検索の速度向上にインデックスが必要と感じることになります。GiSTインデックスは、サイズがデータベースで使えるRAM容量を超えず、インデックスのストレージサイズに余裕があり、書き込み時のインデックス更新コストにも余裕があるなら、非常に高いパフォーマンスを発揮します。そうでない場合には、非常に大きなテーブルにおいては、BRINインデックスを代替に考えることができます。

BRINインデックスは、連続するテーブルブロックの集合 (ブロック範囲と言います)の全てのジオメトリを囲むバウンディングボックスを格納します。インデックスを使用した問い合わせを実行する時に、問い合わせ範囲とインタセクトするブロック範囲を見つけるためにスキャンします。これは、データが物理的に整列していて、ブロック範囲のバウンディングボックスのオーバラップが最小である (理想的には相互に排他的である)場合に限って効率的です。結果インデックスは非常に小さいサイズですが、通常、読み込み効率は、同じデータにおけるGiSTインデックスより悪くなります。

BRINインデックスの構築は、はGiSTインデックスと比べて、CPU集中を非常に減らします。BRINインデックスはGiSTインデックスよりも、同じデータに対して10倍速く構築するのが普通です。BRINインデックスはテーブルブロックの範囲ごとに一つのバウンディングボックスしか格納しないので、GiSTインデックスと比べて、ディスクスペースを1000倍少なくできます。

レンジ内で要約するブロック数を選択できます。この数字を減らすと、インデックスは大きくなりますが、効率向上の助けになる可能性があります。

BRINを効果的にするには、テーブルデータをブロック範囲のオーバラップの量を最小にするような物理的オーダーで格納します。データが既に適切に並び替えられているかも知れません (たとえば、既に空間オーダーで並び替えられているデータセットを他のデータベースからロードする場合)。そうでない場合には、一つの空間キーによるデータの並べ替えで実現できます。一つの方法として、ジオメトリ値で並べ替えた新しいテーブルを生成することです (最近のPostGISのバージョンで効果的なヒルベルト曲線オーダーが使われています)。

CREATE TABLE table_sorted AS
   SELECT * FROM table  ORDER BY geom;

もしくは、データは、ジオハッシュを (一時的な)インデックスに使い、そのインデックスでクラスタリングを行うことによって適切に並べ替えることができます。

CREATE INDEX idx_temp_geohash ON table
    USING btree (ST_GeoHash( ST_Transform( geom, 4326 ), 20));
CLUSTER table USING idx_temp_geohash;

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

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

上の文で2次元インデックスを構築します。3次元インデックスをビルドするには、この文を使います。

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

また、4次元演算子クラスを使う4次元インデックスを使うこともできます。

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

上記のコマンドでは、範囲のブロック数はデフォルトの128を使用しています。集計で範囲のブロック数を指定するには、この文を使います。

CREATE INDEX [インデックス名] ON [テーブル名]
    USING BRIN ( [ジオメトリカラム名] ) WITH (pages_per_range = [数字]); 

また、BRINインデックスは、多数の行で一つのインデックス値を格納することを心に留めておいて下さい。テーブルに違う次元のジオメトリを格納する場合には、インデックスの効率が悪くなります。この効率欠落を回避するには、格納したジオメトリの次元数の最小値となる演算子クラスを選択します。

「ジオグラフィ」型もまたBRINインデックスに対応しています。BRINインデックスを「ジオグラフィ」カラムに構築するための文は次の通りです。

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

上の文では常に回転楕円体面上の地理空間オブジェクトの2次元インデックスを構築します。

現在のところは「包括対応」だけをここで考えています。これは、&&, ~, @の演算子だけが2次元で使われることを意味します (ジオメトリジオグラフィの両方)。 &&&演算子は3次元ジオメトリで使えます。しばらくはKNN検索に対応しません。

BRINと他のインデックスとの重要な違いは、データベースがインデックスを動的に保守しないことです。テーブルの空間データを変更すると、単純にインデックスの末尾に追加しています。このためインデックス探索の能率が時間とともに低下します。インデックスはVACUUMか空間関数brin_summarize_new_values(regclass)を実行することで更新できます。このため、BRINは読み込み専用か、書き込みがほとんど発生しないよなデータでの利用では最も適切になりえます。詳細情報については、manualをご覧下さい。

空間データにBRINを使用して集計するには:

  • インデックス構築時間は非常に速く、インデックスサイズは非常に小さいです。

  • インデックスのクエリ時間はGiSTより遅いですが、十分許容できます。

  • テーブルデータを空間順序で並べ替える必要があります。

  • 手動でインデックスの保守をする必要があります。

  • 巨大なテーブルであって、オーバラップが少ないか無く (ポイントなど)、かつ静的か頻繁には変更しないようなものに、最も適しています。

  • 比較的多数のデータレコードを返すクエリでの使用が、より効果的です。

4.9.3. SP-GiSTインデックス

SP-GiSTは、「空間分割された一般探索木」を表します。四分木、k次元木、基数木 (トライ木)のような分割探索木に対応するインデックスの総称的な形式です。このデータ構造の一般的な機能は、検索空間を反復して分割することですが、分割は等しいサイズである必要はありません。SP-GiSTは、GISインデックスだけでなく、電話回線のルーティングや、IPルーティング、部分文字列検索等といった、様々な種類のデータを探索する速度の向上に使われます。詳細情報についてはPostgreSQL manualをご覧下さい。

GiSTインデックスを利用しているので、空間オブジェクトを覆うバウンディングボックスを保存するという意味で、SP-GiSTインデックスは不可逆です。SP-GiSTインデックスは、GiSTインデックスの代替と考えることができます。

一度GISデータテーブルが数千行を超えると、データの空間探索の速度向上にSP-GiSTインデックスを使うと良いかも知れません。「ジオメトリ」カラムにSP-GiSTインデックスを構築するための文は次の通りです。

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

上の文では、2次元インデックスを構築します。ジオメトリ型の3次元インデックスは、次のように、3次元演算子クラスを使用して生成します。

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

空間インデックスの構築は、計算量を集中させて行われます。また、この時には、テーブルへの書き込みアクセスがブロックされます。そのため、本番システムでは、より遅いCONCURRENTLYを選択するかも知れません。次のようにします。

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

インデックス構築後に、時々PostgreSQLにテーブルの統計情報を集めさせると助かります。クエリプランの最適化に使われます。

VACUUM ANALYZE [テーブル名] [(カラム名)];

SP-GiSTインデックスは次の演算子を含むクエリの実行速度を向上させられます。

  • 2次元インデックスについては <<, &<, &>, >>, <<|, &<|, |&>, |>>, &&, @>, <@, ~=です。

  • 3次元インデックスについては &/&, ~==, @>>, and <<@ 。

現時点ではkNN探索に対応していません。

4.9.4. インデックス使用のチューニング

通常、インデックスは知らないうちにデータアクセスの速度を向上します。ひとたびインデックスを構築すれば、PostgreSQLクエリプランナは自動的にクエリの能率を向上させるために使うべきかどうかを決定します。しかし、プランナが既存のインデックスを選択せず、遅いシーケンシャルスキャンを使い続ける場合があります。

空間インデックスが使われていないのが分かった場合には、少しの行えることがあります。

  • クエリプランの試験とクエリの確認で、必要なものを計算できます。誤ったJOINや忘れ去られたテーブルや間違ったテーブルでは、予期しないテーブルレコード検索が複数回行われることがありえます。クエリプランを得るにはクエリの先頭にEXPLAINを付けて実行します。

  • テーブル内の値の数量と分布に関する統計情報を収集するとともに、クエリプランナにインデックス使用にかかる意思決定のための、より良い情報を与えるようにします。VACUUM ANALYZEは両方を計算します。

    データベースに対する定期的なvacuumは常に実行するべきです。多くのPostgreSQLデータベースエージェントは、閑散時のcronジョブとして定期的にVACUUMを実行します。

  • VACUUMが役に立たない場合には、SET ENABLE_SEQSCAN TO OFF;コマンドを使用して、一時的にプランナにインデックス情報の使用を強制することができます。この方法で、プランナがインデックス使用を多くしたクエリプランを生成できるかどうかを確認できます。このコマンドはデバッグにのみ使用してください。一般的に言えば、プランナはインデックスを使用するタイミングをよく知っています。クエリを実行したらSET ENABLE_SEQSCAN TO ON;を実行して、他のクエリでは通常操作にすることを忘れないでください。

  • SET ENABLE_SEQSCAN TO OFF;でクエリ速度が向上する場合には、PostgreSQLのハードウェア関連のチューンが行われていないのかも知れません。プランナがシーケンシャル対インデックスのコストが誤っている場合には、postgresql.conf内にあるRANDOM_PAGE_COSTの値を変更してみて下さい。SET RANDOM_PAGE_COST TO 1.1;とします。RANDOM_PAGE_COSTのデフォルト値は4.0です。1.1 (SSDの場合)または2.0 (高速磁気ディスクの場合)を試してみて下さい。値を小さくするほど、プランナがインデックススキャンをしやすくなります。

  • SET ENABLE_SEQSCAN TO OFF;がクエリの助けにならないなら、クエリはPostgreSQLプランナがまだ最適化できないSQL構成なのかも知れません。プランナが処理できるようにクエリを再記述できるかもしれません。例えば、インラインSELECTを持つ副問い合わせがあると、効果的なプランを作らないことがあり、LATERAL JOINを使うように書き換えることができます。

詳細情報についてはPostgreSQLマニュアルの問い合わせ計画節をご覧下さい。

Chapter 5. 空間クエリ

空間データベースのレゾンデートルは、通常ならデスクトップGISの機能が必要なクエリをデータベース内で実行することです。PostGISを使うには、使用可能な空間関数は何かを知り、またクエリ内でどう使うかを知って、適切なインデックスで能率を向上させることが求められます。

5.1. 空間関係の決定

空間関係は、二つのジオメトリについて、一方がもう一方にどのような相互関係になっているかを示すものです。ジオメトリのクエリにおける基本的な機能です。

5.1.1. Dimensionally Extended 9-Intersection Model

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

点集合トポロジでは、2次元空間に埋め込まれたジオメトリの中にあるポイントは、次に示す三つの集合に分類されます。

境界

ジオメトリの境界は、一次元低いジオメトリです。POINTでは、次元が0になり、境界は空集合です。LINESTRINGの境界は二つの端点です。POLYGONの境界は、外環と内環の線です。

内部 (Interior)

ジオメトリの内部は、ジオメトリの境界以外のポイントです。POINTでは、内部はポイント自体です。LINESTRINGの内部は端点の間のポイントの集合です。POLYGONの内部は、ポリゴン内部の面です。

外部 (Exterior)

ジオメトリの外部はジオメトリが組み込まれた空間の残りです。言い換えると、ジオメトリの内部にも境界にもない点の全てです。これは2次元の閉じていない面になります。

Dimensionally Extended 9-Intersection Model (DE-9IM)は、二つのジオメトリの空間関係を九つの交差の次元を指定することで記述します。交差次元は3×3の交差行列で正式に表現することができます。

ジオメトリgに対する内部境界外部I(g)B(g)E(g)と表記します。また、dim(s)sの集合を{0,1,2,F}の値で示すます。

  • 0 => 点

  • 1 => 線

  • 2 => 面

  • F => 空集合

この表記法を使うと、二つのジオメトリabの交差行列は次の通りです。

 内部 (Interior)境界 (Boundary)外部 (Exterior)
内部 (Interior)dim( I(a) ∩ I(b) )dim( I(a) ∩ B(b) )dim( I(a) ∩ E(b) )
境界 (Boundary)dim( B(a) ∩ I(b) )dim( B(a) ∩ B(b) )dim( B(a) ∩ E(b) )
外部 (Exterior)dim( E(a) ∩ I(b) )dim( E(a) ∩ B(b) )dim( E(a) ∩ E(b) )

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

 

 内部 (Interior)境界 (Boundary)外部 (Exterior)
内部 (Interior)

dim( I(a) ∩ I(b) ) = 2

dim( I(a) ∩ B(b) = 1

dim( I(a) ∩ E(b) ) = 2

境界 (Boundary)

dim( B(a) ∩ I(b) ) = 1

dim( B(a) ∩ B(b) ) = 0

dim( B(a) ∩ E(b) ) = 1

外部 (Exterior)

dim( E(a) ∩ I(b) ) = 2

dim( E(a) ∩ B(b) ) = 1

dim( E(a) ∩ E(b) = 2

左から右に、上から下に読みます。交差行列の文字列表現は'212101212'です。

詳細情報については次をご覧下さい。

5.1.2. 名前付き空間関係

共通の空間関係を簡単に決定できるように、PGC SFSは名前付き空間関係述語の集合を定義しています。PostGISではST_ContainsST_CrossesST_DisjointST_EqualsST_IntersectsST_OverlapsST_TouchesST_Withinが提供されています。非標準の空間関係述語ST_CoversST_CoveredByST_ContainsProperlyも定義されています。

空間述語は通常SQLのWHERE節やJOIN節内で条件に使用されます。名前付き空間述語は、インデックスが有効なら自動的に空間インデックスを使うので、バウンディングボックス演算子&&を使う必要はありません。例えば次のようになります。

SELECT city.name, state.name, city.geom
FROM city JOIN state ON ST_Intersects(city.geom, state.geom);

詳細や図についてはPostGIS Workshopをご覧下さい。

5.1.3. 一般的な空間関係

名前付き空間関係が求める空間フィルタ条件を与えるのに不十分となる場合があります。

例えば、道路ネットワークを表現する線データセットを考えてみます。点でなく線で交差する全ての道路の辺を識別しなければならないことがあります (ビジネスルールの検証のためならありえます)。この場合、ST_Crossesでは、点で交差する場合しかtrueを返さないので、必要な空間フィルタになりません。

2ステップ解決法を示します。まず、空間的にインタセクトしている同路線の二本を抜き出し (ST_Intersects)、実際にインタセクトしている部分を計算 (ST_Intersection)します。次いで、インタセクトしている部分のST_GeometryTypeLINESTRING' かどうかを確認します ([MULTI]POINT[MULTI]LINESTRING等のGEOMETRYCOLLECTIONを返す場合に適切に処理します)。

明らかに、より単純でより速い解法が望ましいです。

二つ目の例では、湖の境界とインタセクトし、かつ終端が岸に上がっている波止場を見つけます。言い換えると、波止場が湖に含まれるが完全には含まれず、湖の境界線とインタセクトして、波止場の終端が確実に湖内または境界にある場合を指します。空間述語を併用すると求める地物を見つけることができます。

この要件は完全なDE-9IM交差行列の計算で満たすことができます。PostGISは、これを行うST_Relate関数を提供しています。次のようにします。

SELECT ST_Relate( 'LINESTRING (1 1, 5 5)',
                  'POLYGON ((3 3, 3 7, 7 7, 7 3, 3 3))' );
st_relate
-----------
1010F0212

特定の空間関係をテストするには、交差行列パターンを使います。これは、追加シンボル{T,*}で拡張された行列表現です。

  • T => インタセクションの次元は空ではないという意味です。すなわち{0,1,2}のいずれかです。

  • * => 何でも良い

交差行列パターンを使って、特定の空間関係の評価がより簡潔な方法で可能です。交差行列パターンのテストにST_RelateST_RelateMatchを使うことができます。上に挙げた一つ目の例では、二つのラインがライン内部でインタセクトする交差行列パターンは'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');

5.2. 空間インデックスを使う

空間条件を使用するクエリを構築する時、最良の効果を得るには、空間インデックスが存在する場合に (Section 4.9, “空間インデックス”参照)これを確実に使用することが重要です。そのためには、WHERE節やON節で、空間演算子またはインデックス対応関数を使用しなければなりません。

空間演算子には、バウンディングボックス演算子 (最もよく使われるのは&&です。Section 8.10.1, “バウンディングボックス演算子”参照)、および近傍クエリで使用される距離演算子 (最もよく使われるのは<->です。Section 8.10.2, “距離演算子”参照)が含まれます。

インデックス対応関数は、自動的にバウンディングボックス演算子を空間条件に追加します。インデックス対応関数は空間関係述語を含みます。空間関係述語には、ST_Contains, ST_ContainsProperly, ST_CoveredBy, ST_Covers, ST_Crosses, ST_Intersects, ST_Overlaps, ST_Touches, ST_Within, ST_Within, ST_3DIntersectsがあり、距離述語にはST_DWithin, ST_DFullyWithin, ST_3DDFullyWithin, ST_3DDWithin があります。

ST_Distanceといった関数は、演算の最適化のためにはインデックスを使用しません。例えば、次のクエリは、大きなテーブルでは非常に遅くなります。

SELECT geom
FROM geom_table
WHERE ST_Distance( geom, 'SRID=312;POINT(100000 200000)' ) < 100

このクエリはgeom_tableテーブル内の、(100000, 200000)のポイントから100単位内にある全てのジオメトリを選択します。テーブル内の個々のポイントと指定したポイントとの距離を計算しているため、非常に遅くなります。すなわち、1回のST_Distance()の計算で、テーブルの全ての行について計算することになります。

インデックス対応関数ST_DWithinを使用すると、処理行数を実質的に減らすことができます。次のようにします。

SELECT geom
FROM geom_table
WHERE ST_DWithin( geom, 'SRID=312;POINT(100000 200000)', 100 )

このクエリは、同じジオメトリを選択しますが、より効率的な方法を取ります。 ST_DWithin()が内部で&&演算子をクエリジオメトリのバウンディングボックスを拡大したボックスで使うことによって可能となります。geom上に空間インデックスが存在するなら、クエリプランナは距離計算の前に対象行数を減らすためにインデックスを使えることを認識します。空間インデックスによって、バウンディングボックスが拡張された範囲とオーバラップするジオメトリだけを検索して、そのため、求めようとする距離内にあるかも知れないジオメトリを検索することができます。その後で、結果集合内のレコードを含めるかどうかを確認するための実際の距離計算が行われます。

詳細情報と例についてはPostGIS Workshopをご覧下さい。

5.3. 空間SQLの例

本節の例では、線の道路のテーブルとポリゴンの市区町村境界テーブルとを使います。bc_roadsテーブルの定義は次の通りです。

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

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

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

5.3.1.

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

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

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

km_roads
------------------
70842.1243039643

5.3.2.

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

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

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

hectares
------------------
32657.9103824927

5.3.3.

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

このクエリでは、順序付けの値に空間計測関数を使っています。この問題に対しては複数の方法がありますが、最も効果的な方法は次の通りです。

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

name           | hectares
---------------+-----------------
TUMBLER RIDGE  | 155020.02556131

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

5.3.4.

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

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

SELECT
  m.name,
  sum(ST_Length(r.geom))/1000 as roads_km
FROM bc_roads AS r
JOIN bc_municipality AS m
  ON ST_Contains(m.geom, r.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の道です)にまとめられるので、少し時間がかかります。より小さいオーバレイ (数百の道路で数千のレコード)の場合、応答はもっと早くなりえます。

5.3.5.

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

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

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

5.3.6.

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

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

kilometers
------------------
4.89151904172838

5.3.7.

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

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

gid  | name         | area
-----+--------------+------------------
12   | SPALLUMCHEEN | 257374619.430216

Chapter 6. 性能向上に関する技法

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

6.1.1. 問題の説明

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

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

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

この問題に苦しむかどうかを見るには、PostgreSQLの"EXPLAIN ANALYZE"コマンドを使います。詳細情報と技術情報については、PostgreSQL性能メーリングリストのスレッドhttp://archives.postgresql.org/pgsql-performance/2005-02/msg00030.phpをご覧下さい。

また、PostGISの新しいスレッドhttps://lists.osgeo.org/pipermail/postgis-devel/2017-June/026209.htmlもご覧下さい。

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_Force2D(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 "geom" NOT NULL.
(ヒント: 列"the_geom"をNOT NULLとすることで、これを回避できるかもしれません)

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

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

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

6.3. 次元変換の回避

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

UPDATE mytable SET geom = ST_Force2D(geom);
VACUUM FULL ANALYZE mytable;

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

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

Chapter 7. アプリケーションのビルド

7.1. MapServerを使う

Minnesota MapServer は、OpenGIS Web Map Service仕様に準拠したインターネットWebマッピングサーバです。

7.1.1. 基本的な使い方

PostGISとMapServerとを併用するには、MapServerの設定方法を知る必要がありますが、本文書の範囲外です。本節では、PostGIS独特の問題と設定詳細について説明します。

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

  • PostGIS 0.6以上

  • MapServer 3.5以上

MapServerは、他のPostgreSQLクライアントと同じくPostGIS/PostgreSQLデータにアクセスします。アクセスにはlibpqインタフェースを使います。つまり、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"
      # 'roads'テーブルの'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=<ユーザ名> password=<パスワード> dbname=<ユーザ名> hostname=<サーバ> port=<5432>

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

    DATA

    このパラメータの形式は "<カラム名> from <テーブル名> using srid=<SRID> using unique <主キー>"となります。ここで、カラム名は地図に描画したい空間カラムを指し、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では、クエリ実行の際には、それぞれの空間レコードを識別するための一意な識別子が必要です。MapServerのPostGISモジュールは、一意な識別子を提供するために、ユーザ指定の一意な値を使います。テーブルの主キーを使うのが最も良い方法です。

7.1.2. よくある質問

7.1.2.1. EXPRESSIONをマップファイルで使う時に、値がテーブルにあるのを確認しているのに条件がtrueになりません。
7.1.2.2. シェープファイルに使用している FILTER が、同じデータを持つPostGISテーブルでは動作しません。
7.1.2.3. PostGISレイヤは、シェープファイルレイヤよりもはるかに遅く描画しますが、これは正常ですか?
7.1.2.4. PostGISレイヤはちゃんと描けましたが、クエリが本当に遅いです。何が問題なのですか?
7.1.2.5. ジオグラフィカラム (PostGIS 1.5で機能追加)をMapServerのレイヤのソースとして使用できますか?

7.1.2.1.

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

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

EXPRESSION ([numlanes] >= 6)

7.1.2.2.

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

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

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

7.1.2.3.

PostGISレイヤは、シェープファイルレイヤよりもはるかに遅く描画しますが、これは正常ですか?

一般に、与えられた地図に描画する地物が多いほど、PostGISはシェープファイルより遅くなる可能性が高くなります。相対的に地物が少ない (100個台)地図では、PostGISの方が速くなることがしばしばあります。地物が少多い (1000個台)地図では、PostGISは常に遅くなります。

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

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

7.1.2.4.

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

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

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

DATA "geom FROM geotable USING UNIQUE gid"

7.1.2.5.

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

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

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

7.1.3. 踏み込んだ使用法

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

DATA "geom FROM (
  SELECT
    table1.geom AS geom,
    table1.gid AS gid,
    table2.data AS data
  FROM table1
  LEFT JOIN table2
  ON table1.id = table2.id
) AS new_table USING UNIQUE gid USING SRID=4326"
USING UNIQUE <uniqueid>

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

[Note]

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

USING SRID=<srid>

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

7.1.4. 例

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

LAYER
  CONNECTIONTYPE postgis
  NAME "roads"
  CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
  DATA "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 "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 "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 "geom FROM (SELECT roads.gid AS gid, roads.geom AS 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 gid USING SRID=4326"
  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を使用する方法も示しています。

7.2. 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.PGConnection)conn).addDataType("geometry",Class.forName("org.postgis.PGgeometry"));
    ((org.postgresql.PGConnection)conn).addDataType("box3d",Class.forName("org.postgis.PGbox3d"));
    /*
    * ステートメントの生成とSELECTクエリの実行を行います。
    */
    Statement s = conn.createStatement();
    ResultSet r = s.executeQuery("select 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をご覧下さい。

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

...

7.3.1. テキストカーソル

...

7.3.2. バイナリカーソル

...

Chapter 8. PostGISリファレンス

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

[Note]

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

8.1. PostGIS Geometry/Geography/Box データ型

Abstract

このセクションでは、空間データを表現するためにPostGISとともにインストールされたカスタムPostgreSQLデータ型の一覧を示します。

データ型ごとに、型キャストのふるまいが記述されています。型キャストによって、あるデータ型の値が他のデータ型に変換されます。PostgreSQLでは、型を変換するために使われる関数に加えて、ユーザ定義型のキャストのふるまいの定義が可能です。キャストは自動的なふるまいを持つことができ、それによって、関数の引数をその関数が対応する型に自動的に変換できます。

キャストには明示的なふるまいがあります。このふるまいは、キャストはCAST(myval As sometype)またはmyval::sometypeという書式で指定されます。与えられた型に対応していないオーバロード関数を使うときに発生するあいまいなキャストの問題は、明示的なキャストによって回避できます。例えば、関数はbox2dまたはbox3dを受け付けるがジオメトリを受け付けない場合です。ジオメトリはボックス型の両方への自動キャストが可能なため、「あいまいな関数」エラーが発生します。このエラーを防ぐには、求められるボックス型への明示的なキャストを使用します。

全てのデータ型はtextにキャストできます。このため、明示的に指定する必要はありません。

box2d — 2次元バウンディングボックスを表現する型。
box3d — 3次元バウンディングボックスを表現する型。
geometry — 平面座標系を持つ空間地物を表現する型。
geometry_dump — 複雑なジオメトリの部品を記述するために使われる複合型です。
geography — 地理座標系 (回転楕円体)座標系を持つ空間地物を表現する型です。

Name

box2d — 2次元バウンディングボックスを表現する型。

説明

box2dは、ジオメトリまたはジオメトリコレクションの、2次元の囲い込んでいるボックスを表現するために使われる空間データ型です。たとえば、集約関数ST_Extentbox2dインスタンスを返します。

xmin, ymin, xmax, ymaxの値を含む表現。これらは、XとYの範囲の最小値と最大値を示しています。

box2dのテキスト表現はBOX(1 2,5 6)のようになります。

キャストの挙動

このテーブルでは、このデータ型で許容される明示的なキャストと自動キャストの一覧を挙げます。

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

Name

box3d — 3次元バウンディングボックスを表現する型。

説明

box3dは、ジオメトリまたはジオメトリのコレクションを囲む3次元のボックスを表現するために使われるPostGIS空間データ型です。たとえば、集約関数のST_3DExtentbox3dオブジェクトを返します。

この表現は、xmin, ymin, zmin, xmax, ymax, zmaxです。これらは、X, Y, Zの範囲の最小値と最大値を取ります。

box3dのテキスト表現はBOX3D(1 2 3,5 6 5)のようになります。

キャストの挙動

このテーブルでは、このデータ型で許容される明示的なキャストと自動キャストの一覧を挙げます。

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

Name

geometry — 平面座標系を持つ空間地物を表現する型。

説明

geometryは、平面 (ユークリッド)座標系上の地物を表現するために使われる基本的なPostGISの空間データ型です。

ジオメトリ上の全ての空間演算子は、ジオメトリが所属する空間参照系の単位を使います。

キャストの挙動

このテーブルでは、このデータ型で許容される明示的なキャストと自動キャストの一覧を挙げます。

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

Name

geometry_dump — 複雑なジオメトリの部品を記述するために使われる複合型です。

説明

geometry_dumpは、次のフィールドを持つ複合型です。

  • geom - ダンプされたジオメトリの要素を表現するジオメトリです。ジオメトリタイプは、使われた関数に依存します。

  • path[] - ダンプされたジオメトリ内におけるgeom要素へのパスを定義する1次整数配列。パス配列は1始まりです (path[1]が最初の要素です)。

ST_Dump*系関数で複雑なジオメトリを構成部品に分解する出力型として使います。


Name

geography — 地理座標系 (回転楕円体)座標系を持つ空間地物を表現する型です。

説明

geographyは、地理座標系上で地物を表現するために使われる空間型です。地理座標系は回転楕円体で地球をモデル化します。

ジオグラフィ型を用いた空間演算によって、回転楕円体モデルを考慮するので、より精度の良い結果が得られます。

キャストの挙動

このテーブルでは、このデータ型で許容される明示的なキャストと自動キャストの一覧を挙げます。

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

8.2. テーブル管理関数

Abstract

これらの関数は、ジオメトリカラムを含むテーブルの定義を支援します。

AddGeometryColumn — ジオメトリカラムを既存のテーブルに追加します。
DropGeometryColumn — ジオメトリカラムを空間テーブルから除去します。
DropGeometryTable — テーブルとgeometry_columnsの当該テーブルへの参照の全てを削除します。
Find_SRID — ジオメトリカラムで定義されているSRIDを返します。
Populate_Geometry_Columns — ジオメトリカラムが型修飾子で定義されるか、適切な空間制約を持つようにします。
UpdateGeometrySRID — ジオメトリカラム内の全ての地物のSRIDを更新し、テーブルのメタデータを更新します。

Name

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

Synopsis

text AddGeometryColumn(varchar table_name, varchar column_name, integer srid, varchar type, integer dimension, boolean use_typmod=true);

text AddGeometryColumn(varchar schema_name, varchar table_name, varchar column_name, integer srid, varchar type, integer dimension, boolean use_typmod=true);

text AddGeometryColumn(varchar catalog_name, varchar schema_name, varchar table_name, varchar column_name, integer srid, varchar type, integer dimension, boolean use_typmod=true);

説明

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

[Note]

Changed: 2.0.0 geometry_columnsがシステムカタログを読むビューになったため、geometry_columnsを更新しないようになりました。デフォルトでは制約を生成せず、PostgreSQLの型修飾子を使います。この関数によるWGS 84のPOINTカラムの構築とALTER TABLE some_table ADD COLUMN geom geometry(Point,4326);とは等価です。

Changed: 2.0.0 制約を使う必要がある場合には、use_typmodをFALSEにします。

[Note]

Changed: 2.0.0 ビューについては、geometry_columnsへの手動登録はできなくなりました。しかし、typmodテーブルジオメトリに対して構築されていて、かつラッパ関数が無いビューは、親テーブルカラムのtypmodの挙動を継承するので、正しく登録されます。他のジオメトリを出力するジオメトリ関数を使うビューについては、ビューのジオメトリカラムが正しく登録されるようにするため、typmodジオメトリへのキャストが必要です。Section 4.6.3, “手動でジオメトリカラムをgeometry_columnsに登録する”を参照して下さい。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1.

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

Enhanced: 2.0.0 use_typmod引数が導入されました。デフォルトでは制約を基にしたものでなくtypmodジオメトリカラムが生成されます。

-- データを保持するスキーマの生成
CREATE SCHEMA my_schema;
-- 新しい単純なPostgreSQLテーブルの生成
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)

-- テーブルにジオメトリカラムを追加\
SELECT AddGeometryColumn ('my_schema','my_spatial_table','geom',4326,'POINT',2);

-- 制約を基にした古い方法でPOINTカラムを追加
SELECT AddGeometryColumn ('my_schema','my_spatial_table','geom_c',4326,'POINT',2, false);

-- 制約を基にした古い方法でCURVEPOLYGONカラムを追加
SELECT AddGeometryColumn ('my_schema','my_spatial_table','geomcp_c',4326,'CURVEPOLYGON',2, false);

-- 再度説明を表示し、新しいジオメトリカラムの追加を明らかにする
\d my_schema.my_spatial_table
                            addgeometrycolumn
-------------------------------------------------------------------------
 my_schema.my_spatial_table.geomcp_c SRID:4326 TYPE:CURVEPOLYGON DIMS:2
(1 row)

                                    Table "my_schema.my_spatial_table"
  Column  |         Type         |                                Modifiers
----------+----------------------+-------------------------------------------------------------------------
 id       | integer              | not null default nextval('my_schema.my_spatial_table_id_seq'::regclass)
 geom     | geometry(Point,4326) |
 geom_c   | geometry             |
 geomcp_c | geometry             |
Check constraints:
    "enforce_dims_geom_c" CHECK (st_ndims(geom_c) = 2)
    "enforce_dims_geomcp_c" CHECK (st_ndims(geomcp_c) = 2)
    "enforce_geotype_geom_c" CHECK (geometrytype(geom_c) = 'POINT'::text OR geom_c IS NULL)
    "enforce_geotype_geomcp_c" CHECK (geometrytype(geomcp_c) = 'CURVEPOLYGON'::text OR geomcp_c IS NULL)
    "enforce_srid_geom_c" CHECK (st_srid(geom_c) = 4326)
    "enforce_srid_geomcp_c" CHECK (st_srid(geomcp_c) = 4326)

-- geometry_columnsビューにも新しいカラムが登録されています --
SELECT f_geometry_column As col_name, type, srid, coord_dimension As ndims
    FROM geometry_columns
    WHERE f_table_name = 'my_spatial_table' AND f_table_schema = 'my_schema';

 col_name |     type     | srid | ndims
----------+--------------+------+-------
 geom     | Point        | 4326 |     2
 geom_c   | Point        | 4326 |     2
 geomcp_c | CurvePolygon | 4326 |     2

Name

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

Synopsis

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フィールドと一致しなければならないことにご注意ください。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1.

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

[Note]

Changed: 2.0.0 この関数は後方互換のためのものです。geometry_columnsは現在はシステムカタログに対するビューですので、他のテーブルのカラムと同じようにALTER TABLEを使った削除が可能です。

SELECT DropGeometryColumn ('my_schema','my_spatial_table','geom');
                        ---- 結果出力 ----
                                          dropgeometrycolumn
------------------------------------------------------
 my_schema.my_spatial_table.geom effectively removed.

-- PostGIS 2.0以上では標準的なALTER TABLEと上の例とは等価です
-- 両方ともgeometry_columnsの登録を抹消します
ALTER TABLE my_schema.my_spatial_table DROP column geom;
                

Name

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

Synopsis

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()を使います。

[Note]

Changed: 2.0.0で この関数は後方互換のためのものです。geometry_columnsは現在はシステムカタログに対するビューですので、他のテーブルのカラムと同じようにDROP TABLEを使った削除が可能です。

SELECT DropGeometryTable ('my_schema','my_spatial_table');
---- 結果出力 ----
my_schema.my_spatial_table dropped.

-- 上の例は次の例と等価です --
DROP TABLE my_schema.my_spatial_table;
                

Name

Find_SRID — ジオメトリカラムで定義されているSRIDを返します。

Synopsis

integer Find_SRID(varchar a_schema_name, varchar a_table_name, varchar a_geomfield_name);

説明

指定したジオメトリカラムSRID整数値をGEOMETRY_COLUMNSテーブルの探索によって返します。ジオメトリカラムが正しく追加されていない (例: AddGeometryColumn関数)場合には、この関数は動作しません。

SELECT Find_SRID('public', 'tiger_us_state_2007', 'geom_4269');
find_srid
----------
4269

関連情報

ST_SRID


Name

Populate_Geometry_Columns — ジオメトリカラムが型修飾子で定義されるか、適切な空間制約を持つようにします。

Synopsis

text Populate_Geometry_Columns(boolean use_typmod=true);

int Populate_Geometry_Columns(oid relation_oid, boolean use_typmod=true);

説明

ジオメトリカラムが適切な型修飾子を持つか、geometry_columnsビュー内で正しく登録されていることを確実にするために空間制約を持つようにします。デフォルトでは、型修飾子を持たないすべてのジオメトリカラムを型修飾子を持つカラムに変換します。

後方互換のためと、それぞれの子テーブルが異なるジオメトリタイプを持つテーブル継承といった空間テーブルにとって必要があるためとの二つの理由から、古いCHECK制約の挙動がなお有効になっています。古い挙動が必要な場合には、新しいオプション引数でuse_typmod=falseを渡す必要があります。これが実行されると、型修飾子なしのジオメトリカラムが生成され、三つの制約が定義されます。特に、これは、テーブルに属するすべてのジオメトリカラムが少なくとも三つの制約を持つことを意味します。

  • enforce_dims_the_geom - あらゆるジオメトリが同じ次元を持つことを確実にします (ST_NDimsをご覧下さい)

  • enforce_geotype_the_geom - あらゆるジオメトリが同じ型を持つことを確実にします (GeometryTypeをご覧下さい)

  • enforce_srid_the_geom - あらゆるジオメトリが同じ投影法になることを確実にします (ST_SRIDをご覧下さい)

テーブルにoidがある場合には、この関数はテーブルのジオメトリカラム全てについて、SRIDと次元とジオメトリタイプを判定して、必要に応じて制約を追加しようとします。 成功した場合には、geometry_columnsに適切な行が追加され、その他の場合には、例外が捕まえられ、問題を記述したエラーが通知されます。

ビューのoidがある場合、テーブルの場合と同じで、SIRDと次元とジオメトリタイプを判定して、適切なエントリをgeometry_columnsテーブルに挿入しますが、制約の追加はされません。

パラメタの無い形式は、geometry_columnsの行を削除したうえで、全ての空間テーブルと空間ビューについて再挿入し、適切な空間制約をテーブルに追加する、パラメタ付きの形式の単純なラッパです。パラメタが無い形式は、検出したジオメトリカラムの数の要約とgeometry_columnsに挿入された行の数とを返します。パラメタ付きの形式は単純にgeometry_columnsに挿入された行の数を返します。

Availability: 1.4.0

Changed: 2.0.0 デフォルトでは、ジオメトリタイプの制限について、制約を確認する代わりに型修飾子を使います。新しいuse_typmodをFALSEに設定して使うことで、制約確認を使用することができます。

Enhanced: 2.0.0 use_typmod任意引数が導入されました。カラムが型修飾子で生成されるか制約チェックで作られるかの制御ができます。

CREATE TABLE public.myspatial_table(gid serial, geom geometry);
INSERT INTO myspatial_table(geom) VALUES(ST_GeomFromText('LINESTRING(1 2, 3 4)',4326) );
-- 型修飾子を使います
-- 動作するにはデータが存在していなければなりません
SELECT Populate_Geometry_Columns('public.myspatial_table'::regclass);

populate_geometry_columns
--------------------------
                        1


\d myspatial_table

                                   Table "public.myspatial_table"
 Column |           Type            |                           Modifiers
--------+---------------------------+---------------------------------------------------------------
 gid    | integer                   | not null default nextval('myspatial_table_gid_seq'::regclass)
 geom   | geometry(LineString,4326) |
-- カラムが型修飾子でないか、既に制約が存在している場合には制約を使います
-- 動作するにはデータが存在していなければなりません
CREATE TABLE public.myspatial_table_cs(gid serial, geom geometry);
INSERT INTO myspatial_table_cs(geom) VALUES(ST_GeomFromText('LINESTRING(1 2, 3 4)',4326) );
SELECT Populate_Geometry_Columns('public.myspatial_table_cs'::regclass, false);
populate_geometry_columns
--------------------------
                        1
\d myspatial_table_cs

                          Table "public.myspatial_table_cs"
 Column |   Type   |                            Modifiers
--------+----------+------------------------------------------------------------------
 gid    | integer  | not null default nextval('myspatial_table_cs_gid_seq'::regclass)
 geom   | geometry |
Check constraints:
    "enforce_dims_geom" CHECK (st_ndims(geom) = 2)
    "enforce_geotype_geom" CHECK (geometrytype(geom) = 'LINESTRING'::text OR geom IS NULL)
    "enforce_srid_geom" CHECK (st_srid(geom) = 4326)

Name

UpdateGeometrySRID — ジオメトリカラム内の全ての地物のSRIDを更新し、テーブルのメタデータを更新します。

Synopsis

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の参照を更新します。カラムが型定義で強制されているなら、型定義は変更されます。ご注意: スキーマ対応版PostgreSQLでは、スキーマが提供されていない場合には、current_schema()を使用します。

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

ジオメトリを、EWKT書式を使って、SRIDを持つ道路テーブルに挿入します。

COPY roads (geom) FROM STDIN;
SRID=4326;LINESTRING(0 0, 10 10)
SRID=4326;LINESTRING(10 10, 15 0)
\.
                

これにより道路テーブルが、以前がどんなSRIDであっても、4326に変更されます。

SELECT UpdateGeometrySRID('roads','geom',4326);

上述の例と、次のDDL手続き (訳注: DDLはData Definition Languageの略で、データ構造の操作を行う言語を指し、この場合は CREATE TABLEやALTER TABLE等が該当します)とは同じです。

ALTER TABLE roads
  ALTER COLUMN geom TYPE geometry(MULTILINESTRING, 4326)
    USING ST_SetSRID(geom,4326);

ロードしたデータの変換座標系が誤りである (またはunknownになっている)けれどもWebメルカトルに一度の処理で変換したい場合、DDLで実行可能ですが、PostGIS管理関数では一度の処理ですむ等価なものはありません。

ALTER TABLE roads
 ALTER COLUMN geom TYPE geometry(MULTILINESTRING, 3857) USING ST_Transform(ST_SetSRID(geom,4326),3857) ;

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

ST_Collect — ジオメトリの集合からジオメトリコレクションまたはマルチ系ジオメトリを生成します。
ST_LineFromMultiPoint — マルチポイントジオメトリからラインストリングを生成します。
ST_MakeEnvelope — 座標値の最小値と最大値から矩形ポリゴンを生成します。
ST_MakeLine — POINT、MULTIPOINT、LINESTRINGからLINESTRINGを生成します。
ST_MakePoint — 2次元、3次元 (XYZ)、4次元のポイントを生成します。
ST_MakePointM — X, Y, M値からポイントを生成します。
ST_MakePolygon — 外殻と穴のリストからポリゴンを生成します。
ST_Point — X, YとSRIDの値からポイントを生成します。
ST_PointZ — X, Y, ZとSRIDの値からポイントを生成します。
ST_PointM — X, Y, MとSRIDの値からポイントを生成します。
ST_PointZM — X, Y, Z, MとSRIDの値からポイントを生成します。
ST_Polygon — ラインストリングから指定したSRIDを持つポリゴンを生成します。
ST_TileEnvelope — Webメルカトル (SRID:3857)上で XYZタイルを使った矩形ポリゴンを生成します。
ST_HexagonGrid — 引数ジオメトリの境界を完全にカバーする六角形とセルインデックスを返します。
ST_Hexagon — 与えられたエッジサイズと六角形グリッド空間内のセル座標を使って単一の六角形を返します。
ST_SquareGrid — 引数ジオメトリの境界を完全にカバーするグリッド正方形とセルインデックスを返します。
ST_Square — 与えられたエッジサイズと六角形グリッド空間内のセル座標を使って単一の正方形を返します。
ST_Letters — デフォルトの開始位置を原点とし、デフォルトの高さを100とする、ジオメトリとして描画された文字を返します。

Name

ST_Collect — ジオメトリの集合からジオメトリコレクションまたはマルチ系ジオメトリを生成します。

Synopsis

geometry ST_Collect(geometry g1, geometry g2);

geometry ST_Collect(geometry[] g1_array);

geometry ST_Collect(geometry set g1field);

説明

ジオメトリを集めてジオメトリコレクションにします。結果はマルチ系ジオメトリかジオメトリコレクションかのいずれかで、この差は、入力ジオメトリのタイプが同じか異なるか(均質か不均質か)で決まります。入力ジオメトリはコレクション内で変更されることはありません。

1番目の形式: 二つの入力ジオメトリを受け付ける。

2番目の形式: ジオメトリの配列を受け付ける。

3番目の形式: ジオメトリの行集合を受け付ける集約関数。

[Note]

入力ジオメトリのいずれかがコレクション (マルチ系ジオメトリまたはジオメトリコレクション)の場合には、ST_Collectはジオメトリコレクションを返します (入れ子になったコレクションを含む唯一のタイプであるため)。これを避けるには、サブクエリでST_Dump を使い、入力コレクションを分解できない要素にまで分解します (下に例があります)。

[Note]

ST_CollectとST_Unionは似ているように見えますが、実際には全く異なる処理を行います。ST_Collectは入力ジオメトリを変更せずにコレクションにする集約関数です。ST_Unionは、オーバラップしている時は幾何学的に併合し、インタセクトするところでラインストリングを分割します。境界をディゾルブするときには単一のジオメトリを返す可能性があります。

Availability: 1.4.0 - ST_Collect(geometry)が導入されました。ST_Collectがより多くのジオメトリをより早く扱えるよう強化されました。

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

例 - 二つ入力を引数に取る形式

2次元ポイントを収集します。

SELECT ST_AsText( ST_Collect( ST_GeomFromText('POINT(1 2)'),
        ST_GeomFromText('POINT(-2 3)') ));

st_astext
----------
MULTIPOINT((1 2),(-2 3))

2次元ポイントの収集

SELECT ST_AsEWKT( ST_Collect( ST_GeomFromEWKT('POINT(1 2 3)'),
                ST_GeomFromEWKT('POINT(1 2 4)') ) );

                st_asewkt
-------------------------
 MULTIPOINT(1 2 3,1 2 4)
 

曲線を収集します。

SELECT ST_AsText( ST_Collect( 'CIRCULARSTRING(220268 150415,220227 150505,220227 150406)',
                'CIRCULARSTRING(220227 150406,2220227 150407,220227 150406)'));

                st_astext
------------------------------------------------------------------------------------
MULTICURVE(CIRCULARSTRING(220268 150415,220227 150505,220227 150406),
 CIRCULARSTRING(220227 150406,2220227 150407,220227 150406))

例 - 配列を引数に取る形式

サブクエリから配列を生成するコンストラクタの使用。

SELECT ST_Collect( ARRAY( SELECT geom FROM sometable ) );

値から配列を生成するコンストラクタの使用。

SELECT ST_AsText(  ST_Collect(
                ARRAY[ ST_GeomFromText('LINESTRING(1 2, 3 4)'),
                        ST_GeomFromText('LINESTRING(3 4, 4 5)') ] )) As wktcollect;

--wkt collect --
MULTILINESTRING((1 2,3 4),(3 4,4 5))

例 - 集約関数の形式

テーブル内のジオメトリのグループ化による複数コレクションを生成します。

SELECT stusps, ST_Collect(f.geom) as geom
         FROM (SELECT stusps, (ST_Dump(geom)).geom As geom
                                FROM
                                somestatetable ) As f
        GROUP BY stusps

関連情報

ST_Dump, ST_Union


Name

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

Synopsis

geometry ST_LineFromMultiPoint(geometry aMultiPoint);

説明

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

ポイントまたはラインストリングの入力からラインを生成するにはST_MakeLineを使います。

This function supports 3d and will not drop the z-index.

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

SELECT ST_AsEWKT(  ST_LineFromMultiPoint('MULTIPOINT(1 2 3, 4 5 6, 7 8 9)')  ));

-- 結果 --
LINESTRING(1 2 3,4 5 6,7 8 9)

関連情報

ST_AsEWKT, ST_MakeLine


Name

ST_MakeEnvelope — 座標値の最小値と最大値から矩形ポリゴンを生成します。

Synopsis

geometry ST_MakeEnvelope(float xmin, float ymin, float xmax, float ymax, integer srid=unknown);

説明

XとYの最小値と最大値から矩形ポリゴンを生成します。入力値はSRIDで指定された空間参照系に合わせなければなりません。SRIDが指定されていない場合には、不明な空間参照系 (SRID 0)が使われます。

Availability: 1.5

Enhanced: 2.0 SRID指定なしでエンベロープを指定できるようになりました。

例: バウンディングボックスポリゴンの生成

SELECT ST_AsText( ST_MakeEnvelope(10, 10, 11, 11, 4326) );

st_asewkt
-----------
POLYGON((10 10, 10 11, 11 11, 11 10, 10 10))

Name

ST_MakeLine — POINT、MULTIPOINT、LINESTRINGからLINESTRINGを生成します。

Synopsis

geometry ST_MakeLine(geometry geom1, geometry geom2);

geometry ST_MakeLine(geometry[] geoms_array);

geometry ST_MakeLine(geometry set geoms);

説明

ポイント、マルチポイントまたはラインストリングのジオメトリの点を含むラインストリングを生成します。他のジオメトリではエラーが発生します。

1番目の形式: 二つの入力ジオメトリを受け付ける。

2番目の形式: ジオメトリの配列を受け付ける。

形式3: ジオメトリの行集合を受け付ける約関数。入力ジオメトリの順序を確実にするには、関数呼び出しでORDER BYを使うか、ORDER BY節を持つサブクエリを使います。

入力ラインストリングの開始位置で重複するノードは単一のポイントに減らされます。ポイントとマルチポイントの入力での重複するポイントは減らされません。出力ラインストリングから重複ポイントを削除するにはST_RemoveRepeatedPointsが使えます。

This function supports 3d and will not drop the z-index.

Availability: 2.3.0 - MULTIPOINT入力要素への対応が導入されました

Availability: 2.0.0 - LINESTRING入力要素への対応が導入されました

Availability: 1.4.0 - ST_MakeLine(geomarray)が導入されました。ST_MakeLine集約関数はより多くのポイントをより早く扱うための強化が施されています。

例: 二つ入力を引数に取る形式

二つのポイントで構成されるラインを生成します。

SELECT ST_AsText( ST_MakeLine(ST_Point(1,2), ST_Point(3,4)) );

          st_astext
---------------------
 LINESTRING(1 2,3 4)

二つの3次元ポイントから3次元ラインを生成します。

SELECT ST_AsEWKT( ST_MakeLine(ST_MakePoint(1,2,3), ST_MakePoint(3,4,5) ));

                st_asewkt
-------------------------
 LINESTRING(1 2 3,3 4 5)

二つの接続されていないラインストリングからラインを生成します。

select ST_AsText( ST_MakeLine( 'LINESTRING(0 0, 1 1)', 'LINESTRING(2 2, 3 3)' ) );

          st_astext
-----------------------------
 LINESTRING(0 0,1 1,2 2,3 3)

例: 配列を引数に取る形式

並べ替えを伴うサブクエリで作られた配列からラインを生成します。

SELECT ST_MakeLine( ARRAY( SELECT ST_Centroid(geom) FROM visit_locations ORDER BY visit_time) );

3次元ポイントの配列から3次元ラインを生成します。

SELECT ST_AsEWKT( ST_MakeLine(
          ARRAY[ ST_MakePoint(1,2,3), ST_MakePoint(3,4,5), ST_MakePoint(6,6,6) ]  ));

                st_asewkt
-------------------------
LINESTRING(1 2 3,3 4 5,6 6 6)

例: 集約関数の形式

この例ではGPSトラックの集合からポイントの時間ベースのシーケンスを問い合わせています。結果ジオメトリは、GPSトラックの移動順ポイントで構成されるラインストリングです。

ORDER BY節を使うことで、正しい順序のLINESTRINGが生成できます。

SELECT gps.track_id, ST_MakeLine(gps.geom ORDER BY gps_time) As geom
        FROM gps_points As gps
        GROUP BY track_id;

PostgreSQL 9より前の版では、サブクエリでの順序付けを使うことができます。ただし、クエリプランでサブクエリの並び順が尊重されない場合があります。

SELECT gps.track_id, ST_MakeLine(gps.geom) As geom
        FROM ( SELECT track_id, gps_time, geom
                        FROM gps_points ORDER BY track_id, gps_time ) As gps
        GROUP BY track_id;

Name

ST_MakePoint — 2次元、3次元 (XYZ)、4次元のポイントを生成します。

Synopsis

geometry ST_MakePoint(float x, float y);

geometry ST_MakePoint(float x, float y, float z);

geometry ST_MakePoint(float x, float y, float z, float m);

説明

2次元、3次元 (XYZ)、4次元 (XYZM)のポイントを生成します。

XYM座標を持つポイントを作るにはST_MakePointMを使います。

OGC準拠ではありませんが、ST_MakePointST_GeomFromTextST_PointFromTextより高速かつ正確です。また、簡単に数値の座標値を使用できます。

[Note]

地理座標系について、Xは経度で、Yは緯度です。

This function supports 3d and will not drop the z-index.

-- SRID不明のポイントを返します
SELECT ST_MakePoint(-71.1043443253471, 42.3150676015829);

-- WGS 84経度緯度とするポイントを返します。
SELECT ST_SetSRID(ST_MakePoint(-71.1043443253471, 42.3150676015829),4326);

-- 3次元ポイント (たとえば標高を持つ)を返します
SELECT ST_MakePoint(1, 2,1.5);

-- ポイントのZ値を得ます
SELECT ST_Z(ST_MakePoint(1, 2,1.5));
result
-------
1.5

Name

ST_MakePointM — X, Y, M値からポイントを生成します。

Synopsis

geometry ST_MakePointM(float x, float y, float m);

説明

X, Y, M (Measure) 値からポイントを生成します。

XY, XYZ, XYZM座標のポイントを作るにはST_MakePointを使います。

[Note]

地理座標系について、Xは経度で、Yは緯度です。

[Note]

ST_AsEWKT は文字列出力のために使います。ST_AsTextがM値に対応していないためです。

不明なSRIDでのポイントを生成します。

SELECT ST_AsEWKT(  ST_MakePointM(-71.1043443253471, 42.3150676015829, 10)  );

                                   st_asewkt
-----------------------------------------------
 POINTM(-71.1043443253471 42.3150676015829 10)

WGS 84地理座標系のM値を持つポイントの生成。

SELECT ST_AsEWKT( ST_SetSRID(  ST_MakePointM(-71.104, 42.315, 10),  4326));

                                                st_asewkt
---------------------------------------------------------
SRID=4326;POINTM(-71.104 42.315 10)

生成したポイントのM値を取得します。

SELECT ST_M(  ST_MakePointM(-71.104, 42.315, 10)  );

result
-------
10

Name

ST_MakePolygon — 外殻と穴のリストからポリゴンを生成します。

Synopsis

geometry ST_MakePolygon(geometry linestring);

geometry ST_MakePolygon(geometry outerlinestring, geometry[] interiorlinestrings);

説明

与えられた外殻と任意指定の穴の配列で掲載されるポリゴンを生成します。入力ジオメトリは閉じたラインストリング (リング)でなければなりません。

形式1: 一つの外殻のラインストリングを受け付けます。

形式2: 外殻のラインストリングと内部 (穴)のラインストリングの配列とを受け付けます。ジオメトリ配列はPostgreSQLのarray_agg(), ARRAY[], ARRAY()コンストラクタを使います。

[Note]

この関数はマルチラインストリングを受け付けません。ラインストリングの生成にはST_LineMergeを使用します。また、ラインストリングを抽出するにはST_Dumpを使用します。

This function supports 3d and will not drop the z-index.

例: 単一入力の形式

2次元ラインストリングからポリゴンを生成します。

SELECT ST_MakePolygon( ST_GeomFromText('LINESTRING(75 29,77 29,77 29, 75 29)'));

開いたラインストリングを閉じるためにST_StartPointST_AddPointを使用したうえでポリゴンを生成します。

SELECT ST_MakePolygon( ST_AddPoint(foo.open_line, ST_StartPoint(foo.open_line)) )
FROM (
  SELECT ST_GeomFromText('LINESTRING(75 29,77 29,77 29, 75 29)') As open_line) As foo;

3次元ラインストリングからポリゴンを生成します。

SELECT ST_AsEWKT( ST_MakePolygon( 'LINESTRING(75.15 29.53 1,77 29 1,77.6 29.5 1, 75.15 29.53 1)'));

st_asewkt
-----------
POLYGON((75.15 29.53 1,77 29 1,77.6 29.5 1,75.15 29.53 1))

M値を持つラインストリングからポリゴンを生成します。

SELECT ST_AsEWKT( ST_MakePolygon( 'LINESTRINGM(75.15 29.53 1,77 29 1,77.6 29.5 2, 75.15 29.53 2)' ));

st_asewkt
----------
POLYGONM((75.15 29.53 1,77 29 1,77.6 29.5 2,75.15 29.53 2))

例: 内部の穴を持つ外殻の形式

余分な穴を持つドーナツポリゴンを生成します。

SELECT ST_MakePolygon( ST_ExteriorRing( ST_Buffer(ring.line,10)),
        ARRAY[  ST_Translate(ring.line, 1, 1),
                ST_ExteriorRing(ST_Buffer(ST_Point(20,20),1)) ]
        )
FROM (SELECT ST_ExteriorRing(
        ST_Buffer(ST_Point(10,10),10,10)) AS line ) AS ring;

湖を表現する穴を持つ県の境界の集合を生成します。入力は県ポリゴン/マルチポリゴンのテーブルと水涯線のラインストリングのテーブルです。湖を構成するラインはST_IsClosedで判定します。県を示すラインはST_Boundaryで抽出します。ST_MakePolygonが必要ですので、境界をST_LineMergeで単一のLINESTRINGに強制します(県が二つ以上の領域を持つか島を持つ場合には、不正なポリゴンを生成します)。LEFT JOINを使って、湖の無い県を含む全ての県が返ることを保証しています。

[Note]

NULL配列をST_MakePolygonに渡すとNULLが返るので、CASE式を使っています。

SELECT p.gid, p.province_name,
        CASE WHEN array_agg(w.geom) IS NULL
        THEN p.geom
        ELSE  ST_MakePolygon( ST_LineMerge(ST_Boundary(p.geom)),
                        array_agg(w.geom)) END
FROM
        provinces p LEFT JOIN waterlines w
                ON (ST_Within(w.geom, p.geom) AND ST_IsClosed(w.geom))
GROUP BY p.gid, p.province_name, p.geom;

他には、相関サブクエリと行集合を配列に変換するARRAY()コンストラクタとを使う手法があります。

SELECT p.gid,  p.province_name,
    CASE WHEN EXISTS( SELECT w.geom
        FROM waterlines w
        WHERE ST_Within(w.geom, p.geom)
        AND ST_IsClosed(w.geom))
    THEN ST_MakePolygon(
        ST_LineMerge(ST_Boundary(p.geom)),
        ARRAY( SELECT w.geom
            FROM waterlines w
            WHERE ST_Within(w.geom, p.geom)
            AND ST_IsClosed(w.geom)))
    ELSE p.geom
    END AS geom
FROM provinces p;

関連情報

ST_BuildArea ST_Polygon


Name

ST_Point — X, YとSRIDの値からポイントを生成します。

Synopsis

geometry ST_Point(float x, float y);

geometry ST_Point(float x, float y, integer srid=unknown);

説明

与えられたXとYの座標値からポイントを返します。これは、XとYを取るSQL-MMのST_MakePointと同等です。

[Note]

地理座標系について、Xは経度で、Yは緯度です。

Enhanced: 3.2.0 SRID任意引数が追加されました。古いバージョンでは、ジオメトリにSRIDを与えるにはST_SetSRIDを併用しなければなりませんでした。

This method implements the SQL/MM specification. SQL-MM 3: 6.1.2

例: ジオメトリ

SELECT ST_Point( -71.104, 42.315);
SELECT ST_SetSRID(ST_Point( -71.104, 42.315),4326);

New in 3.2.0: SRIDが指定できます

SELECT ST_Point( -71.104, 42.315, 4326);

例: ジオグラフィ

PostGIS 3.2より前の構文

SELECT CAST( ST_SetSRID(ST_Point( -71.104, 42.315), 4326) AS geography);

3.2ではSRIDを含むことができます

SELECT CAST( ST_Point( -71.104, 42.315, 4326) AS geography);

PostgreSQLはキャストの簡略表記として::を提供しています

SELECT ST_Point( -71.104, 42.315, 4326)::geography;

ポイントの座標が地理座標系 (WGS84等)でない場合には、ジオグラフィにキャストする前に座標系変換を行う必要があります。この例では、ペンシルバニア州平面フィート (SRID 2273)上のポイントをWGS84 (SRID 4326)に座標系変換を行っています。

SELECT ST_Transform(ST_SetSRID( ST_Point( 3637510, 3014852 ), 2273), 4326)::geography;

Name

ST_PointZ — X, Y, ZとSRIDの値からポイントを生成します。

Synopsis

geometry ST_PointZ(float x, float y, float z, integer srid=unknown);

説明

与えたX,Y,Z座標値を持ち、与えた場合はSRID値も持つポイントを生成します。

Enhanced: 3.2.0 SRID任意引数が追加されました。古いバージョンでは、ジオメトリにSRIDを与えるにはST_SetSRIDを併用しなければなりませんでした。

SELECT ST_PointZ(-71.104, 42.315, 3.4, 4326)
SELECT ST_PointZ(-71.104, 42.315, 3.4, srid =
> 4326)
SELECT ST_PointZ(-71.104, 42.315, 3.4)

Name

ST_PointM — X, Y, MとSRIDの値からポイントを生成します。

Synopsis

geometry ST_PointM(float x, float y, float m, integer srid=unknown);

説明

与えたX,Y,M座標値を持ち、与えた場合はSRID値も持つポイントを生成します。

Enhanced: 3.2.0 SRID任意引数が追加されました。古いバージョンでは、ジオメトリにSRIDを与えるにはST_SetSRIDを併用しなければなりませんでした。

SELECT ST_PointM(-71.104, 42.315, 3.4, 4326)
SELECT ST_PointM(-71.104, 42.315, 3.4, srid =
> 4326)
SELECT ST_PointM(-71.104, 42.315, 3.4)

Name

ST_PointZM — X, Y, Z, MとSRIDの値からポイントを生成します。

Synopsis

geometry ST_PointZM(float x, float y, float z, float m, integer srid=unknown);

説明

与えたX,Y,Z,M座標値を持ち、与えた場合はSRID値も持つポイントを生成します。

Enhanced: 3.2.0 SRID任意引数が追加されました。古いバージョンでは、ジオメトリにSRIDを与えるにはST_SetSRIDを併用しなければなりませんでした。

SELECT ST_PointZM(-71.104, 42.315, 3.4, 4.5, 4326)
SELECT ST_PointZM(-71.104, 42.315, 3.4, 4.5, srid =
> 4326)
SELECT ST_PointZM(-71.104, 42.315, 3.4, 4.5)

Name

ST_Polygon — ラインストリングから指定したSRIDを持つポリゴンを生成します。

Synopsis

geometry ST_Polygon(geometry lineString, integer srid);

説明

与えられたラインストリングから構築し、sridから空間参照系を指定したポリゴンを返します。

ST_PolygonはST_MakePolygonの形式1の、SRIDの設定を追加したものに似ています。

穴を持つポリゴンを生成するには、ST_MakePolygonの形式2を使い、ST_SetSRIDを使います。

[Note]

この関数はマルチラインストリングを受け付けません。ラインストリングの生成にはST_LineMergeを使用します。また、ラインストリングを抽出するにはST_Dumpを使用します。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1.

This method implements the SQL/MM specification. SQL-MM 3: 8.3.2

This function supports 3d and will not drop the z-index.

2次元ポリゴンを生成します。

SELECT ST_AsText( ST_Polygon('LINESTRING(75 29, 77 29, 77 29, 75 29)'::geometry, 4326) );

-- 結果 --
POLYGON((75 29, 77 29, 77 29, 75 29))

3次元ポリゴンを生成します。

SELECT ST_AsEWKT( ST_Polygon( ST_GeomFromEWKT('LINESTRING(75 29 1, 77 29 2, 77 29 3, 75 29 1)'), 4326) );

-- 結果 --
SRID=4326;POLYGON((75 29 1, 77 29 2, 77 29 3, 75 29 1))

Name

ST_TileEnvelope — Webメルカトル (SRID:3857)上で XYZタイルを使った矩形ポリゴンを生成します。

Synopsis

geometry ST_TileEnvelope(integer tileZoom, integer tileX, integer tileY, geometry bounds=SRID=3857;LINESTRING(-20037508.342789 -20037508.342789,20037508.342789 20037508.342789), float margin=0.0);

説明

XYZ tile systemでのタイルの範囲を示す長方形ポリゴンを生成します。タイルはズームレベルを示すZと、そのレベルでのタイルインデックスを示すX, Yで指定します。ST_AsMVTGeomでジオメトリをMVTタイルの座標空間に変換のために必要なタイル境界を定義するために使います。

デフォルトでは、タイルエンベロープの座標系はWeb Mercator (SRID: 3857)で、標準的なウェブメルカトルの範囲 (-20037508.342789, 20037508.342789)を取ります。これがMVTタイルで使用される最も標準的な座標系です。任意パラメータboundsを使うと、あらゆる座標系のタイルを生成することができます。SRIDを持ち、ズームレベル0の時の、ジオメトリのXYZタイルシステムが内側に存在する矩形を示すジオメトリを与えます。

任意パラメータmarginは、タイルを与えられた割合だけ拡張するために使います。たとえばmargin=0.125と指定すると、12.5%拡張します。これは、ST_AsMVTGeomで使われている、タイルサイズが4096の時にbuffer=512と指定するのと等価です。タイル表示領域の外側にバッファを生成するために使いますが、この範囲はタイル描画に影響を与えます。たとえば、市名 (ポイント)を一つのタイルの端付近にあっても、そのラベルが二つのタイルで描画されるべきです。拡張したタイルをクエリで使うと、両方のタイルに市名のポイントが含まれることになります。負数を指定すると反対に縮小します。-0.5より小さい値は、タイルを完全に消すことになるので、許可されません。ST_AsMVTGeomと併用する時はマージンを指定しないでください。ST_AsMVTの例をご覧下さい。

Enhanced: 3.1.0 marginパラメータが追加されました。

Availability: 3.0.0

例: タイルエンベロープの構築

SELECT ST_AsText( ST_TileEnvelope(2, 1, 1) );

 st_astext
------------------------------
 POLYGON((-10018754.1713945 0,-10018754.1713945 10018754.1713945,0 10018754.1713945,0 0,-10018754.1713945 0))

SELECT ST_AsText( ST_TileEnvelope(3, 1, 1, ST_MakeEnvelope(-180, -90, 180, 90, 4326) ) );

                      st_astext
------------------------------------------------------
 POLYGON((-135 45,-135 67.5,-90 67.5,-90 45,-135 45))

関連情報

ST_MakeEnvelope


Name

ST_HexagonGrid — 引数ジオメトリの境界を完全にカバーする六角形とセルインデックスを返します。

Synopsis

setof record ST_HexagonGrid(float8 size, geometry bounds);

説明

平面の六角形タイルの概念から始まります。(地球の六角形タイルではなくH3タイルスキーマではありません)。平面 SRS とエッジサイズを与えると、SRS の原点から始まり、平面の一意な六角形のタイル、すなわち Tiling(SRS, Size)が一つ存在します。この関数は、指定されたTiling(SRS, Size)内の六角形が指定された境界を覆っているかどうかという質問に答えます。

出力六角形のSRSは境界ジオメトリのSRSです。

六角形の辺の長さを2倍または3倍にすることで、元のタイルに適合する新しい親タイルが生成されます。残念ながら子タイルが完全に親タイルの中に入るような親六角形タイルを生成することはできません。

Availability: 3.1.0

例: 六角形の中の点を数え上げる

六角形タイリングに対してポイントをまとめるには、ポイントの範囲を境界として使って六角形グリッドを生成し、グリッドに空間的に結合します。

SELECT COUNT(*), hexes.geom
FROM
    ST_HexagonGrid(
        10000,
        ST_SetSRID(ST_EstimatedExtent('pointtable', 'geom'), 3857)
    ) AS hexes
    INNER JOIN
    pointtable AS pts
    ON ST_Intersects(pts.geom, hexes.geom)
GROUP BY hexes.geom;

例: ポリゴンの六角形カバレッジの生成

ポリゴン境界ごとに六角形の集合を生成し、六角形とインタセクトしないものを除外すると、ポリゴンごとのタイルとなります。

州のタイルは、それぞれの州の六角形のカバレッジとなり、複数の六角形が州境界で重なります。

[Note]

LATERALキーワードは、FROMリスト内の、対象より前のテーブルを参照する時は、集合を返す関数に暗黙的に含まれます。 CROSS JOIN LATERAL、CROSS JOIN、指定なし、は、この例の同じ構成要素です。

SELECT admin1.gid, hex.geom
FROM
    admin1
    CROSS JOIN
    ST_HexagonGrid(100000, admin1.geom) AS hex
WHERE
    adm0_a3 = 'USA'
    AND
    ST_Intersects(admin1.geom, hex.geom)

Name

ST_Hexagon — 与えられたエッジサイズと六角形グリッド空間内のセル座標を使って単一の六角形を返します。

Synopsis

geometry ST_Hexagon(float8 size, integer cell_i, integer cell_j, geometry origin);

説明

ST_HexagonGridと同じ六角形タイルの概念を使いますが、求めるセルの座標に一つだけの六角形を生成します。任意でタイルの原点の座標を調整できます。デフォルトの原点座標は0,0です。

六角形はSRIDの設定なしで生成されるので、SRIDを期待する値に設定するためにST_SetSRIDを使います。

Availability: 3.1.0

例: 原点で六角形の生成

SELECT ST_AsText(ST_SetSRID(ST_Hexagon(1.0, 0, 0), 3857));

POLYGON((-1 0,-0.5
         -0.866025403784439,0.5
         -0.866025403784439,1
         0,0.5
         0.866025403784439,-0.5
         0.866025403784439,-1 0)) 

Name

ST_SquareGrid — 引数ジオメトリの境界を完全にカバーするグリッド正方形とセルインデックスを返します。

Synopsis

setof record ST_SquareGrid(float8 size, geometry bounds);

説明

平面の正方形タイルの概念から始まります。与えられた平面SRSとエッジサイズに対して、SRS原点から始まり、一意の平面の正方形タイル(SRS, Size)が一つ存在します。この関数は、与えられたタイル(SRS, Size)内のグリッド内のどのタイルが与えられた境界とオーバラップするかという問題に答えを出します。

出力正方形のSRSは境界ジオメトリのSRSです。

正方形の2倍またはエッジサイズによって、新しい親タイルが生成されます。親タイルは完全に元のタイルに適合します。標準のウェブマップにおけるメルカトルのタイルは、メルカトル平面の2の累乗での正方形です。

Availability: 3.1.0

例: 国の1度グリッドの生成

グリッドは国の境界全体を埋めます。国に接触する四角形が欲しい場合には、ST_Intersects後にフィルタリングする必要があります。

WITH grid AS (
SELECT (ST_SquareGrid(1, ST_Transform(geom,4326))).*
FROM admin0 WHERE name = 'Canada'
)
  SELEcT ST_AsText(geom)
  FROM grid

例: 正方形内のポイントの数え上げ (細かくした単一のグリッドを使用)

正方形タイルのポイントのサマリを行うには、境界としてポイントの拡張を使った正方形グリッドを生成し、グリッドに空間的に結合します。推定範囲は実際の範囲と異なる場合があるのでご注意下さい。慎重に取り扱うようにし、最低でも確実にテーブルを解析して下さい。

SELECT COUNT(*), squares.geom
    FROM
    pointtable AS pts
    INNER JOIN
    ST_SquareGrid(
        1000,
        ST_SetSRID(ST_EstimatedExtent('pointtable', 'geom'), 3857)
    ) AS squares
    ON ST_Intersects(pts.geom, squares.geom)
    GROUP BY squares.geom

例: ポイントごとのグリッドの集合を使った正方形内のポイント数え上げ

これは最初の例と同じ結果になりますが、ポイント数が多くなると遅くなります。

SELECT COUNT(*), squares.geom
    FROM
    pointtable AS pts
    INNER JOIN
    ST_SquareGrid(
        1000,
       pts.geom
    ) AS squares
    ON ST_Intersects(pts.geom, squares.geom)
    GROUP BY squares.geom

Name

ST_Square — 与えられたエッジサイズと六角形グリッド空間内のセル座標を使って単一の正方形を返します。

Synopsis

geometry ST_Square(float8 size, integer cell_i, integer cell_j, geometry origin);

説明

ST_SquareGridと同じ正方形タイルの概念を使っていますが、求めるセルの座標に一つだけの正方形を生成します。任意でタイルの原点の座標を調整できます。デフォルトの原点座標は0,0です。

四角形はSRIDの設定なしで生成されるので、SRIDを期待する値に設定するためにST_SetSRIDを使います。

Availability: 3.1.0

例: 原点で四角形の生成

SELECT ST_AsText(ST_SetSRID(ST_Square(1.0, 0, 0), 3857));

 POLYGON((0 0,0 1,1 1,1 0,0 0))

Name

ST_Letters — デフォルトの開始位置を原点とし、デフォルトの高さを100とする、ジオメトリとして描画された文字を返します。

Synopsis

geometry ST_Letters(text letters, json font);

説明

組込みフォントを使って、出力文字列をマルチポリゴンとして描画します。ディセンダからキャピタルまでの文字高さは100.0です。デフォルトのベースラインの開始位置は原点に置かれます。フォントのオーバライドは文字をキーとしたJSONマッピングと、ディセンダからキャピタルまでの1000単位の高さを持つフォント形状のTWKBをbase64エンコードしたものを渡します。

テキストは、デフォルトでは原点に生成されるので、テキストの位置変更とサイズ変更とを行います。最初にST_Scale関数を適用し、その後ST_Translate関数を適用します。

Availability: 3.3.0

例: 単語'Yo'の生成

SELECT ST_AsText(ST_Letters('Yo'), 1);

ST_Letterで生成した文字

例: 単語の拡大と移動

SELECT ST_Translate(ST_Scale(ST_Letters('Yo'), 10, 10), 100,100);

8.4. ジオメトリアクセサ

GeometryType — ジオメトリのタイプを文字列で返します。
ST_Boundary — ジオメトリの境界を返します。
ST_BoundingDiagonal — ジオメトリのバウンディングボックスの対角線を返します。
ST_CoordDim — ジオメトリの座標次元を返します。
ST_Dimension — ST_Geometry値の座標次元を返します。
ST_Dump — ジオメトリの要素となるgeometry_dump行の集合を返します。
ST_DumpPoints — ジオメトリ内の座標の行であるgeometry_dump行の集合を返します。
ST_DumpSegments — ジオメトリ内の辺の行であるgeometry_dump行の集合を返します。
ST_DumpRings — ポリゴンのリングごとのgeometry_dump行の集合を返します。
ST_EndPoint — LINESTRINGまたはCIRCULARLINESTRINGの終端のポイントを返します。
ST_Envelope — ジオメトリのバウンディングボックスを表現するジオメトリを返します。
ST_ExteriorRing — ポリゴンの外環を表現するラインストリングを返します。
ST_GeometryN — ジオメトリコレクションの要素を一つ返します。
ST_GeometryType — ジオメトリのSQL-MM型を文字列で返します。
ST_HasArc — ジオメトリに円弧が含まれているかどうかテストします。
ST_InteriorRingN — ポリゴンのN番目の内環 (穴)を返します。
ST_IsClosed — ラインストリングの始点と終点が一致しているかをテストします。多面体サーフェスについては閉じているか (立体であるか)をテストします。
ST_IsCollection — ジオメトリのタイプがジオメトリコレクションかをテストします。
ST_IsEmpty — ジオメトリが空かをテストします。
ST_IsPolygonCCW — ポリゴンが反時計回りの外環を持っていて、時計回りの内環を持っているかをテストします。
ST_IsPolygonCW — ポリゴンが時計回りの外環を持っていて、反時計回りの内環を持っているかをテストします。
ST_IsRing — ラインストリングが閉じていてかつ単純であるかをテストします。
ST_IsSimple — ジオメトリが自己インタセクトまたは自己接触となるポイントが無いかをテストします。
ST_M — ポイントのM値を返します。
ST_MemSize — ジオメトリが取るメモリ空間の合計を返します。
ST_NDims — ST_Geometry値の座標次元を返します。
ST_NPoints — ジオメトリのポイント (頂点)の数を返します。
ST_NRings — ポリゴンジオメトリのリング数を返します。
ST_NumGeometries — ジオメトリコレクションの要素数を返します。
ST_NumInteriorRings — ポリゴンの内環 (穴)の数を返します。
ST_NumInteriorRing — ポリゴンの内環 (穴)の数を返します。ST_NumInteriorRingsの別名です。
ST_NumPatches — 多面体サーフェスのフェイス数を返します。多面体でないジオメトリの場合にはNULLを返します。
ST_NumPoints — ラインストリングまたは曲線ストリングのポイント数を返します。
ST_PatchN — 多面体サーフェスのN番目のジオメトリ (フェイス)を返します。
ST_PointN — ジオメトリの最初のラインストリングまたは曲線ストリングのN番目のポイントを返します。
ST_Points — ジオメトリの全ての座標を含むマルチポイントを返します。
ST_StartPoint — ラインストリングの始点を返します。
ST_Summary — ジオメトリについての要約文を返します。
ST_X — ポイントのX値を返します。
ST_Y — ポイントのY値を返します。
ST_Z — ポイントのZ値を返します。
ST_Zmflag — ジオメトリのZM座標次元を示す符号を返します。

Name

GeometryType — ジオメトリのタイプを文字列で返します。

Synopsis

text GeometryType(geometry geomA);

説明

ジオメトリ型を'LINESTRING', 'POLYGON', 'MULTIPOINT'などの文字列で返します。

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

[Note]

この関数は、'POINTM'等が返るので、ジオメトリがM値を持っているかどうかも示します。

Enhanced: 2.0.0 多面体サーフェス対応、三角対応、TIN対応が導入されました。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1.

This method supports Circular Strings and Curves

This function supports 3d and will not drop the z-index.

This function supports Polyhedral surfaces.

This function supports Triangles and Triangulated Irregular Network Surfaces (TIN).

SELECT GeometryType(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
 geometrytype
--------------
 LINESTRING
SELECT ST_GeometryType(ST_GeomFromEWKT('POLYHEDRALSURFACE( ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),
                ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),
                ((1 1 0, 1 1 1, 1 0 1, 1 0 0, 1 1 0)),
                ((0 1 0, 0 1 1, 1 1 1, 1 1 0, 0 1 0)), ((0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1)) )'));
                        -- 結果 --
                        POLYHEDRALSURFACE
                        
SELECT GeometryType(geom) as result
  FROM
    (SELECT
       ST_GeomFromEWKT('TIN (((
                0 0 0,
                0 0 1,
                0 1 0,
                0 0 0
            )), ((
                0 0 0,
                0 1 0,
                1 1 0,
                0 0 0
            ))
            )')  AS geom
    ) AS g;
 result
--------
 TIN    

関連情報

ST_GeometryType


Name

ST_Boundary — ジオメトリの境界を返します。

Synopsis

geometry ST_Boundary(geometry geomA);

説明

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

GEOSモジュールで実現しています。

[Note]

2.0.0より前の版では、この関数はGEOMETRYCOLLECTION.を与えると例外を投げました。2.0.0以上では代わりにNULLが返ります (非対応入力)。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1. OGC SPEC s2.1.1.1

This method implements the SQL/MM specification. SQL-MM IEC 13249-3: 5.1.17

This function supports 3d and will not drop the z-index.

Enhanced: 2.1.0 三角対応が導入されました。

Changed: 3.2.0 TINに対応しました。GEOSを使いません。曲線を線形化しません。

境界ポイントを重ねたラインストリング

SELECT ST_Boundary(geom)
FROM (SELECT 'LINESTRING(100 150,50 60, 70 80, 160 170)'::geometry As geom) As f;
                                

-- ST_AsText 出力
MULTIPOINT((100 150),(160 170))

境界マルチラインストリングを重ねたポリゴンの穴

SELECT ST_Boundary(geom)
FROM (SELECT
'POLYGON (( 10 130, 50 190, 110 190, 140 150, 150 80, 100 10, 20 40, 10 130 ),
        ( 70 40, 100 50, 120 80, 80 110, 50 90, 70 40 ))'::geometry As geom) As f;
                                

-- ST_AsText 出力 --
MULTILINESTRING((10 130,50 190,110 190,140 150,150 80,100 10,20 40,10 130),
        (70 40,100 50,120 80,80 110,50 90,70 40))

SELECT ST_AsText(ST_Boundary(ST_GeomFromText('LINESTRING(1 1,0 0, -1 1)')));
st_astext
-----------
MULTIPOINT((1 1),(-1 1))

SELECT ST_AsText(ST_Boundary(ST_GeomFromText('POLYGON((1 1,0 0, -1 1, 1 1))')));
st_astext
----------
LINESTRING(1 1,0 0,-1 1,1 1)

-- 3次元ポリゴンの使用
SELECT ST_AsEWKT(ST_Boundary(ST_GeomFromEWKT('POLYGON((1 1 1,0 0 1, -1 1 1, 1 1 1))')));

st_asewkt
-----------------------------------
LINESTRING(1 1 1,0 0 1,-1 1 1,1 1 1)

-- 3次元ラインストリングの使用
SELECT ST_AsEWKT(ST_Boundary(ST_GeomFromEWKT('MULTILINESTRING((1 1 1,0 0 0.5, -1 1 1),(1 1 0.5,0 0 0.5, -1 1 0.5, 1 1 0.5) )')));

st_asewkt
----------
MULTIPOINT((-1 1 1),(1 1 0.75))

Name

ST_BoundingDiagonal — ジオメトリのバウンディングボックスの対角線を返します。

Synopsis

geometry ST_BoundingDiagonal(geometry geom, boolean fits=false);

説明

与えられたジオメトリのバウンディングボックスの対角線をラインストリングで返します。最小値のポイントを始点とし、最大値のポイントを終点とする、二つのポイントからなるラインストリングになります。入力ジオメトリが空の場合には、対角線はLINESTRING EMPTYとなります。

fitsパラメータは、最良適合が必要かどうかを指定するものです。FALSEの場合には、幾分大きめなバウンディングボックスの対角線を受け付けることができます (多数の頂点からなるジオメトリの取得が早くなります)。いずれにしても返された対角線のバウンディングボックスは常に入力ジオメトリを含みます。

返されるラインストリングは常に、入力ジオメトリのSRIDと次元 (ZとMがあること)を維持します。

[Note]

縮退した (入力の頂点が一つ)場合、返されるラインストリングは形式的に不正です (内部が無い)。トポロジ的には妥当です。

Availability: 2.2.0

This function supports 3d and will not drop the z-index.

This function supports M coordinates.

-- ポイントまわりのバッファのXの最小値を得ます
SELECT ST_X(ST_StartPoint(ST_BoundingDiagonal(
  ST_Buffer(ST_Point(0,0),10)
)));
 st_x
------
  -10
                

Name

ST_CoordDim — ジオメトリの座標次元を返します。

Synopsis

integer ST_CoordDim(geometry geomA);

説明

ST_Geometry値の座標次元を返します。

この関数はST_NDimsのMM対応の別名です。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1.

This method implements the SQL/MM specification. SQL-MM 3: 5.1.3

This method supports Circular Strings and Curves

This function supports 3d and will not drop the z-index.

This function supports Polyhedral surfaces.

This function supports Triangles and Triangulated Irregular Network Surfaces (TIN).

SELECT ST_CoordDim('CIRCULARSTRING(1 2 3, 1 3 4, 5 6 7, 8 9 10, 11 12 13)');
                        -- 結果 --
                                3

                                SELECT ST_CoordDim(ST_Point(1,2));
                        -- 結果 --
                                2

                

関連情報

ST_NDims


Name

ST_Dimension — ST_Geometry値の座標次元を返します。

Synopsis

integer ST_Dimension(geometry g);

説明

ジオメトリの固有次元を返します。ジオメトリは座標次元以下でなければなりません。OGC SPEC s2.1.1.1 - 0ならPOINT、1ならLINESTRING、2ならPOLYGONで、GEOMETRYCOLLECTIONの場合は要素ごとの次元の最大値です。不明なジオメトリ (空のGEOMETRYCOLLECTION等)の場合はNULLが返ります。

This method implements the SQL/MM specification. SQL-MM 3: 5.1.2

Enhanced: 2.0.0 多面体サーフェス対応とTIN対応が導入されました。空ジオメトリを与えた場合に例外を投げなくなりました。

[Note]

2.0.0より前では、空ジオメトリを与えると例外を投げていました。

This function supports Polyhedral surfaces.

This function supports Triangles and Triangulated Irregular Network Surfaces (TIN).

SELECT ST_Dimension('GEOMETRYCOLLECTION(LINESTRING(1 1,0 0),POINT(0 0))');
ST_Dimension
-----------
1

関連情報

ST_NDims


Name

ST_Dump — ジオメトリの要素となるgeometry_dump行の集合を返します。

Synopsis

geometry_dump[] ST_Dump(geometry g1);

説明

ジオメトリ要素を抽出する、集合を返す関数 (SRF=Set-Returning Function)です。ジオメトリ (geomフィールド)と整数配列 (pathフィールド)からなるgeometry_dump行の集合を返します。

非マルチ系ジオメトリタイプ (POINT,LINESTRING,POLYGON)では、path配列が空でgeomが入力ジオメトリと同じになる単一の行が返ります。コレクションまたはマルチ系ジオメトリでは、個々の要素と、コレクションの要素位置を示すpathとからなる行を返します。

ST_Dumpはジオメトリを展開するのに使います。ST_Collect/GROUP BYの逆で、この関数の中で新行を作成します。たとえば、MULTIPOLYGONをPOLYGONに展開するために使います。

Enhanced: 2.0.0 多面体サーフェス対応、三角対応、TIN対応が導入されました。

Availability: PostGIS 1.0.0RC1。PostgreSQL 7.3以上が必要です。

[Note]

1.3.4より前では、曲線を含むジオメトリで使用すると、この関数はクラッシュします。これは1.3.4以上で訂正されています。

This method supports Circular Strings and Curves

This function supports Polyhedral surfaces.

This function supports Triangles and Triangulated Irregular Network Surfaces (TIN).

This function supports 3d and will not drop the z-index.

標準的な例

SELECT sometable.field1, sometable.field1,
      (ST_Dump(sometable.geom)).geom AS geom
FROM sometable;

-- 複合曲線をラインストリングと曲線ストリングに分解
SELECT ST_AsEWKT(a.geom), ST_HasArc(a.geom)
  FROM ( SELECT (ST_Dump(p_geom)).geom AS geom
         FROM (SELECT ST_GeomFromEWKT('COMPOUNDCURVE(CIRCULARSTRING(0 0, 1 1, 1 0),(1 0, 0 1))') AS p_geom) AS b
        ) AS a;
          st_asewkt          | st_hasarc
-----------------------------+----------
 CIRCULARSTRING(0 0,1 1,1 0) | t
 LINESTRING(1 0,0 1)         | f
(2 rows)

多面体サーフェス、TIN、三角形の例

-- 多面体サーフェスの例
-- 多面体サーフェスをフェイスに分解します。
SELECT (a.p_geom).path[1] As path, ST_AsEWKT((a.p_geom).geom) As geom_ewkt
  FROM (SELECT ST_Dump(ST_GeomFromEWKT('POLYHEDRALSURFACE(
((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),
((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),  ((1 1 0, 1 1 1, 1 0 1, 1 0 0, 1 1 0)),
((0 1 0, 0 1 1, 1 1 1, 1 1 0, 0 1 0)),  ((0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1))
)') ) AS p_geom )  AS a;

 path |                geom_ewkt
------+------------------------------------------
    1 | POLYGON((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0))
    2 | POLYGON((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0))
    3 | POLYGON((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0))
    4 | POLYGON((1 1 0,1 1 1,1 0 1,1 0 0,1 1 0))
    5 | POLYGON((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0))
    6 | POLYGON((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1))
-- TIN --
SELECT (g.gdump).path, ST_AsEWKT((g.gdump).geom) as wkt
  FROM
    (SELECT
       ST_Dump( ST_GeomFromEWKT('TIN (((
                0 0 0,
                0 0 1,
                0 1 0,
                0 0 0
            )), ((
                0 0 0,
                0 1 0,
                1 1 0,
                0 0 0
            ))
            )') ) AS gdump
    ) AS g;
-- result --
 path |                 wkt
------+-------------------------------------
 {1}  | TRIANGLE((0 0 0,0 0 1,0 1 0,0 0 0))
 {2}  | TRIANGLE((0 0 0,0 1 0,1 1 0,0 0 0))

Name

ST_DumpPoints — ジオメトリ内の座標の行であるgeometry_dump行の集合を返します。

Synopsis

geometry_dump[] ST_DumpPoints(geometry geom);

説明

ジオメトリの座標 (頂点)を抽出する、集合を返す関数 (SRF=Set-Returning Function)です。ジオメトリ (geomフィールド)と整数配列 (pathフィールド)からなるgeometry_dump行の集合を返します。

  • geomフィールドには、与えられたジオメトリの座標を表現するPOINTが入ります。

  • pathフィールド (integer[])は、与えられたジオメトリの要素内の座標位置を列挙するインデックスです。インデックスは1始まりです。たとえば、LINESTRINGに対しては、LINESTRINGn番目の座標をiとすると、{i}となります。POLYGONに対しては、iを環番号 (1が外環、続いて内環)、jを環の座標位置とすると、{i,j}となります。

座業を含む単一ジオメトリを取得するにはST_Pointsを使います。

Enhanced: 2.1.0 速度向上しました。C言語で実装しなおしました。

Enhanced: 2.0.0 多面体サーフェス対応、三角対応、TIN対応が導入されました。

Availability: 1.5.0

This method supports Circular Strings and Curves

This function supports Polyhedral surfaces.

This function supports Triangles and Triangulated Irregular Network Surfaces (TIN).

This function supports 3d and will not drop the z-index.

ラインストリングのテーブルのノードへの古典的な分割

SELECT edge_id, (dp).path[1] As index, ST_AsText((dp).geom) As wktnode
FROM (SELECT 1 As edge_id
        , ST_DumpPoints(ST_GeomFromText('LINESTRING(1 2, 3 4, 10 10)')) AS dp
     UNION ALL
     SELECT 2 As edge_id
        , ST_DumpPoints(ST_GeomFromText('LINESTRING(3 5, 5 6, 9 10)')) AS dp
   ) As foo;
 edge_id | index |    wktnode
---------+-------+--------------
       1 |     1 | POINT(1 2)
       1 |     2 | POINT(3 4)
       1 |     3 | POINT(10 10)
       2 |     1 | POINT(3 5)
       2 |     2 | POINT(5 6)
       2 |     3 | POINT(9 10)

標準的な例

SELECT path, ST_AsText(geom)
FROM (
  SELECT (ST_DumpPoints(g.geom)).*
  FROM
    (SELECT
       'GEOMETRYCOLLECTION(
          POINT ( 0 1 ),
          LINESTRING ( 0 3, 3 4 ),
          POLYGON (( 2 0, 2 3, 0 2, 2 0 )),
          POLYGON (( 3 0, 3 3, 6 3, 6 0, 3 0 ),
                   ( 5 1, 4 2, 5 2, 5 1 )),
          MULTIPOLYGON (
                  (( 0 5, 0 8, 4 8, 4 5, 0 5 ),
                   ( 1 6, 3 6, 2 7, 1 6 )),
                  (( 5 4, 5 8, 6 7, 5 4 ))
          )
        )'::geometry AS geom
    ) AS g
  ) j;

   path    | st_astext
-----------+------------
 {1,1}     | POINT(0 1)
 {2,1}     | POINT(0 3)
 {2,2}     | POINT(3 4)
 {3,1,1}   | POINT(2 0)
 {3,1,2}   | POINT(2 3)
 {3,1,3}   | POINT(0 2)
 {3,1,4}   | POINT(2 0)
 {4,1,1}   | POINT(3 0)
 {4,1,2}   | POINT(3 3)
 {4,1,3}   | POINT(6 3)
 {4,1,4}   | POINT(6 0)
 {4,1,5}   | POINT(3 0)
 {4,2,1}   | POINT(5 1)
 {4,2,2}   | POINT(4 2)
 {4,2,3}   | POINT(5 2)
 {4,2,4}   | POINT(5 1)
 {5,1,1,1} | POINT(0 5)
 {5,1,1,2} | POINT(0 8)
 {5,1,1,3} | POINT(4 8)
 {5,1,1,4} | POINT(4 5)
 {5,1,1,5} | POINT(0 5)
 {5,1,2,1} | POINT(1 6)
 {5,1,2,2} | POINT(3 6)
 {5,1,2,3} | POINT(2 7)
 {5,1,2,4} | POINT(1 6)
 {5,2,1,1} | POINT(5 4)
 {5,2,1,2} | POINT(5 8)
 {5,2,1,3} | POINT(6 7)
 {5,2,1,4} | POINT(5 4)
(29 rows)

多面体サーフェス、TIN、三角形の例

-- 多面体サーフェスの立方体 --
SELECT (g.gdump).path, ST_AsEWKT((g.gdump).geom) as wkt
  FROM
    (SELECT
       ST_DumpPoints(ST_GeomFromEWKT('POLYHEDRALSURFACE( ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),
((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),
((1 1 0, 1 1 1, 1 0 1, 1 0 0, 1 1 0)),
((0 1 0, 0 1 1, 1 1 1, 1 1 0, 0 1 0)), ((0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1)) )') ) AS gdump
    ) AS g;
-- 結果 --
  path   |     wkt
---------+--------------
 {1,1,1} | POINT(0 0 0)
 {1,1,2} | POINT(0 0 1)
 {1,1,3} | POINT(0 1 1)
 {1,1,4} | POINT(0 1 0)
 {1,1,5} | POINT(0 0 0)
 {2,1,1} | POINT(0 0 0)
 {2,1,2} | POINT(0 1 0)
 {2,1,3} | POINT(1 1 0)
 {2,1,4} | POINT(1 0 0)
 {2,1,5} | POINT(0 0 0)
 {3,1,1} | POINT(0 0 0)
 {3,1,2} | POINT(1 0 0)
 {3,1,3} | POINT(1 0 1)
 {3,1,4} | POINT(0 0 1)
 {3,1,5} | POINT(0 0 0)
 {4,1,1} | POINT(1 1 0)
 {4,1,2} | POINT(1 1 1)
 {4,1,3} | POINT(1 0 1)
 {4,1,4} | POINT(1 0 0)
 {4,1,5} | POINT(1 1 0)
 {5,1,1} | POINT(0 1 0)
 {5,1,2} | POINT(0 1 1)
 {5,1,3} | POINT(1 1 1)
 {5,1,4} | POINT(1 1 0)
 {5,1,5} | POINT(0 1 0)
 {6,1,1} | POINT(0 0 1)
 {6,1,2} | POINT(1 0 1)
 {6,1,3} | POINT(1 1 1)
 {6,1,4} | POINT(0 1 1)
 {6,1,5} | POINT(0 0 1)
(30 rows)
-- Triangle --
SELECT (g.gdump).path, ST_AsText((g.gdump).geom) as wkt
  FROM
    (SELECT
       ST_DumpPoints( ST_GeomFromEWKT('TRIANGLE ((
                0 0,
                0 9,
                9 0,
                0 0
            ))') ) AS gdump
    ) AS g;
-- 結果 --
 path |    wkt
------+------------
 {1}  | POINT(0 0)
 {2}  | POINT(0 9)
 {3}  | POINT(9 0)
 {4}  | POINT(0 0)
-- TIN --
SELECT (g.gdump).path, ST_AsEWKT((g.gdump).geom) as wkt
  FROM
    (SELECT
       ST_DumpPoints( ST_GeomFromEWKT('TIN (((
                0 0 0,
                0 0 1,
                0 1 0,
                0 0 0
            )), ((
                0 0 0,
                0 1 0,
                1 1 0,
                0 0 0
            ))
            )') ) AS gdump
    ) AS g;
-- 結果 --
  path   |     wkt
---------+--------------
 {1,1,1} | POINT(0 0 0)
 {1,1,2} | POINT(0 0 1)
 {1,1,3} | POINT(0 1 0)
 {1,1,4} | POINT(0 0 0)
 {2,1,1} | POINT(0 0 0)
 {2,1,2} | POINT(0 1 0)
 {2,1,3} | POINT(1 1 0)
 {2,1,4} | POINT(0 0 0)
(8 rows)

Name

ST_DumpSegments — ジオメトリ内の辺の行であるgeometry_dump行の集合を返します。

Synopsis

geometry_dump[] ST_DumpSegments(geometry geom);

説明

ジオメトリの辺を抽出する、集合を返す関数 (SRF=Set-Returning Function)です。ジオメトリ (geomフィールド)と整数配列 (pathフィールド)からなるgeometry_dump行の集合を返します。

  • geomフィールドには、与えられたジオメトリの辺を表現するLINESTRINGが入ります。

  • pathフィールド (integer[])は、与えられたジオメトリの要素内の辺の始点位置を列挙するインデックスです。インデックスは1始まりです。たとえば、LINESTRINGに対しては、LINESTRINGn番目の辺をiとすると、{i}となります。POLYGONに対しては、iを環番号 (1が外環、続いて内環)、jを環の辺の始点位置とすると、{i,j}となります。

Availability: 3.2.0

This function supports Triangles and Triangulated Irregular Network Surfaces (TIN).

This function supports 3d and will not drop the z-index.

標準的な例

SELECT path, ST_AsText(geom)
FROM (
    SELECT (ST_DumpSegments(g.geom)).*
    FROM (SELECT 'GEOMETRYCOLLECTION(
    LINESTRING(1 1, 3 3, 4 4),
    POLYGON((5 5, 6 6, 7 7, 5 5))
)'::geometry AS geom
        ) AS g
) j;

  path   │      st_astext
---------------------------------
 {1,1}   │ LINESTRING(1 1,3 3)
 {1,2}   │ LINESTRING(3 3,4 4)
 {2,1,1} │ LINESTRING(5 5,6 6)
 {2,1,2} │ LINESTRING(6 6,7 7)
 {2,1,3} │ LINESTRING(7 7,5 5)
(5 rows)

TIN、三角形の例

-- 三角形 --
SELECT path, ST_AsText(geom)
FROM (
    SELECT (ST_DumpSegments(g.geom)).*
    FROM (SELECT 'TRIANGLE((
        0 0,
        0 9,
        9 0,
        0 0
    ))'::geometry AS geom
        ) AS g
) j;

 path  │      st_astext
 ---------------------------------
 {1,1} │ LINESTRING(0 0,0 9)
 {1,2} │ LINESTRING(0 9,9 0)
 {1,3} │ LINESTRING(9 0,0 0)
(3 rows)
-- TIN --
SELECT path, ST_AsEWKT(geom)
FROM (
    SELECT (ST_DumpSegments(g.geom)).*
    FROM (SELECT 'TIN(((
        0 0 0,
        0 0 1,
        0 1 0,
        0 0 0
    )), ((
        0 0 0,
        0 1 0,
        1 1 0,
        0 0 0
    ))
    )'::geometry AS geom
        ) AS g
) j;

  path   │        st_asewkt
  ---------------------------------
 {1,1,1} │ LINESTRING(0 0 0,0 0 1)
 {1,1,2} │ LINESTRING(0 0 1,0 1 0)
 {1,1,3} │ LINESTRING(0 1 0,0 0 0)
 {2,1,1} │ LINESTRING(0 0 0,0 1 0)
 {2,1,2} │ LINESTRING(0 1 0,1 1 0)
 {2,1,3} │ LINESTRING(1 1 0,0 0 0)
(6 rows)

Name

ST_DumpRings — ポリゴンのリングごとのgeometry_dump行の集合を返します。

Synopsis

geometry_dump[] ST_DumpRings(geometry a_polygon);

説明

ジオメトリ要素を抽出する、集合を返す関数 (SRF=Set-Returning Function)です。ジオメトリ (geomフィールド)と整数配列 (pathフィールド)からなるgeometry_dump行の集合を返します。

ジオメトリ要素を抽出する、集合を返す関数 (SRF=Set-Returning Function)です。ジオメトリ (geomフィールド)と整数配列 (pathフィールド)からなるgeometry_dump行の集合を返します。

[Note]

POLYGONジオメトリでのみ動作します。MULTIPOLYGONでは動作しません。

Availability: PostGIS 1.1.3 PostgreSQL 7.3以上が必要です。

This function supports 3d and will not drop the z-index.

クエリの一般的な形式。

SELECT polyTable.field1, polyTable.field1,
          (ST_DumpRings(polyTable.geom)).geom As geom
FROM polyTable;

単一の穴を持つポリゴン

SELECT path, ST_AsEWKT(geom) As geom
        FROM ST_DumpRings(
                ST_GeomFromEWKT('POLYGON((-8149064 5133092 1,-8149064 5132986 1,-8148996 5132839 1,-8148972 5132767 1,-8148958 5132508 1,-8148941 5132466 1,-8148924 5132394 1,
                -8148903 5132210 1,-8148930 5131967 1,-8148992 5131978 1,-8149237 5132093 1,-8149404 5132211 1,-8149647 5132310 1,-8149757 5132394 1,
                -8150305 5132788 1,-8149064 5133092 1),
                (-8149362 5132394 1,-8149446 5132501 1,-8149548 5132597 1,-8149695 5132675 1,-8149362 5132394 1))')
                )  as foo;
 path |                                            geom
----------------------------------------------------------------------------------------------------------------
  {0} | POLYGON((-8149064 5133092 1,-8149064 5132986 1,-8148996 5132839 1,-8148972 5132767 1,-8148958 5132508 1,
          |          -8148941 5132466 1,-8148924 5132394 1,
          |          -8148903 5132210 1,-8148930 5131967 1,
          |          -8148992 5131978 1,-8149237 5132093 1,
          |          -8149404 5132211 1,-8149647 5132310 1,-8149757 5132394 1,-8150305 5132788 1,-8149064 5133092 1))
  {1} | POLYGON((-8149362 5132394 1,-8149446 5132501 1,
          |          -8149548 5132597 1,-8149695 5132675 1,-8149362 5132394 1))

Name

ST_EndPoint — LINESTRINGまたはCIRCULARLINESTRINGの終端のポイントを返します。

Synopsis

geometry ST_EndPoint(geometry g);

説明

LINESTRINGまたはCIRCULARLINESTRINGジオメトリの、最後のポイントをPOINTで返します。入力パラメータがLINESTRINGでもCIRCULARLINESTRINGでもない場合には、NULLを返します。

This method implements the SQL/MM specification. SQL-MM 3: 7.1.4

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

[Note]

Changed: 2.0.0 一つのジオメトリマルチラインストリングで動作しなくなりました。PostGIS の古いバージョンでは、この関数は一つのマルチラインストリングで動作し、終端ポイントを返します。2.0.0では、他のマルチラインストリングと同様にNULLを返します。古い動作は文書化されていない機能でしたが、データをLINESTRINGとして格納していると思われるユーザーは、2.0.0 でNULLが返されることを経験するかも知れません。

ラインストリングの終端ポイント

postgis=# SELECT ST_AsText(ST_EndPoint('LINESTRING(1 1, 2 2, 3 3)'::geometry));
 st_astext
------------
 POINT(3 3)

ラインストリング以外の終端ポイントはNULL

SELECT ST_EndPoint('POINT(1 1)'::geometry) IS NULL AS is_null;
  is_null
----------
 t

3次元ラインストリングの終端ポイント

-- 3次元終端ポイント
SELECT ST_AsEWKT(ST_EndPoint('LINESTRING(1 1 2, 1 2 3, 0 0 5)'));
  st_asewkt
--------------
 POINT(0 0 5)

CIRCULARSTRINGの終端ポイント

SELECT ST_AsText(ST_EndPoint('CIRCULARSTRING(5 2,-3 1.999999, -2 1, -4 2, 6 3)'::geometry));
 st_astext
------------
 POINT(6 3)

Name

ST_Envelope — ジオメトリのバウンディングボックスを表現するジオメトリを返します。

Synopsis

geometry ST_Envelope(geometry g1);

説明

与えられたジオメトリの倍精度浮動小数点数 (float8)の最小バウンディングボックスをジオメトリで返します。ポリゴンはバウンディングボックスの角のポイントで定義されます ((MINX, MINY), (MINX, MAXY), (MAXX, MAXY), (MAXX, MINY), (MINX, MINY))。(PostGISはZMIN/ZMAXも追加します).

縮退する場合 (縦のライン、ポイント)はPOLYGONより低い次元のジオメトリ、すなわちPOINTまたはLINESTRINGを返します。

Availability: 1.5.0 挙動が変更され出力がfloat4からfloat8になりました。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1. s2.1.1.1

This method implements the SQL/MM specification. SQL-MM 3: 5.1.19

SELECT ST_AsText(ST_Envelope('POINT(1 3)'::geometry));
 st_astext
------------
 POINT(1 3)
(1 row)


SELECT ST_AsText(ST_Envelope('LINESTRING(0 0, 1 3)'::geometry));
                   st_astext
--------------------------------
 POLYGON((0 0,0 3,1 3,1 0,0 0))
(1 row)


SELECT ST_AsText(ST_Envelope('POLYGON((0 0, 0 1, 1.0000001 1, 1.0000001 0, 0 0))'::geometry));
                                                  st_astext
--------------------------------------------------------------
 POLYGON((0 0,0 1,1.00000011920929 1,1.00000011920929 0,0 0))
(1 row)
SELECT ST_AsText(ST_Envelope('POLYGON((0 0, 0 1, 1.0000000001 1, 1.0000000001 0, 0 0))'::geometry));
                                                  st_astext
--------------------------------------------------------------
 POLYGON((0 0,0 1,1.00000011920929 1,1.00000011920929 0,0 0))
(1 row)

SELECT Box3D(geom), Box2D(geom), ST_AsText(ST_Envelope(geom)) As envelopewkt
        FROM (SELECT 'POLYGON((0 0, 0 1000012333334.34545678, 1.0000001 1, 1.0000001 0, 0 0))'::geometry As geom) As foo;


        

ポイントとラインストリングの最小バウンディングボックス

SELECT ST_AsText(ST_Envelope(
                ST_Collect(
                        ST_GeomFromText('LINESTRING(55 75,125 150)'),
                                ST_Point(20, 80))
                                )) As wktenv;
wktenv
-----------
POLYGON((20 75,20 150,125 150,125 75,20 75))

Name

ST_ExteriorRing — ポリゴンの外環を表現するラインストリングを返します。

Synopsis

geometry ST_ExteriorRing(geometry a_polygon);

説明

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

[Note]

この関数はマルチポリゴンでは動作しません。マルチポリゴンに対してはST_GeometryNまたはST_Dumpを併用して下さい。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1. 2.1.5.1

This method implements the SQL/MM specification. SQL-MM 3: 8.2.3, 8.3.3

This function supports 3d and will not drop the z-index.

-- ポリゴンのテーブルを持っているとします
SELECT gid, ST_ExteriorRing(geom) AS ering
FROM sometable;

-- マルチポリゴンのテーブルを持っていて、
-- それぞれのポリゴンの外環からなるマルチラインストリングを返させたいとします。
SELECT gid, ST_Collect(ST_ExteriorRing(geom)) AS erings
        FROM (SELECT gid, (ST_Dump(geom)).geom As geom
                        FROM sometable) As foo
GROUP BY gid;

-- 3次元の例
SELECT ST_AsEWKT(
        ST_ExteriorRing(
        ST_GeomFromEWKT('POLYGON((0 0 1, 1 1 1, 1 2 1, 1 1 1, 0 0 1))')
        )
);

st_asewkt
---------
LINESTRING(0 0 1,1 1 1,1 2 1,1 1 1,0 0 1)

Name

ST_GeometryN — ジオメトリコレクションの要素を一つ返します。

Synopsis

geometry ST_GeometryN(geometry geomA, integer n);

説明

GEOMETRYCOLLECTION, MULTIPOINT, MULTILINESTRING, MULTICURVE, MULTIPOLYGON, POLYHEDRALSURFACEの入力ジオメトリの、1始まりでN番目の要素を返します。他の場合にはNULLを返します。

[Note]

OGC仕様のため0.8.0版からインデクスを1始まりにしています。これより前の版では0始まりになっています。

[Note]

ジオメトリの全ての要素を抽出するにはST_Dumpの方が効率的ですし、単一ジオメトリでも動作します。

Enhanced: 2.0.0 多面体サーフェス対応、三角対応、TIN対応が導入されました。

Changed: 2.0.0 以前の版では非マルチのジオメトリではNULLが返りました。ST_GeometryN(..,1)の場合にはジオメトリを返すよう変更されました。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1.

This method implements the SQL/MM specification. SQL-MM 3: 9.1.5

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

This function supports Polyhedral surfaces.

This function supports Triangles and Triangulated Irregular Network Surfaces (TIN).

標準的な例

-- 3次元マルチポイントから部分集合を抽出
SELECT n, ST_AsEWKT(ST_GeometryN(the_geom, n)) As geomewkt
FROM (
VALUES (ST_GeomFromEWKT('MULTIPOINT(1 2 7, 3 4 7, 5 6 7, 8 9 10)') ),
( ST_GeomFromEWKT('MULTICURVE(CIRCULARSTRING(2.5 2.5,4.5 2.5, 3.5 3.5), (10 11, 12 11))') )
        )As foo(the_geom)
        CROSS JOIN generate_series(1,100) n
WHERE n <= ST_NumGeometries(the_geom);

 n |               geomewkt
---+-----------------------------------------
 1 | POINT(1 2 7)
 2 | POINT(3 4 7)
 3 | POINT(5 6 7)
 4 | POINT(8 9 10)
 1 | CIRCULARSTRING(2.5 2.5,4.5 2.5,3.5 3.5)
 2 | LINESTRING(10 11,12 11)


-- 全てのジオメトリを抽出(idを付けたい場合に便利です)
SELECT gid, n, ST_GeometryN(the_geom, n)
FROM sometable CROSS JOIN generate_series(1,100) n
WHERE n <= ST_NumGeometries(the_geom);

多面体サーフェス、TIN、三角形の例

-- 多面体サーフェスの例
-- 多面体サーフェスをフェイスに分解します。
SELECT ST_AsEWKT(ST_GeometryN(p_geom,3)) As geom_ewkt
  FROM (SELECT ST_GeomFromEWKT('POLYHEDRALSURFACE(
((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),
((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),
((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),
((1 1 0, 1 1 1, 1 0 1, 1 0 0, 1 1 0)),
((0 1 0, 0 1 1, 1 1 1, 1 1 0, 0 1 0)),
((0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1))
)')  AS p_geom )  AS a;

                geom_ewkt
------------------------------------------
 POLYGON((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0))
-- TIN --
SELECT ST_AsEWKT(ST_GeometryN(geom,2)) as wkt
  FROM
    (SELECT
       ST_GeomFromEWKT('TIN (((
                0 0 0,
                0 0 1,
                0 1 0,
                0 0 0
            )), ((
                0 0 0,
                0 1 0,
                1 1 0,
                0 0 0
            ))
            )')  AS geom
    ) AS g;
-- 結果--
                 wkt
-------------------------------------
 TRIANGLE((0 0 0,0 1 0,1 1 0,0 0 0))

Name

ST_GeometryType — ジオメトリのSQL-MM型を文字列で返します。

Synopsis

text ST_GeometryType(geometry g1);

説明

ジオメトリ型を'ST_LineString', 'ST_Polygon', 'ST_MultiPolygon'等の文字列で返します。この関数はGeometryType(geometry)とは異なり、先頭に'ST'が付き、M値を持っているかを示しません。

Enhanced: 2.0.0 多面体サーフェス対応が導入されました。

This method implements the SQL/MM specification. SQL-MM 3: 5.1.4

This function supports 3d and will not drop the z-index.

This function supports Polyhedral surfaces.

SELECT ST_GeometryType(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
                        -- 結果
                        ST_LineString
SELECT ST_GeometryType(ST_GeomFromEWKT('POLYHEDRALSURFACE( ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),
                ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),
                ((1 1 0, 1 1 1, 1 0 1, 1 0 0, 1 1 0)),
                ((0 1 0, 0 1 1, 1 1 1, 1 1 0, 0 1 0)), ((0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1)) )'));
                        --結果 --
                        ST_PolyhedralSurface
SELECT ST_GeometryType(ST_GeomFromEWKT('POLYHEDRALSURFACE( ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),
                ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),
                ((1 1 0, 1 1 1, 1 0 1, 1 0 0, 1 1 0)),
                ((0 1 0, 0 1 1, 1 1 1, 1 1 0, 0 1 0)), ((0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1)) )'));
                        --結果 --
                        ST_PolyhedralSurface
SELECT ST_GeometryType(geom) as result
  FROM
    (SELECT
       ST_GeomFromEWKT('TIN (((
                0 0 0,
                0 0 1,
                0 1 0,
                0 0 0
            )), ((
                0 0 0,
                0 1 0,
                1 1 0,
                0 0 0
            ))
            )')  AS geom
    ) AS g;
 result
--------
 ST_Tin    

関連情報

GeometryType


Name

ST_HasArc — ジオメトリに円弧が含まれているかどうかテストします。

Synopsis

boolean ST_HasArc(geometry geomA);

説明

ジオメトリまたはジオメトリコレクションに曲線ラインストリングが含まれている場合にTRUEを返します。

Availability: 1.2.3?

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

SELECT ST_HasArc(ST_Collect('LINESTRING(1 2, 3 4, 5 6)', 'CIRCULARSTRING(1 1, 2 3, 4 5, 6 7, 5 6)'));
                st_hasarc
                --------
                t
                

Name

ST_InteriorRingN — ポリゴンのN番目の内環 (穴)を返します。

Synopsis

geometry ST_InteriorRingN(geometry a_polygon, integer n);

説明

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

[Note]

この関数はマルチポリゴンでは動作しません。マルチポリゴンに対してはST_GeometryNまたはST_Dumpを併用して下さい。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1.

This method implements the SQL/MM specification. SQL-MM 3: 8.2.6, 8.3.5

This function supports 3d and will not drop the z-index.

SELECT ST_AsText(ST_InteriorRingN(geom, 1)) As geom
FROM (SELECT ST_BuildArea(
                ST_Collect(ST_Buffer(ST_Point(1,2), 20,3),
                        ST_Buffer(ST_Point(1, 2), 10,3))) As geom
                )  as foo;
                

Name

ST_IsClosed — ラインストリングの始点と終点が一致しているかをテストします。多面体サーフェスについては閉じているか (立体であるか)をテストします。

Synopsis

boolean ST_IsClosed(geometry g);

説明

LINESTRINGの始点と終点が一致する場合にTRUEを返します。多面体サーフェスについては、サーフェスが面 (開いている)か立体 (閉じている)かをテストします。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1.

This method implements the SQL/MM specification. SQL-MM 3: 7.1.5, 9.3.3

[Note]

SQL-MMではST_IsClosed(NULL)は0を返しますが、PostGISではNULLを返します。

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

Enhanced: 2.0.0 多面体サーフェス対応が導入されました。

This function supports Polyhedral surfaces.

ラインストリングとポイントの例

postgis=# SELECT ST_IsClosed('LINESTRING(0 0, 1 1)'::geometry);
 st_isclosed
-------------
 f
(1 row)

postgis=# SELECT ST_IsClosed('LINESTRING(0 0, 0 1, 1 1, 0 0)'::geometry);
 st_isclosed
-------------
 t
(1 row)

postgis=# SELECT ST_IsClosed('MULTILINESTRING((0 0, 0 1, 1 1, 0 0),(0 0, 1 1))'::geometry);
 st_isclosed
-------------
 f
(1 row)

postgis=# SELECT ST_IsClosed('POINT(0 0)'::geometry);
 st_isclosed
-------------
 t
(1 row)

postgis=# SELECT ST_IsClosed('MULTIPOINT((0 0), (1 1))'::geometry);
 st_isclosed
-------------
 t
(1 row)

多面体サーフェスの例

-- 立方体 --
                SELECT ST_IsClosed(ST_GeomFromEWKT('POLYHEDRALSURFACE( ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),
                ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),
                ((1 1 0, 1 1 1, 1 0 1, 1 0 0, 1 1 0)),
                ((0 1 0, 0 1 1, 1 1 1, 1 1 0, 0 1 0)), ((0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1)) )'));

 st_isclosed
-------------
 t


 -- 立方体のようなものだけれども側面が一つ無いもの--
 SELECT ST_IsClosed(ST_GeomFromEWKT('POLYHEDRALSURFACE( ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),
                ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),
                ((1 1 0, 1 1 1, 1 0 1, 1 0 0, 1 1 0)),
                ((0 1 0, 0 1 1, 1 1 1, 1 1 0, 0 1 0)) )'));

 st_isclosed
-------------
 f

関連情報

ST_IsRing


Name

ST_IsCollection — ジオメトリのタイプがジオメトリコレクションかをテストします。

Synopsis

boolean ST_IsCollection(geometry g);

説明

ジオメトリのタイプがジオメトリコレクションである場合にTRUEを返します。コレクションは次の通りです。

  • ジオメトリコレクション

  • マルチポイント、マルチポリゴン、マルチラインストリング、マルチ曲線、マルチサーフェス

  • 複合曲線

[Note]

この関数はジオメトリのタイプを解析します。これは、空のコレクションである場合、または一つのエレメントを持つコレクションである場合にはTRUEを返すことを意味します。

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

postgis=# SELECT ST_IsCollection('LINESTRING(0 0, 1 1)'::geometry);
 st_iscollection
-------------
 f
(1 row)

postgis=# SELECT ST_IsCollection('MULTIPOINT EMPTY'::geometry);
 st_iscollection
-------------
 t
(1 row)

postgis=# SELECT ST_IsCollection('MULTIPOINT((0 0))'::geometry);
 st_iscollection
-------------
 t
(1 row)

postgis=# SELECT ST_IsCollection('MULTIPOINT((0 0), (42 42))'::geometry);
 st_iscollection
-------------
 t
(1 row)

postgis=# SELECT ST_IsCollection('GEOMETRYCOLLECTION(POINT(0 0))'::geometry);
 st_iscollection
-------------
 t
(1 row)

関連情報

ST_NumGeometries


Name

ST_IsEmpty — ジオメトリが空かをテストします。

Synopsis

boolean ST_IsEmpty(geometry geomA);

説明

ジオメトリが空ジオメトリの場合にtrueを返します。 trueの場合には、このジオメトリは、空のジオメトリコレクション、ポリゴン、ポイント等です。

[Note]

SQL-MMでは、ST_IsEmpty(NULL)は0を返しますが、PostGISではNULLを返します。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1. s2.1.1.1

This method implements the SQL/MM specification. SQL-MM 3: 5.1.7

This method supports Circular Strings and Curves

[Warning]

Changed: 2.0.0 以前の版のPostGISではST_GeomFromText('GEOMETRYCOLLECTION(EMPTY)')を許しました。PostGIS 2.0.0では、SQL/MM標準により準拠させるため、これは不正となります。

SELECT ST_IsEmpty(ST_GeomFromText('GEOMETRYCOLLECTION EMPTY'));
 st_isempty
------------
 t
(1 row)

 SELECT ST_IsEmpty(ST_GeomFromText('POLYGON EMPTY'));
 st_isempty
------------
 t
(1 row)

SELECT ST_IsEmpty(ST_GeomFromText('POLYGON((1 2, 3 4, 5 6, 1 2))'));

 st_isempty
------------
 f
(1 row)

 SELECT ST_IsEmpty(ST_GeomFromText('POLYGON((1 2, 3 4, 5 6, 1 2))')) = false;
 ?column?
----------
 t
(1 row)

 SELECT ST_IsEmpty(ST_GeomFromText('CIRCULARSTRING EMPTY'));
  st_isempty
------------
 t
(1 row)


                

Name

ST_IsPolygonCCW — ポリゴンが反時計回りの外環を持っていて、時計回りの内環を持っているかをテストします。

Synopsis

boolean ST_IsPolygonCCW ( geometry geom );

説明

入力ジオメトリの全てのポリゴン要素の外環については反時計回りで、全ての内環については時計回りである場合には、TRUEを返します。

ジオメトリがポリゴン要素を持っていない場合にはTRUEを返します。

[Note]

閉じたラインストリングはポリゴン要素とみなされません。単一の閉じたラインストリングを渡すと、右回り左回りにかかわらずTRUEが得られます。

[Note]

ポリゴン要素の内環が逆回りになっていない (すなわち外環と同じ方向で回る内環が1個以上ある)場合には、ST_IsPolygonCWとST_IsPolygonCCW の両方ともにFALSEを返します。

Availability: 2.4.0

This function supports 3d and will not drop the z-index.

This function supports M coordinates.


Name

ST_IsPolygonCW — ポリゴンが時計回りの外環を持っていて、反時計回りの内環を持っているかをテストします。

Synopsis

boolean ST_IsPolygonCW ( geometry geom );

説明

入力ジオメトリの全てのポリゴン要素の外環については時計回りで、全ての内環については反時計回りである場合には、TRUEを返します。

ジオメトリがポリゴン要素を持っていない場合にはTRUEを返します。

[Note]

閉じたラインストリングはポリゴン要素とみなされません。単一の閉じたラインストリングを渡すと、右回り左回りにかかわらずTRUEが得られます。

[Note]

ポリゴン要素の内環が逆回りになっていない (すなわち外環と同じ方向で回る内環が1個以上ある)場合には、ST_IsPolygonCWとST_IsPolygonCCW の両方ともにFALSEを返します。

Availability: 2.4.0

This function supports 3d and will not drop the z-index.

This function supports M coordinates.


Name

ST_IsRing — ラインストリングが閉じていてかつ単純であるかをテストします。

Synopsis

boolean ST_IsRing(geometry g);

説明

LINESTRINGST_IsClosed (ST_StartPoint(g) ~= ST_Endpoint(g))で、かつST_IsSimple (自己インタセクションが無い)場合にTRUEを返します。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1. 2.1.5.1

This method implements the SQL/MM specification. SQL-MM 3: 7.1.6

[Note]

SQL-MMでは、ST_IsRing(NULL)は0を返しますが、PostGISではNULLを返します。

SELECT ST_IsRing(geom), ST_IsClosed(geom), ST_IsSimple(geom)
FROM (SELECT 'LINESTRING(0 0, 0 1, 1 1, 1 0, 0 0)'::geometry AS geom) AS foo;
 st_isring | st_isclosed | st_issimple
-----------+-------------+-------------
 t         | t           | t
(1 row)

SELECT ST_IsRing(geom), ST_IsClosed(geom), ST_IsSimple(geom)
FROM (SELECT 'LINESTRING(0 0, 0 1, 1 0, 1 1, 0 0)'::geometry AS geom) AS foo;
 st_isring | st_isclosed | st_issimple
-----------+-------------+-------------
 f         | t           | f
(1 row)

Name

ST_IsSimple — ジオメトリが自己インタセクトまたは自己接触となるポイントが無いかをテストします。

Synopsis

boolean ST_IsSimple(geometry geomA);

説明

ジオメトリが自己インタセクションや自己接触のような異常な幾何学ポイントを持っていない場合にTRUEを返します。OGCのジオメトリ単純性と妥当性の定義に関する詳細情報については「ジオメトリのOpenGIS準拠を確実にする」をご覧ください。

[Note]

SQL-MMでは、ST_IsSimple(NULL)は0を返しますが、PostGISではNULLを返します。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1. s2.1.1.1

This method implements the SQL/MM specification. SQL-MM 3: 5.1.8

This function supports 3d and will not drop the z-index.

SELECT ST_IsSimple(ST_GeomFromText('POLYGON((1 2, 3 4, 5 6, 1 2))'));
 st_issimple
-------------
 t
(1 row)

 SELECT ST_IsSimple(ST_GeomFromText('LINESTRING(1 1,2 2,2 3.5,1 3,1 2,2 1)'));
 st_issimple
-------------
 f
(1 row)

関連情報

ST_IsValid


Name

ST_M — ポイントのM値を返します。

Synopsis

float ST_M(geometry a_point);

説明

ポイントのM座標値を返し、有効でないならNULLを返します。入力はポイントでなければなりません。

[Note]

これは (いまだに)OGC仕様に入っていませんが、ポイント座標抽出関数のリストを完全にするために挙げています。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1.

This method implements the SQL/MM specification.

This function supports 3d and will not drop the z-index.

SELECT ST_M(ST_GeomFromEWKT('POINT(1 2 3 4)'));
 st_m
------
        4
(1 row)

                

関連情報

ST_GeomFromEWKT, ST_X, ST_Y, ST_Z


Name

ST_MemSize — ジオメトリが取るメモリ空間の合計を返します。

Synopsis

integer ST_MemSize(geometry geomA);

説明

ジオメトリが取るメモリ空間の合計をバイト単位で返します。

この関数は、PostgreSQLビルトインデータベースオブジェクト管理関数のpg_column_size, pg_size_pretty, pg_relation_size, pg_total_relation_sizeを補完します。

[Note]

テーブルのバイト単位のサイズを与えるpg_relation_sizeはST_Mem_Sizeより小さいバイト数が返ります。これはpg_relation_sizeがTOAST化されたテーブルの寄与を追加せず、TOASTテーブルに格納された大きなジオメトリを加えないためです。

pg_total_relation_size - テーブル、TOASTテーブル、インデクスを含みます。

pg_column_sizeは、ジオメトリがカラム内で取る領域がどれだけかを、圧縮を考慮して返します。そのため、ST_MemSizeより小さくなることがあります。

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

This function supports Polyhedral surfaces.

This function supports Triangles and Triangulated Irregular Network Surfaces (TIN).

Changed: 2.2.0 命名規則に従うためにST_MemSizeに変更しました。

-- マサチューセッツのデータセットでボストンが占めるバイト単位の容量を返します
SELECT pg_size_pretty(SUM(ST_MemSize(geom))) as totgeomsum,
pg_size_pretty(SUM(CASE WHEN town = 'BOSTON' THEN ST_MemSize(geom) ELSE 0 END)) As bossum,
CAST(SUM(CASE WHEN town = 'BOSTON' THEN ST_MemSize(geom) ELSE 0 END)*1.00 /
                SUM(ST_MemSize(geom))*100 As numeric(10,2)) As perbos
FROM towns;

totgeomsum        bossum        perbos
----------        ------        ------
1522 kB                30 kB        1.99


SELECT ST_MemSize(ST_GeomFromText('CIRCULARSTRING(220268 150415,220227 150505,220227 150406)'));

---
73

-- ジオメトリがテーブルに占める割合
SELECT pg_total_relation_size('public.neighborhoods') As fulltable_size, sum(ST_MemSize(geom)) As geomsize,
sum(ST_MemSize(geom))*1.00/pg_total_relation_size('public.neighborhoods')*100 As pergeom
FROM neighborhoods;
fulltable_size geomsize  pergeom
------------------------------------------------
262144         96238         36.71188354492187500000
        

Name

ST_NDims — ST_Geometry値の座標次元を返します。

Synopsis

integer ST_NDims(geometry g1);

説明

ジオメトリの座標次元返します。PostGISでは、2 - (X,Y), 3 - (X,Y,Z), (X,Y,M), 4 - (X,Y,Z,M)に対応しています。

This function supports 3d and will not drop the z-index.

SELECT ST_NDims(ST_GeomFromText('POINT(1 1)')) As d2point,
        ST_NDims(ST_GeomFromEWKT('POINT(1 1 2)')) As d3point,
        ST_NDims(ST_GeomFromEWKT('POINTM(1 1 0.5)')) As d2pointm;

         d2point | d3point | d2pointm
---------+---------+----------
           2 |       3 |        3
                        

Name

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

Synopsis

integer ST_NPoints(geometry g1);

説明

ジオメトリのポイントの数を返します。全てのジオメトリに対して動作します。

Enhanced: 2.0.0 多面体サーフェス対応が導入されました。

[Note]

1.3.4より前では、曲線を含むジオメトリで使用すると、この関数はクラッシュします。これは1.3.4以上で訂正されています。

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

This function supports Polyhedral surfaces.

SELECT ST_NPoints(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
-- 結果
4

-- 3次元空間上のポリゴン
SELECT ST_NPoints(ST_GeomFromEWKT('LINESTRING(77.29 29.07 1,77.42 29.26 0,77.27 29.31 -1,77.29 29.07 3)'))
-- 結果
4

関連情報

ST_NumPoints


Name

ST_NRings — ポリゴンジオメトリのリング数を返します。

Synopsis

integer ST_NRings(geometry geomA);

説明

ジオメトリがポリゴンまたはマルチポリゴンの場合、リング数を返します。NumInteriorRingsと違い、外環も数えます。

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

SELECT ST_NRings(geom) As Nrings, ST_NumInteriorRings(geom) As ninterrings
                                        FROM (SELECT ST_GeomFromText('POLYGON((1 2, 3 4, 5 6, 1 2))') As geom) As foo;
         nrings | ninterrings
--------+-------------
          1 |           0
(1 row)

Name

ST_NumGeometries — ジオメトリコレクションの要素数を返します。

Synopsis

integer ST_NumGeometries(geometry geom);

説明

ジオメトリの数を返します。ジオメトリがジオメトリコレクションまたはマルチ系の場合は、ジオメトリの数を返し、単一のジオメトリの場合は1を返し、それ以外の場合はNULLを返します。

Enhanced: 2.0.0 多面体サーフェス対応、三角対応、TIN対応が導入されました。

Changed: 2.0.0 前の版では、ジオメトリがコレクション/マルチ系でない場合にはNULLを返しました。2.0.0以上では、POLYGON, LINESTRING, POINTといった単一ジオメトリについては1を返します。

This method implements the SQL/MM specification. SQL-MM 3: 9.1.4

This function supports 3d and will not drop the z-index.

This function supports Polyhedral surfaces.

This function supports Triangles and Triangulated Irregular Network Surfaces (TIN).

-- 以前の版ではNULLが返りました
-- 2.0.0から1が返ります
SELECT ST_NumGeometries(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
-- 結果
1

-- ジオメトリコレクションの例
-- - マルチ系はコレクションで一つのジオメトリと数えます。
SELECT ST_NumGeometries(ST_GeomFromEWKT('GEOMETRYCOLLECTION(MULTIPOINT(-2 3 , -2 2),
LINESTRING(5 5 ,10 10),
POLYGON((-7 4.2,-7.1 5,-7.1 4.3,-7 4.2)))'));
-- 結果
3

関連情報

ST_GeometryN, ST_Multi


Name

ST_NumInteriorRings — ポリゴンの内環 (穴)の数を返します。

Synopsis

integer ST_NumInteriorRings(geometry a_polygon);

説明

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

This method implements the SQL/MM specification. SQL-MM 3: 8.2.5

Changed: 2.0.0 - 以前の版では、MULTIPOLYGONを渡して最初のPOLYGONの内環の数を返すことができました。

-- 通常のポリゴンの場合
SELECT gid, field1, field2, ST_NumInteriorRings(geom) AS numholes
FROM sometable;

-- マルチポリゴンの内側リングの総数を知りたい場合
SELECT gid, field1, field2, SUM(ST_NumInteriorRings(geom)) AS numholes
FROM (SELECT gid, field1, field2, (ST_Dump(geom)).geom As geom
        FROM sometable) As foo
GROUP BY gid, field1,field2;
                        

Name

ST_NumInteriorRing — ポリゴンの内環 (穴)の数を返します。ST_NumInteriorRingsの別名です。

Synopsis

integer ST_NumInteriorRing(geometry a_polygon);


Name

ST_NumPatches — 多面体サーフェスのフェイス数を返します。多面体でないジオメトリの場合にはNULLを返します。

Synopsis

integer ST_NumPatches(geometry g1);

説明

多面体サーフェスのフェイス数を返します。多面体でないジオメトリの場合にはNULLを返します。ST_NumGeometriesの別名で、MMの名前付けに対応するためのものです。MM規約を気にしない場合はST_NumGeometriesの方が速いです。

Availability: 2.0.0

This function supports 3d and will not drop the z-index.

This method implements the OGC Simple Features Implementation Specification for SQL 1.1.

This method implements the SQL/MM specification. SQL-MM ISO/IEC 13249-3: 8.5

This function supports Polyhedral surfaces.

SELECT ST_NumPatches(ST_GeomFromEWKT('POLYHEDRALSURFACE( ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),
                ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),
                ((1 1 0, 1 1 1, 1 0 1, 1 0 0, 1 1 0)),
                ((0 1 0, 0 1 1, 1 1 1, 1 1 0, 0 1 0)), ((0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1)) )'));
                -- 結果 --
                6
                

Name

ST_NumPoints — ラインストリングまたは曲線ストリングのポイント数を返します。

Synopsis

integer ST_NumPoints(geometry g1);

説明

ST_LineStringまたはST_CircularStringのポイント数を返します。1.4より前は仕様通りにラインストリングにのみ対応していました。1.4以上ではラインストリングだけでなく頂点数を返すST_NPointsの別名です。多目的で多数のジオメトリタイプで動作するST_NPointsを使うことを考えて下さい。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1.

This method implements the SQL/MM specification. SQL-MM 3: 7.2.4

SELECT ST_NumPoints(ST_GeomFromText('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'));
                -- 結果
                4
                

関連情報

ST_NPoints


Name

ST_PatchN — 多面体サーフェスのN番目のジオメトリ (フェイス)を返します。

Synopsis

geometry ST_PatchN(geometry geomA, integer n);

説明

ジオメトリがPOLYHEDRALSURFACEかPOLYHEDRALSURFACEMの場合には、1始まりでN番目のジオメトリ (フェイス)を返します。それ以外の場合には、NULLを返します。多面体サーフェスを引数にとるST_GeometryNと同じ答えが返ります。ST_GeometryNの方が速いです。

[Note]

インデクスは1始まりです。

[Note]

ジオメトリの全ての要素を抽出するにはST_Dumpが最も効率的です。

Availability: 2.0.0

This method implements the SQL/MM specification. SQL-MM ISO/IEC 13249-3: 8.5

This function supports 3d and will not drop the z-index.

This function supports Polyhedral surfaces.

-- 多面体サーフェスの2番目のフェイスを抽出
SELECT ST_AsEWKT(ST_PatchN(geom, 2)) As geomewkt
FROM (
VALUES (ST_GeomFromEWKT('POLYHEDRALSURFACE( ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)),
        ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),
        ((1 1 0, 1 1 1, 1 0 1, 1 0 0, 1 1 0)),
        ((0 1 0, 0 1 1, 1 1 1, 1 1 0, 0 1 0)), ((0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1)) )')) ) As foo(geom);

              geomewkt
---+-----------------------------------------
 POLYGON((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0))

Name

ST_PointN — ジオメトリの最初のラインストリングまたは曲線ストリングのN番目のポイントを返します。

Synopsis

geometry ST_PointN(geometry a_linestring, integer n);

説明

ラインストリングまたは曲線ストリングのN番目の点を返します。負数はラインストリングの終端から逆方向に遡って数えます。-1は終端を指します。ジオメトリにラインストリングが無い場合には、NULLを返します。

[Note]

OGC仕様のため0.8.0版からインデックスを1始まりにしています。これより前の版では0はじまりになっています。後方インデックス (負数インデックス)はOGC仕様ではありません。

[Note]

マルチラインストリング内のラインストリングのN番目のポイントを得るには、ST_Dumpを併用します。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1.

This method implements the SQL/MM specification. SQL-MM 3: 7.2.5, 7.3.5

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

[Note]

Changed: 2.0.0 単一ジオメトリのMULTILINESTRINGで動作しなくなりました。単一のラインストリングからなるMULTILINESTRINGについては幸運にも動いていて、最初のポイントを返していました。2.0.0では他のMULTILINESTRINGと同様にNULLを返すようになりました。

Changed: 2.3.0 : 負数インデックスが有効になりました (-1は終端を指します)

-- LINESTRINGから全てのPOINTを抽出
SELECT ST_AsText(
   ST_PointN(
          column1,
          generate_series(1, ST_NPoints(column1))
   ))
FROM ( VALUES ('LINESTRING(0 0, 1 1, 2 2)'::geometry) ) AS foo;

 st_astext
------------
 POINT(0 0)
 POINT(1 1)
 POINT(2 2)
(3 rows)

-- 曲線ストリングの例
SELECT ST_AsText(ST_PointN(ST_GeomFromText('CIRCULARSTRING(1 2, 3 2, 1 2)'), 2));

 st_astext
------------
 POINT(3 2)
(1 row)

SELECT ST_AsText(f)
FROM ST_GeomFromText('LINESTRING(0 0 0, 1 1 1, 2 2 2)') AS g
  ,ST_PointN(g, -2) AS f; -- 1 based index

    st_astext
-----------------
 POINT Z (1 1 1)
(1 row)

関連情報

ST_NPoints


Name

ST_Points — ジオメトリの全ての座標を含むマルチポイントを返します。

Synopsis

geometry ST_Points( geometry geom );

説明

ジオメトリの全ての座標を含むマルチポイントを返します。リングジオメトリの始点と終点を含む重複ポイントは保存されます (重複ポイントの削除が必要ならST_RemoveRepeatedPointsを呼ぶと削除した結果が得られます)。

親ジオメトリの個々の座標のポイントに関する情報を取得するにはST_DumpPointsを使います。

M値とZ値が存在する場合には保持されます。

This method supports Circular Strings and Curves

This function supports 3d and will not drop the z-index.

Availability: 2.3.0

SELECT ST_AsText(ST_Points('POLYGON Z ((30 10 4,10 30 5,40 40 6, 30 10))'));

-- 結果 --
MULTIPOINT Z ((30 10 4),(10 30 5),(40 40 6),(30 10 4))
                        

Name

ST_StartPoint — ラインストリングの始点を返します。

Synopsis

geometry ST_StartPoint(geometry geomA);

説明

LINESTRINGまたはCIRCULARLINESTRINGジオメトリの、最初のポイントをPOINTで返します。入力パラメータがLINESTRINGでもCIRCULARLINESTRINGでもない場合には、NULLを返します。

This method implements the SQL/MM specification. SQL-MM 3: 7.1.3

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

[Note]

Enhanced: 3.2.0 全てのジオメトリのポイントを返すようになりました。以前のバージョンではラインストリング以外ではNULLを返していました。

Changed: 2.0.0 一つのMULTILINESTRINGで動作しなくなりました。PostGIS の古いバージョンでは、この関数は、一つのラインストリングからなるMULTILINESTRINGについては幸運にも動いていて、始端ポイントを返していました。2.0.0では他のMULTILINESTRINGと同様にNULLを返すようになりました。古い動作は文書化されていない機能でしたが、データをLINESTRINGとして格納していると思われるユーザーは、2.0.0 でNULLが返されることを経験するかも知れません。

ラインストリングの始端ポイント

SELECT ST_AsText(ST_StartPoint('LINESTRING(0 1, 0 2)'::geometry));
 st_astext
------------
 POINT(0 1)

ラインストリングでないものの始端ポイントはNULL

SELECT ST_StartPoint('POINT(0 1)'::geometry) IS NULL AS is_null;
  is_null
----------
 t

3次元ラインストリングの始端ポイント

SELECT ST_AsEWKT(ST_StartPoint('LINESTRING(0 1 1, 0 2 2)'::geometry));
 st_asewkt
------------
 POINT(0 1 1)

CIRCULARSTRINGの始端ポイント

SELECT ST_AsText(ST_StartPoint('CIRCULARSTRING(5 2,-3 1.999999, -2 1, -4 2, 6 3)'::geometry));
 st_astext
------------
 POINT(5 2)

関連情報

ST_EndPoint, ST_PointN


Name

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

Synopsis

text ST_Summary(geometry g);

text ST_Summary(geography g);

説明

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

ジオメトリ型の後の角括弧で示されたフラグには次の意味があります。

  • M: M軸を持ちます

  • Z: Z軸を持ちます

  • B: バウンディングボックスを持ちます

  • G: 測地座標系 (ジオグラフィ)です

  • S: 空間参照系を持ちます

This method supports Circular Strings and Curves

This function supports Polyhedral surfaces.

This function supports Triangles and Triangulated Irregular Network Surfaces (TIN).

Availability: 1.2.2

Enhanced: 2.0.0でジオグラフィ対応が追加されました。

Enhanced: 2.1.0 空間参照系を持つかを示すSフラグが追加されました。

Enhanced: 2.2.0 TINと曲線の対応が追加されました。

=# SELECT ST_Summary(ST_GeomFromText('LINESTRING(0 0, 1 1)')) as geom,
        ST_Summary(ST_GeogFromText('POLYGON((0 0, 1 1, 1 2, 1 1, 0 0))')) geog;
            geom             |          geog
-----------------------------+--------------------------
 LineString[B] with 2 points | Polygon[BGS] with 1 rings
                             | ring 0 has 5 points
                             :
(1 row)


=# SELECT ST_Summary(ST_GeogFromText('LINESTRING(0 0 1, 1 1 1)')) As geog_line,
        ST_Summary(ST_GeomFromText('SRID=4326;POLYGON((0 0 1, 1 1 2, 1 2 3, 1 1 1, 0 0 1))')) As geom_poly;
;
           geog_line             |        geom_poly
-------------------------------- +--------------------------
 LineString[ZBGS] with 2 points | Polygon[ZBS] with 1 rings
                                :    ring 0 has 5 points
                                :
(1 row)


Name

ST_X — ポイントのX値を返します。

Synopsis

float ST_X(geometry a_point);

説明

ポイントのX座標値を返し、有効でないならNULLを返します。入力はポイントでなければなりません。

[Note]

ジオメトリのX値の最小値と最大値を得るにはST_XMinST_XMaxを使います。

This method implements the SQL/MM specification. SQL-MM 3: 6.1.3

This function supports 3d and will not drop the z-index.

SELECT ST_X(ST_GeomFromEWKT('POINT(1 2 3 4)'));
 st_x
------
        1
(1 row)

SELECT ST_Y(ST_Centroid(ST_GeomFromEWKT('LINESTRING(1 2 3 4, 1 1 1 1)')));
 st_y
------
  1.5
(1 row)

                

Name

ST_Y — ポイントのY値を返します。

Synopsis

float ST_Y(geometry a_point);

説明

ポイントのY座標値を返し、有効でないならNULLを返します。入力はポイントでなければなりません。

[Note]

ジオメトリの値の最小値と最大値を得るにはST_YMinST_YMaxを使います。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1.

This method implements the SQL/MM specification. SQL-MM 3: 6.1.4

This function supports 3d and will not drop the z-index.

SELECT ST_Y(ST_GeomFromEWKT('POINT(1 2 3 4)'));
 st_y
------
        2
(1 row)

SELECT ST_Y(ST_Centroid(ST_GeomFromEWKT('LINESTRING(1 2 3 4, 1 1 1 1)')));
 st_y
------
  1.5
(1 row)


                

Name

ST_Z — ポイントのZ値を返します。

Synopsis

float ST_Z(geometry a_point);

説明

ポイントのZ座標値を返し、有効でないならNULLを返します。入力はポイントでなければなりません。

[Note]

ジオメトリのZ値の最小値と最大値を得るにはST_ZMinST_ZMaxを使います。

This method implements the SQL/MM specification.

This function supports 3d and will not drop the z-index.

SELECT ST_Z(ST_GeomFromEWKT('POINT(1 2 3 4)'));
 st_z
------
        3
(1 row)

                

Name

ST_Zmflag — ジオメトリのZM座標次元を示す符号を返します。

Synopsis

smallint ST_Zmflag(geometry geomA);

説明

ジオメトリのZM座標次元を示す符号を返します。

値は 0=XY, 1=XYM, 2=XYZ, 3=XYZMとなります。

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

SELECT ST_Zmflag(ST_GeomFromEWKT('LINESTRING(1 2, 3 4)'));
 st_zmflag
-----------
                 0

SELECT ST_Zmflag(ST_GeomFromEWKT('LINESTRINGM(1 2 3, 3 4 3)'));
 st_zmflag
-----------
                 1

SELECT ST_Zmflag(ST_GeomFromEWKT('CIRCULARSTRING(1 2 3, 3 4 3, 5 6 3)'));
 st_zmflag
-----------
                 2
SELECT ST_Zmflag(ST_GeomFromEWKT('POINT(1 2 3 4)'));
 st_zmflag
-----------
                 3

8.5. ジオメトリエディタ

Abstract

これらの関数は、タイプ、構造または頂点の変更によって編集されたジオメトリを生成します。

ST_AddPoint — ラインストリングにポイントを追加します。
ST_CollectionExtract — ジオメトリコレクションを与えると、指定されたタイプの要素だけからなるマルチジオメトリを返します。
ST_CollectionHomogenize — ジオメトリコレクションを与えると、最も単純な表現を返します。
ST_CurveToLine — 曲線を含むジオメトリを線ジオメトリに変換します。
ST_Scroll — 閉じたLINESTRINGの開始点を変更する。
ST_FlipCoordinates — X値とY値を入れ替えたジオメトリを返します。
ST_Force2D — ジオメトリを2次元モードに強制します。
ST_Force3D — ジオメトリをXYZモードに強制します。これはST_Force3DZの別名です。
ST_Force3DZ — ジオメトリをXYZモードに強制します。
ST_Force3DM — ジオメトリをXYMモードに強制します。
ST_Force4D — ジオメトリをXYZMモードに強制します。
ST_ForcePolygonCCW — 全ての外環を反時計回りに、全ての内環を時計回りに、それぞれ強制します。
ST_ForceCollection — ジオメトリをジオメトリコレクションに変換します。
ST_ForcePolygonCW — 全ての外環を時計回りに、全ての内環を反時計回りに、それぞれ強制します。
ST_ForceSFS — SFS 1.1ジオメトリタイプのみ使うようジオメトリに強制します。
ST_ForceRHR — ポリゴンの頂点の方向を右回りに強制します。
ST_ForceCurve — 該当する場合は、ジオメトリを曲線タイプに変換します。
ST_LineToCurve — 曲線を含むジオメトリを線ジオメトリに変換します。
ST_Multi — マルチ系ジオメトリを返します。
ST_Normalize — 標準的な形式に変えたジオメトリを返します。
ST_QuantizeCoordinates — 座標値の最下位ビットを0にします。
ST_RemovePoint — ラインストリングからポイントを削除します。
ST_RemoveRepeatedPoints — 重複ポイントを除いたジオメトリを返します。
ST_Reverse — 頂点の順序を逆にしたジオメトリを返します。
ST_Segmentize — 与えた距離を超える線分を持たないよう変更したジオメトリ/ジオグラフィを返します。
ST_SetPoint — ラインストリングのポイントを与えられたポイントに置き換えます。
ST_ShiftLongitude — 経度座標値を-180度から180度の範囲と0度から360度の範囲との二つの範囲を行き来するようシフトします。
ST_WrapX — ジオメトリをX値で回り込ませます。
ST_SnapToGrid — 入力ジオメトリの全ての点を規則的なグリッドにスナップします。
ST_Snap — 入力ジオメトリの辺と頂点を参照ジオメトリの頂点にスナップします。
ST_SwapOrdinates — 与えられたジオメトリにおいて与えられた座標の値を入れ替えたジオメトリを返します。

Name

ST_AddPoint — ラインストリングにポイントを追加します。

Synopsis

geometry ST_AddPoint(geometry linestring, geometry point);

geometry ST_AddPoint(geometry linestring, geometry point, integer position = -1);

説明

LINESTRINGのpositionの位置 (0はじまり)の前にポイントを追加します。positionパラメータが省略されるか-1の場合には、LINESTRINGの末尾に追加されます。

Availability: 1.1.0

This function supports 3d and will not drop the z-index.

3次元ラインの末尾へのポイントの追加

SELECT ST_AsEWKT(ST_AddPoint('LINESTRING(0 0 1, 1 1 1)', ST_MakePoint(1, 2, 3)));

    st_asewkt
    ----------
    LINESTRING(0 0 1,1 1 1,1 2 3)

テーブル内の全てのラインについて、閉じていないラインにだけ始端を末尾に追加することで、閉じていることを保証します。

UPDATE sometable
SET geom = ST_AddPoint(geom, ST_StartPoint(geom))
FROM sometable
WHERE ST_IsClosed(geom) = false;

Name

ST_CollectionExtract — ジオメトリコレクションを与えると、指定されたタイプの要素だけからなるマルチジオメトリを返します。

Synopsis

geometry ST_CollectionExtract(geometry collection);

geometry ST_CollectionExtract(geometry collection, integer type);

説明

ジオメトリコレクションを指定すると、要素のタイプが統一されたマルチジオメトリを返します。

typeが指定されていない場合には、最大次元のジオメトリだけを含むマルチジオメトリを返します。このため、ポリゴンはラインに優先され、ラインはポイントに優先されます。

typeが指定されている場合には、指定されたタイプだけを含むマルチジオメトリを返します。指定されたタイプの要素が無い場合には、EMPTYジオメトリを返します。ポイント、ライン、ポリゴンだけに対応しています。タイプの番号は次の通りです。

  • 1 == POINT

  • 2 == LINESTRING

  • 3 == POLYGON

非マルチジオメトリの入力に対しては、ジオメトリのタイプと指定したタイプが合致している場合には変更せず返します。合致しない場合には、指定したタイプのEMPTYジオメトリを返します。ST_Multi"/>を使ってマルチ系ジオメトリに変換する必要があるならST_Multiを使います。

[Warning]

マルチポリゴンの結果は妥当性チェックを行いません。ポリゴン要素が隣接やオーバラップしている場合には、結果ジオメトリは不正となります (たとえば、この関数をST_Splitの結果に適用すると発生します)。この状況に陥っているかはST_IsValidで確認でき、ST_MakeValidで修復できます。

Availability: 1.5.0

[Note]

1.5.3より前のこの関数は非マルチジオメトリの入力に対して、指定タイプに関係なく変更せずに返しました。1.5.3で指定タイプに合致しない単一ジオメトリ入力に対してNULLを返すようになりました。2.0.0で、合致しないジオメトリに対して、指定タイプのEMPTYジオメトリを返すようになりました。

最大次元となるタイプの抽出:

SELECT ST_AsText(ST_CollectionExtract(
        'GEOMETRYCOLLECTION( POINT(0 0), LINESTRING(1 1, 2 2) )'));
    st_astext
    ---------------
    MULTILINESTRING((1 1, 2 2))

ポイントの抽出 (type 1 == POINT):

SELECT ST_AsText(ST_CollectionExtract(
        'GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(POINT(0 0)))',
        1 ));
    st_astext
    ---------------
    MULTIPOINT(0 0)

ラインの抽出 (type 2 == LINESTRING):

SELECT ST_AsText(ST_CollectionExtract(
        'GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(LINESTRING(0 0, 1 1)),LINESTRING(2 2, 3 3))',
        2 ));
    st_astext
    ---------------
    MULTILINESTRING((0 0, 1 1), (2 2, 3 3))

Name

ST_CollectionHomogenize — ジオメトリコレクションを与えると、最も単純な表現を返します。

Synopsis

geometry ST_CollectionHomogenize(geometry collection);

説明

ジオメトリコレクションを与えると、「最も単純な」表現を返します。

  • 同種の要素からなるコレクションが適切なマルチ系ジオメトリとして返されます。

  • タイプ混合のコレクションはフラットな単一のGEOMETRYCOLLECTIONに変換されます。

  • 単一の非マルチジオメトリ要素からなるコレクションはその要素が返されます。

  • 非マルチジオメトリは変更されずに返ります。マルチジオメトリへの変換が必要ならST_Multiを使います。

[Warning]

この関数は結果ジオメトリの妥当性を保証されず、隣接やオーバラップする複数ポリゴンからは不正なMULTIPOLYGONが生成されます。この状況に陥っているかはST_IsValidで確認でき、ST_MakeValidで修復できます。

Availability: 2.0.0

単一要素のコレクションから非マルチジオメトリへの変換

SELECT ST_AsText(ST_CollectionHomogenize('GEOMETRYCOLLECTION(POINT(0 0))'));

        st_astext
        ------------
        POINT(0 0)

ネスト下単一要素のコレクションから非マルチジオメトリへの変換:

SELECT ST_AsText(ST_CollectionHomogenize('GEOMETRYCOLLECTION(MULTIPOINT((0 0)))'));

        st_astext
        ------------
        POINT(0 0)

コレクションからマルチ系ジオメトリへの変換:

SELECT ST_AsText(ST_CollectionHomogenize('GEOMETRYCOLLECTION(POINT(0 0),POINT(1 1))'));

        st_astext
        ---------------------
        MULTIPOINT((0 0),(1 1))

ネストしたタイプ混合のコレクションからフラットなジオメトリコレクションへの変換:

SELECT ST_AsText(ST_CollectionHomogenize('GEOMETRYCOLLECTION(POINT(0 0), GEOMETRYCOLLECTION( LINESTRING(1 1, 2 2)))'));

        st_astext
        ---------------------
        GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(1 1,2 2))

ポリゴンのコレクションから (不正な)マルチポリゴンへの変換:

SELECT ST_AsText(ST_CollectionHomogenize('GEOMETRYCOLLECTION (POLYGON ((10 50, 50 50, 50 10, 10 10, 10 50)), POLYGON ((90 50, 90 10, 50 10, 50 50, 90 50)))'));

        st_astext
        ---------------------
        MULTIPOLYGON(((10 50,50 50,50 10,10 10,10 50)),((90 50,90 10,50 10,50 50,90 50)))

Name

ST_CurveToLine — 曲線を含むジオメトリを線ジオメトリに変換します。

Synopsis

geometry ST_CurveToLine(geometry curveGeom, float tolerance, integer tolerance_type, integer flags);

説明

CIRCULARSTRINGをLINESTRINGに、CURVEPOLYGONをPOLYGONに、MULTISURFACEをMULTIPOLYGONに、それぞれ変換します。CIRCULARSTRINGジオメトリタイプに対応していないデバイスへの出力に使用します。

与えられたジオメトリを線型ジオメトリに変換します。それぞれの曲線ジオメトリまたは辺は、`tolerance` とオプションを使用して線形近似に変換します (デフォルトでは4分の1円ごとに32辺でオプションなしです)。

'tolerance_type'引数によって`tolerance`引数の解釈が決定されます。

  • 0 (デフォルト): toleranceは4分の1円の最大辺数です。

  • 1: toleranceは曲線からラインまでの最大差です。単位は入力ジオメトリの単位です。

  • 2: toleranceは生成される半径がなす角度のラジアン単位の最大値です。

'flags'引数はビットフィールドです。デフォルトでは0です。次のビットに対応します。

  • 1: 対称となる (方向独立)出力。

  • 2: 角度維持。対称出力を生成する時に角度 (辺長)減少を避けます。対称フラグがOFFの時は何の効果もありません。

Availability: 1.3.0

Enhanced: 2.4.0 最大距離差による許容範囲と最大角度による許容範囲に対応し、対称出力に対応しました。

Enhanced: 3.0.0 線形化した弧ごとの最小線分数を実装しました。トポロジ的な崩壊を防ぐためです。

This method implements the OGC Simple Features Implementation Specification for SQL 1.1.

This method implements the SQL/MM specification. SQL-MM 3: 7.1.7

This function supports 3d and will not drop the z-index.

This method supports Circular Strings and Curves

SELECT ST_AsText(ST_CurveToLine(ST_GeomFromText('CIRCULARSTRING(220268 150415,220227 150505,220227 150406)')));

--Result --
 LINESTRING(220268 150415,220269.95064912 150416.539364228,220271.823415575 150418.17258804,220273.613787707 150419.895736857,
 220275.317452352 150421.704659462,220276.930305234 150423.594998003,220278.448460847 150425.562198489,
 220279.868261823 150427.60152176,220281.186287736 150429.708054909,220282.399363347 150431.876723113,
 220283.50456625 150434.10230186,220284.499233914 150436.379429536,220285.380970099 150438.702620341,220286.147650624 150441.066277505,
 220286.797428488 150443.464706771,220287.328738321 150445.892130112,220287.740300149 150448.342699654,
 220288.031122486 150450.810511759,220288.200504713 150453.289621251,220288.248038775 150455.77405574,
 220288.173610157 150458.257830005,220287.977398166 150460.734960415,220287.659875492 150463.199479347,
 220287.221807076 150465.64544956,220286.664248262 150468.066978495,220285.988542259 150470.458232479,220285.196316903 150472.81345077,
 220284.289480732 150475.126959442,220283.270218395 150477.39318505,220282.140985384 150479.606668057,
 220280.90450212 150481.762075989,220279.5637474 150483.85421628,220278.12195122 150485.87804878,
 220276.582586992 150487.828697901,220274.949363179 150489.701464356,220273.226214362 150491.491836488,
 220271.417291757 150493.195501133,220269.526953216 150494.808354014,220267.559752731 150496.326509628,
 220265.520429459 150497.746310603,220263.41389631 150499.064336517,220261.245228106 150500.277412127,
 220259.019649359 150501.38261503,220256.742521683 150502.377282695,220254.419330878 150503.259018879,
 220252.055673714 150504.025699404,220249.657244448 150504.675477269,220247.229821107 150505.206787101,
 220244.779251566 150505.61834893,220242.311439461 150505.909171266,220239.832329968 150506.078553494,
 220237.347895479 150506.126087555,220234.864121215 150506.051658938,220232.386990804 150505.855446946,
 220229.922471872 150505.537924272,220227.47650166 150505.099855856,220225.054972724 150504.542297043,
 220222.663718741 150503.86659104,220220.308500449 150503.074365683,
 220217.994991777 150502.167529512,220215.72876617 150501.148267175,
 220213.515283163 150500.019034164,220211.35987523 150498.7825509,
 220209.267734939 150497.441796181,220207.243902439 150496,
 220205.293253319 150494.460635772,220203.420486864 150492.82741196,220201.630114732 150491.104263143,
 220199.926450087 150489.295340538,220198.313597205 150487.405001997,220196.795441592 150485.437801511,
 220195.375640616 150483.39847824,220194.057614703 150481.291945091,220192.844539092 150479.123276887,220191.739336189 150476.89769814,
 220190.744668525 150474.620570464,220189.86293234 150472.297379659,220189.096251815 150469.933722495,
 220188.446473951 150467.535293229,220187.915164118 150465.107869888,220187.50360229 150462.657300346,
 220187.212779953 150460.189488241,220187.043397726 150457.710378749,220186.995863664 150455.22594426,
 220187.070292282 150452.742169995,220187.266504273 150450.265039585,220187.584026947 150447.800520653,
 220188.022095363 150445.35455044,220188.579654177 150442.933021505,220189.25536018 150440.541767521,
 220190.047585536 150438.18654923,220190.954421707 150435.873040558,220191.973684044 150433.60681495,
 220193.102917055 150431.393331943,220194.339400319 150429.237924011,220195.680155039 150427.14578372,220197.12195122 150425.12195122,
 220198.661315447 150423.171302099,220200.29453926 150421.298535644,220202.017688077 150419.508163512,220203.826610682 150417.804498867,
 220205.716949223 150416.191645986,220207.684149708 150414.673490372,220209.72347298 150413.253689397,220211.830006129 150411.935663483,
 220213.998674333 150410.722587873,220216.22425308 150409.61738497,220218.501380756 150408.622717305,220220.824571561 150407.740981121,
 220223.188228725 150406.974300596,220225.586657991 150406.324522731,220227 150406)

--3d example
SELECT ST_AsEWKT(ST_CurveToLine(ST_GeomFromEWKT('CIRCULARSTRING(220268 150415 1,220227 150505 2,220227 150406 3)')));
Output
------
 LINESTRING(220268 150415 1,220269.95064912 150416.539364228 1.0181172856673,
 220271.823415575 150418.17258804 1.03623457133459,220273.613787707 150419.895736857 1.05435185700189,....AD INFINITUM ....
    220225.586657991 150406.324522731 1.32611114201132,220227 150406 3)

--use only 2 segments to approximate quarter circle
SELECT ST_AsText(ST_CurveToLine(ST_GeomFromText('CIRCULARSTRING(220268 150415,220227 150505,220227 150406)'),2));
st_astext
------------------------------
 LINESTRING(220268 150415,220287.740300149 150448.342699654,220278.12195122 150485.87804878,
 220244.779251566 150505.61834893,220207.243902439 150496,220187.50360229 150462.657300346,
 220197.12195122 150425.12195122,220227 150406)

-- Ensure approximated line is no further than 20 units away from
-- original curve, and make the result direction-neutral
SELECT ST_AsText(ST_CurveToLine(
 'CIRCULARSTRING(0 0,100 -100,200 0)'::geometry,
    20, -- Tolerance
    1, -- Above is max distance between curve and line
    1  -- Symmetric flag
));
st_astext
-------------------------------------------------------------------------------------------
 LINESTRING(0 0,50 -86.6025403784438,150 -86.6025403784439,200 -1.1331077795296e-13,200 0)


        

関連情報

ST_LineToCurve


Name

ST_Scroll — 閉じたLINESTRINGの開始点を変更する。

Synopsis

geometry ST_Scroll(geometry linestring, geometry point);

説明

閉じたLINESTRINGの開始/終了点を pointで指定した頂点に変更します。

Availability: 3.2.0

This function supports 3d and will not drop the z-index.

This function supports M coordinates.

閉じたラインの3番目の頂点を開始点にする

SELECT ST_AsEWKT(ST_Scroll('SRID=4326;LINESTRING(0 0 0 1, 10 0 2 0, 5 5 4 2,0 0 0 1)', 'POINT(5 5 4 2)'));

st_asewkt
----------
SRID=4326;LINESTRING(5 5 4 2,0 0 0 1,10 0 2 0,5 5 4 2)

関連情報

ST_Normalize


Name

ST_FlipCoordinates — X値とY値を入れ替えたジオメトリを返します。

Synopsis

geometry ST_FlipCoordinates(geometry geom);

説明

与えられたジオメトリのX値とY値を入れ替えたものを返します。緯度経度 (Y,X)で表現される座標値を持つジオメトリを修正するのに使います。

Availability: 2.0.0

This method supports Circular Strings and Curves

This function supports 3d and will not drop the z-index.

This function supports M coordinates.

This function supports Polyhedral surfaces.

This function supports Triangles and Triangulated Irregular Network Surfaces (TIN).

SELECT ST_AsEWKT(ST_FlipCoordinates(GeomFromEWKT('POINT(1 2)')));
 st_asewkt
------------
POINT(2 1)