GanosBase Geometry は、PolarDB for PostgreSQL 向けの時空間エンジン拡張機能です。Open Geospatial Consortium (OGC) が定義する Simple Features Access (SFA) 標準を実装しており、単一のポイントから複合曲線、サーフェスコレクションに至るまで、幾何学的オブジェクトを格納・照会・分析するための包括的なツールセットを提供します。
基本概念
ジオメトリ型の階層構造
Geometry は抽象型です。すべての具体的なジオメトリ値は、そのサブタイプのいずれかに属し、以下の 3 つのカテゴリに分類されます。
原子型 — 分割不能な形状:Point、LineString、Polygon
パラメーター化型 — GanosBase 固有の曲線定義形状:EllipticalString、Bezier3Curve
コレクション型 — 複数の形状をグループ化したもの:MultiPoint、MultiLineString、MultiPolygon、GeometryCollection、CompoundCurve、CurvePolygon
各サブタイプの詳細については、「ジオメトリデータ型」をご参照ください。
座標のディメンション
ジオメトリは、2D または 3D の座標系で形状を表現します。すべての座標には x 値と y 値があり、さらに以下の値を含む場合があります。
| 座標 | 意味 | ディメンションへの影響 |
|---|---|---|
| x、y | 平面上の位置 | 2D |
| z | 標高または深さ | 第 3 ディメンションを追加(3D) |
| m | メジャー値 — 時間、距離、その他の線形基準 | 第 3 ディメンションを追加(3D) |
| z と m の両方 | エレベーションとメジャーの両方 | 4D |
z 値または m 値が存在する場合、ジオメトリ内のすべてのポイントで定義する必要があります。
空間参照システム
空間参照システム (SRS) は、座標が地球上の特定の位置にどのようにマッピングされるかを定義します。GanosBase では、整数識別子である SRID を用いて、各ジオメトリ値を SRS に関連付けます。SRID は、spatial_ref_sys テーブルを参照する外部キーです。
詳細については、「空間参照」をご参照ください。
サポートされる入力フォーマット
GanosBase では、以下のフォーマットでジオメトリデータを直接受け入れます。
| フォーマット | タイプ | 備考 |
|---|---|---|
| Well-Known Text (WKT) | テキスト | OGC 標準;タイプおよび座標を含むが、SRID は含まない |
| Well-Known Binary (WKB) | バイナリ | OGC 標準;ポータブルかつ高精度;SRID は含まない |
| EKWT | テキスト | WKT の GanosBase 拡張;SRID の埋め込みおよび 3DZ、3DM、4D をサポート |
| EKWB | バイナリ | WKB の GanosBase 拡張;EKWT と同様の追加機能を提供 |
| KML | XML | — |
| GML | XML | — |
| GeoHash | 文字列 | — |
| GeoJSON | JSON | RFC 7946 |
有効な WKT または WKB の値は、同時に有効な EKWT または EKWB でもあります。Esri Shapefile などの他のフォーマットについては、GanosBase へロードする前に外部インポートツールを使用してください。
ジオメトリデータ型
原子型
| 型 | 説明 | 例 |
|---|---|---|
| Point | 座標空間内における単一の位置を表す 0 次元ジオメトリ | POINT (1 2)、POINT Z (1 2 3)、POINT ZM (1 2 3 4) |
| LineString | 隣接した線分の連続シーケンスによって形成される 1 次元ライン;自己交差が可能 | LINESTRING (1 2, 3 4, 5 6) |
| Polygon | 外部境界(シェル)および 0 個以上の内部境界(ホール)によって区切られた 2 次元平面領域;各境界は LinearRing | 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)) |
パラメーター化型
これらの型は GanosBase 固有であり、ポイントのシーケンスではなく数学的パラメーターを使用します。
| 型 | 説明 | 例 |
|---|---|---|
| EllipticalString | 楕円弧 | ELLIPTICALSTRING(-2 0,2 0,0 0,0,0,0,2,0.5) |
| Bezier3Curve | 4 つの制御点で定義される 3 次ベジエ曲線 | BEZIER3CURVE(1 1, 2 2, 3 2, 3 1) |
コレクション型
| 型 | 説明 | 例 |
|---|---|---|
| MultiPoint | Point のコレクション | MULTIPOINT ( (0 0), (1 2) ) |
| MultiLineString | LineString のコレクション | MULTILINESTRING ( (0 0,1 1,1 2), (2 3,3 2,5 4) ) |
| MultiPolygon | 重複せず、隣接しない Polygon のコレクション;Polygon は有限個の点で接することが可能 | MULTIPOLYGON (((1 5, 5 5, 5 1, 1 1, 1 5)), ((6 5, 9 1, 6 1, 6 5))) |
| GeometryCollection | 任意のジオメトリ型の異種コレクション | GEOMETRYCOLLECTION ( POINT(2 3), LINESTRING(2 3, 3 4)) |
| CompoundCurve | 直線セグメント、楕円弧、ベジエ曲線を組み合わせた複合ライン;各コンポーネントの終端点は次のコンポーネントの始点と一致する必要がある | COMPOUNDCURVE((1 0,2 0),ELLIPTICALSTRING(2 0 ,4 0, 3 0 ,1,0,0,1,0.5)) |
| CurvePolygon | 曲線境界を含む可能性のある閉じたサーフェス | CURVEPOLYGON(ELLIPTICALSTRING(2 0,2 0,0 0,0,0,0,2,0.5),CIRCULARSTRING(-0.5 0,0.5 0,-0.5 0)) |
geometry_columns ビュー
geometry_columns ビューは、データベースのシステムカタログテーブルからすべてのジオメトリカラムを読み取ります。これは、OGC が定義する SQL 向け Simple Features Specification に従います。
| カラム | 型 | 説明 |
|---|---|---|
f_table_catalog | varchar(256) | データベース名。固定値:postgres。 |
f_table_schema | varchar(256) | テーブルのスキーマ。 |
f_table_name | varchar(256) | テーブル名。 |
f_geometry_column | varchar(256) | ジオメトリカラム名。 |
coord_dimension | integer | 座標のディメンション。有効値:2、3、4。 |
srid | integer | カラムの SRID;spatial_ref_sys を参照する外部キー。 |
type | varchar(30) | OGC ジオメトリ型。GEOMETRY の値は、混合型を示します。 |
現在のデータベース内のすべてのジオメトリカラムを照会するには、以下を実行します。
SELECT * FROM geometry_columns;空間インデックス
空間インデックスにより、GanosBase は大規模な空間データセットを処理する際に、データベース全体に対する逐次スキャンを回避できます。空間インデックスは、特定のレコードを高速に検索できるように、データをツリー構造で整理します。
GanosBase では、以下の 3 種類の空間インデックスを提供しています。
| インデックス | 説明 | 推奨用途 |
|---|---|---|
| GiST(Generalized Search Tree) | バランスの取れた検索ツリー;高いクエリ性能;任意のデータ型およびカスタムアクセスメソッドを分散させるためのカスタムルールをサポート | ほとんどの空間テーブルのデフォルト選択肢 |
| BRIN(Block Range Index) | ブロックレベルのサマリーを格納;GiST よりもサイズが小さく、ビルド時間が短いが、クエリ速度は遅い;手動によるメンテナンスが必要;大量のデータレコードを返すクエリに対してより効果的 | 空間的重複が極めて少ない(例:ポイントデータ)、または静的または変更頻度が低い非常に大規模なテーブル |
| SP-GiST(Space-Partitioned Generalized Search Tree) | クアッドツリー、k-d ツリー、ラディクステリーなどのパーティション化された検索ツリーをサポート;GiST よりもサポートする演算子が少なく、KNN 検索をサポートしない | 重複しないオブジェクト;重複しないオブジェクトに対しては GiST よりも適している |
適用範囲/利用シーン/ユースケース
地図作成および可視化:道路、河川、建物などの地図要素をジオメトリ値として格納し、空間範囲に基づいて照会およびレンダリングします。
ロケーションサービス:ポイントデータに対して空間クエリおよび集約を実行し、近隣のリソースを検索したり、距離を計算したり、地理的リスクを評価します。
空間関係クエリ:フィーチャー間の関係(交差、重複、包含、隣接など)を特定します。
空間分析および計測:データセット全体にわたって面積、長さ、距離、重心などを計算します。
クイックスタート
このセクションでは、ganos_geometry 拡張機能の作成、ジオメトリテーブルの定義、データのインポート、インデックスの構築、空間クエリの実行について順に説明します。
拡張機能の作成
-- ganos_geometry 拡張機能を作成します。
CREATE EXTENSION ganos_geometry CASCADE;注意:権限問題を回避するため、拡張機能は public スキーマ内に作成してください。
CREATE EXTENSION ganos_geometry WITH SCHEMA public CASCADE;ジオメトリテーブルの作成
2 つの方法が利用可能です。ジオメトリ型および SRID が事前に判明している場合は、方法 1 を使用してください。
方法 1 — CREATE TABLE 文内でジオメトリカラムを定義する:
CREATE TABLE roads (
id int4,
road_name varchar(25),
geom geometry(LINESTRING, 3857)
);方法 2 — 既存のテーブルにジオメトリカラムを追加する:
CREATE TABLE roads (id int4, road_name varchar(25));
SELECT AddGeometryColumn('roads', 'geom', 3857, 'LINESTRING', 2);ジオメトリ制約の追加
ALTER TABLE roads ADD CONSTRAINT geometry_valid_check CHECK (ST_IsValid(geom));ジオメトリデータのインポート
全 6 行で、SRID 3857 を持つ WKT 文字列を解析するために ST_GeomFromText を使用します。
INSERT INTO roads (id, geom, road_name) VALUES
(1, ST_GeomFromText('LINESTRING(191232 243118,191108 243242)', 3857), '北五環路'),
(2, ST_GeomFromText('LINESTRING(189141 244158,189265 244817)', 3857), '東五環路'),
(3, ST_GeomFromText('LINESTRING(192783 228138,192612 229814)', 3857), '南五環路'),
(4, ST_GeomFromText('LINESTRING(189412 252431,189631 259122)', 3857), '西五環路'),
(5, ST_GeomFromText('LINESTRING(190131 224148,190871 228134)', 3857), '東長安街'),
(6, ST_GeomFromText('LINESTRING(198231 263418,198213 268322)', 3857), '西長安街');ジオメトリデータの照会
SELECT id, ST_AsText(geom) AS geom, road_name FROM roads;期待される出力:
id | geom | road_name
----+-----------------------------------------+----------------------
1 | LINESTRING(191232 243118,191108 243242) | 北五環路
2 | LINESTRING(189141 244158,189265 244817) | 東五環路
3 | LINESTRING(192783 228138,192612 229814) | 南五環路
4 | LINESTRING(189412 252431,189631 259122) | 西五環路
5 | LINESTRING(190131 224148,190871 228134) | 東長安街
6 | LINESTRING(198231 263418,198213 268322) | 西長安街
(6 rows)空間インデックスの作成
GiST インデックス(推奨):
-- 標準的な 2D GiST インデックス:
CREATE INDEX <index_name> ON <table_name> USING GIST (<geometry_column>);
-- N 次元 GiST インデックス:
CREATE INDEX <index_name> ON <table_name> USING GIST (<geometry_column> gist_geometry_ops_nd);
-- インデックス構築後の統計情報更新:
VACUUM ANALYZE <table_name> (<geometry_column>);
-- 例:
CREATE INDEX sp_geom_index ON roads USING GIST(geom);
VACUUM ANALYZE roads (geom);BRIN インデックス(大規模で主に静的なテーブル向け):
-- 標準的な BRIN インデックス:
CREATE INDEX <index_name> ON <table_name> USING BRIN (<geometry_column>);
-- 3D または 4D BRIN インデックス:
CREATE INDEX <index_name> ON <table_name> USING BRIN (<geometry_column> brin_geometry_inclusion_ops_3d);
CREATE INDEX <index_name> ON <table_name> USING BRIN (<geometry_column> brin_geometry_inclusion_ops_4d);
-- カスタムブロックサイズを指定した BRIN インデックス:
CREATE INDEX <index_name> ON <table_name> USING BRIN (<geometry_column>) WITH (pages_per_range = <number>);空間データの計測および分析
以下の例では、2 つのサンプルテーブルを使用します。
bc_roads — カラム:gid (integer)、name (varchar)、the_geom (geometry/LineString)
bc_municipality — カラム:gid (integer)、code (integer)、name (varchar)、the_geom (geometry/Polygon)道路の総延長を計算する:
SELECT sum(ST_Length(the_geom)) / 1000 AS km_roads FROM bc_roads; km_roads
------------------
70842.1243039643
(1 row)自治体の面積を計算する:
SELECT ST_Area(the_geom) / 10000 AS hectares
FROM bc_municipality
WHERE name = 'プリンス・ジョージ'; hectares
------------------
32657.9103824927
(1 row)空間関係クエリの実行
GanosBase では、OGC が定義する完全な空間関係関数セットがサポートされています。以下に、共通パターンの例を示します。
ST_Contains — 各自治体に含まれる道路を検索する:
SELECT m.name, sum(ST_Length(r.the_geom)) / 1000 AS roads_km
FROM bc_roads AS r, bc_municipality AS m
WHERE ST_Contains(m.the_geom, r.the_geom)
GROUP BY m.name
ORDER BY roads_km; name | roads_km
---------------------+------------------
サリー | 1539.47553551242
バンクーバー | 1450.33093486576
ラングレー地区 | 833.793392535662
バーナビー | 773.769091404338
プリンス・ジョージ | 694.37554369147
...ST_Covers — 1 つの円が別の円をカバーしているかどうかをテストする:
SELECT
ST_Covers(smallc, smallc) AS smallinsmall,
ST_Covers(smallc, bigc) AS smallcoversbig,
ST_Covers(bigc, ST_ExteriorRing(bigc)) AS bigcoversexterior,
ST_Contains(bigc, ST_ExteriorRing(bigc)) AS bigcontainsexterior
FROM (
SELECT
ST_Buffer(ST_GeomFromText('POINT(1 2)'), 10) AS smallc,
ST_Buffer(ST_GeomFromText('POINT(1 2)'), 20) AS bigc
) AS foo; smallinsmall | smallcoversbig | bigcoversexterior | bigcontainsexterior
--------------+----------------+-------------------+---------------------
t | f | t | f
(1 row)ST_Disjoint — 2 つのジオメトリが共有点を持たないかどうかをテストする:
SELECT ST_Disjoint('POINT(0 0)'::geometry, 'LINESTRING ( 2 0, 0 2 )'::geometry); st_disjoint
-------------
t
(1 row)SELECT ST_Disjoint('POINT(0 0)'::geometry, 'LINESTRING ( 0 0, 0 2 )'::geometry); st_disjoint
-------------
f
(1 row)ST_Overlaps、ST_Crosses、ST_Intersects、ST_Contains — ポイントとラインを比較する:
SELECT
ST_Overlaps(a, b) AS a_overlap_b,
ST_Crosses(a, b) AS a_crosses_b,
ST_Intersects(a, b) AS a_intersects_b,
ST_Contains(b, a) AS b_contains_a
FROM (
SELECT
ST_GeomFromText('POINT(1 0.5)') AS a,
ST_GeomFromText('LINESTRING(1 0, 1 1, 3 5)') AS b
) AS foo; a_overlap_b | a_crosses_b | a_intersects_b | b_contains_a
-------------+-------------+----------------+--------------
f | f | t | tST_Relate — 特定の DE-9IM パターンをテストする:
SELECT ST_Relate(
ST_GeometryFromText('POINT(1 2)'),
ST_Buffer(ST_GeometryFromText('POINT(1 2)'), 2),
'0FFFFF212'
); st_relate
-----------
tST_Touches — ジオメトリが境界点のみを共有しているかどうかをテストする:
SELECT ST_Touches('LINESTRING(0 0, 1 1, 0 2)'::geometry, 'POINT(1 1)'::geometry); st_touches
------------
f
(1 row)SELECT ST_Touches('LINESTRING(0 0, 1 1, 0 2)'::geometry, 'POINT(0 2)'::geometry); st_touches
------------
t
(1 row)ST_Within — バッファリングされた円の包含関係をテストする:
SELECT
ST_Within(smallc, smallc) AS smallinsmall,
ST_Within(smallc, bigc) AS smallinbig,
ST_Within(bigc, smallc) AS biginsmall,
ST_Within(ST_Union(smallc, bigc), bigc) AS unioninbig,
ST_Within(bigc, ST_Union(smallc, bigc)) AS biginunion,
ST_Equals(bigc, ST_Union(smallc, bigc)) AS bigisunion
FROM (
SELECT
ST_Buffer(ST_GeomFromText('POINT(50 50)'), 20) AS smallc,
ST_Buffer(ST_GeomFromText('POINT(50 50)'), 40) AS bigc
) AS foo; smallinsmall | smallinbig | biginsmall | unioninbig | biginunion | bigisunion
--------------+------------+------------+------------+------------+------------
t | t | f | t | t | t
(1 row)ジオメトリプロパティへのアクセス
ジオメトリがシンプルであるかどうかを確認する:
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)内部リング(交通円環)を持つ最大の都市を検索する:
SELECT gid, name, ST_Area(the_geom) AS area
FROM bc_municipality
WHERE ST_NRings(the_geom) > 1
ORDER BY area DESC
LIMIT 1; gid | name | area
-----+--------+------------------
12 | 安寧 | 257374619.430216
(1 row)拡張機能の削除
-- ganos_geometry 拡張機能およびすべての依存オブジェクトを削除します。
DROP EXTENSION ganos_geometry CASCADE;次のステップ
ジオメトリ SQL リファレンス — GanosBase Geometry 関数の完全な関数リファレンス
空間参照 — SRS および SRID 値の取り扱い方法