40. • ST_setSRID()は空間参照系のメタ情報を付与するだけ。投影変換(座標変換)はされません
• ジオメトリ型にINSERT/UPDATEするときは自動的に投影変換されない
• 別の空間参照系に変換するにはST_Transform()を使う
• 平面直角座標系もPostGISではPOINT(東西(X) 南北(Y))。
生データを扱うときは気をつけましょう
• GPSログをラインにしたいときは・・・
変換のポイント
SELECT
gps_track,
ST_MakeLine(gps.geom ORDER BY gps_time) geom
FROM gps_points
GROUP BY gps_track;
FOSS4G 2014 Tokyo PostGIS入門40
43. PostGISを利用することにより、データベースで行える通常の属性検索に加えて、豊富な空間検索が利
用できます。
• 属性により千葉市の各区を検索し、面積を計算する
SELECT n03_003, n03_004, n03_007,
ST_Area(ST_Transform(geom, 2446)),
ST_Area(ST_Transform(geom, 32654))
FROM polygon_adm
WHERE n03_003 = '千葉市';
2446:平面直角(9)
32654:UTM54
• 千葉市内の郵便局を区毎に数える(図形的に)
PostGISの検索機能
SELECT
n03_004,
count(*)
FROM polygon_adm a, point_public p
WHERE n03_003 = '千葉市'
郵便局:p02_002 = '18'
AND st_contains(a.geom, p.geom)
AND p.p02_002 = '18'
GROUP BY n03_004
st_contains(a, b)
aがbを完全に含むならTRUE
FOSS4G 2014 Tokyo PostGIS入門43
44. 空間インデックスの有無による検索速度を体験してみます
1. ○○市にある福祉施設をカウント
SELECT count(*)
FROM polygon_adm a, point_public p
WHERE n03_004 like '%市' AND st_contains(a.geom, p.geom) AND p.p02_002 = '19'
2. 空間インデックスを削除
DROP INDEX point_public_geom_gist;
DROP INDEX polygon_adm_geom_gist;
3. ふたたび1.で検索すると遅くなっているはず
4. 空間インデックスを再作成
空間インデックスの効果を体験する
CREATE INDEX point_public_geom_gist ON point_public USING GiST (geom);
CREATE INDEX polygon_adm_geom_gist ON polygon_adm USING GiST (geom);
5. ふたたび1.で検索する
6. 1.のSELECTの前にEXPLAIN句をつけて、2.~5.を実行してみる
EXPLAIN SELECT count(*)
FROM polygon_adm a, point_public p
WHERE n03_004 like '%市' AND st_contains(a.geom, p.geom) AND p.p02_002 = '19'
FOSS4G 2014 Tokyo PostGIS入門44
46. • 図形を合成してみます。このSQLそれぞれ結果が1件のみになります(合成の結果)
SELECT n03_003, ST_Collect(geom)
FROM polygon_adm
WHERE n03_003 = '千葉市'
GROUP BY n03_003;
集合条件の指定
• ST_Collect()とST_Union()の違い
図形の集合
SELECT n03_003, ST_Union(geom)
FROM polygon_adm
WHERE n03_003 = '千葉市'
GROUP BY n03_003;
CREATE VIEW collect_polygon as
SELECT max(id) id, ST_Collect(geom)
FROM sample_polygon;
CREATE VIEW union_polygon as
SELECT max(id) id, ST_Union(geom)
FROM sample_polygon;
重複部の座標はそのまま重複部の座標は無くなる
FOSS4G 2014 Tokyo PostGIS入門46
47. 図形の切り出し
ある領域に含まれる部分だけを切り出してみます
• 千葉市の行政界線で道路を切り出します
1. line_roadテーブルは行政界で分割されているので、路線毎にマージされた作業用テーブルを作成
します。
CREATE TABLE union_road AS
SELECT
定型文として覚えておくと便利
ジオメトリが、シンプル→マルチ→マルチ→シンプルと変換される
n01_002 roadname,
(ST_Dump(ST_LineMerge(ST_Union(geom)))).Geom geom
FROM line_road
GROUP BY n01_002;
空間インデックスも忘れずに
CREATE INDEX union_line_geom_gist ON union_road USING GiST (geom);
2. ジオメトリ間の共有部分を求めるビュー(テーブル)を作成し、Shapefileにエクスポートします。
CREATE VIEW chiba_road AS
SELECT
l.roadname, p.n03_004,
ST_Intersection(p.geom, l.geom) geom
FROM polygon_adm p, union_road l
WHERE St_Intersects(p.geom, l.geom)
AND n03_003 = '千葉市';
QGISでこのViewを参照すると
エラーになってしまう・・・
FOSS4G 2014 Tokyo PostGIS入門47