GanosBase Geometry は、PostgreSQL の空間ジオメトリ拡張です。GanosBase Geometry は OpenGIS 仕様に準拠し、PostgreSQL で 2D (X, Y)、3D (X, Y, Z)、4D (X, Y, Z, M) の空間ジオメトリデータを格納および管理できます。GanosBase Geometry は、空間ジオメトリオブジェクト、インデックス、関数、演算子などのさまざまな機能も提供します。
概要
ジオメトリモデルは PostGIS の操作と完全に互換性があり、既存のアプリケーションをスムーズに移行できます。
クイックスタート
拡張を作成します。
-- ジオメトリ拡張を作成します。 Create extension ganos_geometry with schema public cascade;重要GanosBase 拡張と PostGIS 拡張を同じスキーマ内に作成しないでください。作成すると、エラーメッセージ
ERROR: table "spatial_ref_sys" is not a member of the extension being createdが表示されます。GanosBase または PostGIS 拡張を作成すると、
spatial_ref_sysという名前のテーブルが自動的に作成されます。GanosBase 拡張と PostGIS 拡張を同じスキーマ内に作成すると、テーブル競合が発生します。GanosBase と PostGIS の拡張は、異なるスキーマに作成することを推奨します。GanosBase 拡張を作成する前に、PostGIS 拡張を削除することもできます。ジオメトリテーブルを作成します。
-- 方法 1:ジオメトリフィールドを含むテーブルを作成します。 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));ジオメトリデータをインポートします。
INSERT INTO roads (id, geom, road_name) VALUES (1,ST_GeomFromText('LINESTRING(191232 243118,191108 243242)',3857),'North Fifth-Ring Road'); INSERT INTO roads (id, geom, road_name) VALUES (2,ST_GeomFromText('LINESTRING(189141 244158,189265 244817)',3857),'East Fifth-Ring Road'); INSERT INTO roads (id, geom, road_name) VALUES (3,ST_GeomFromText('LINESTRING(192783 228138,192612 229814)',3857),'South Fifth-Ring Road'); INSERT INTO roads (id, geom, road_name) VALUES (4,ST_GeomFromText('LINESTRING(189412 252431,189631 259122)',3857),'West Fifth-Ring Road'); INSERT INTO roads (id, geom, road_name) VALUES (5,ST_GeomFromText('LINESTRING(190131 224148,190871 228134)',3857),'East Central Street'); INSERT INTO roads (id, geom, road_name) VALUES (6,ST_GeomFromText('LINESTRING(198231 263418,198213 268322)',3857),'West Central Street');ジオメトリオブジェクト情報をクエリします。
SELECT id, ST_AsText(geom) AS geom, road_name FROM roads; id | geom | road_name ----+-----------------------------------------+------------------------- 1 | LINESTRING(191232 243118,191108 243242) | North Fifth-Ring Road 2 | LINESTRING(189141 244158,189265 244817) | East Fifth-Ring Road 3 | LINESTRING(192783 228138,192612 229814) | South Fifth-Ring Road 4 | LINESTRING(189412 252431,189631 259122) | West Fifth-Ring Road 5 | LINESTRING(190131 224148,190871 228134) | East Central Street 6 | LINESTRING(198231 263418,198213 268322) | West Central Street (6 rows)インデックスを作成します。
-- GiST インデックスを作成します。 CREATE INDEX [indexname] ON [tablename] USING GIST ( [geometryfield] ); CREATE INDEX [indexname] ON [tablename] USING GIST ([geometryfield] gist_geometry_ops_nd); VACUUM ANALYZE [table_name] [(column_name)]; -- 例: Create INDEX sp_geom_index ON ROADS USING GIST(geom); VACUUM ANALYZE ROADS (geom); -- ブロックレンジインデックス (BRIN) を作成します。 CREATE INDEX [indexname] ON [tablename] USING BRIN ( [geometryfield] ); CREATE INDEX [indexname] ON [tablename] USING BRIN ([geometryfield] brin_geometry_inclusion_ops_3d); CREATE INDEX [indexname] ON [tablename] USING BRIN ([geometryfield] brin_geometry_inclusion_ops_4d); -- 指定した範囲の BRIN インデックスを作成します。 CREATE INDEX [indexname] ON [tablename] USING BRIN ( [geometryfield] ) WITH (pages_per_range = [number]);ジオメトリオブジェクトにアクセスします。
-- 空間ジオメトリオブジェクトが単純な要素のみで構成されているかどうかを判定します。 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 | Anning | 257374619.430216 (1 row)空間データを測定および分析し、空間関係を識別します。
-- bc_roads テーブルを作成します。 Create table bc_roads (gid serial, name varchar, the_geom geometry); -- bc_municipality テーブルを作成します。 Create table bc_municipality(gid serial, code integer, name varchar, the_geom geometry); -- 長さを計算します。 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 = 'PRINCE GEORGE'; hectares ------------------ 32657.9103824927 (1 row) -- 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 --------------------+------------------ SURREY | 1539.47553551242 VANCOUVER | 1450.33093486576 LANGLEY DISTRICT | 833.793392535662 BURNABY | 773.769091404338 PRINCE GEORGE | 694.37554369147 -- ST_Covers 関数を使用します。 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 関数を使用します。 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 関数を使用します。 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 | t (1 row) -- ST_Relate 関数を使用します。 SELECT ST_Relate(ST_GeometryFromText('POINT(1 2)'), ST_Buffer(ST_GeometryFromText('POINT(1 2)'),2), '0FFFFF212'); st_relate ----------- t (1 row) -- ST_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)拡張を削除します。
Drop extension ganos_geometry cascade;
SQL リファレンス
詳細については、「PostGIS 公式リファレンス」をご参照ください。