見出し画像

位置情報を可視化しよう![PostGIS入門]

最近のプロジェクトにて、Geo系データを扱うことがあり、一部の機能でPostGISを利用しました。PostGISはPostgreSQLの拡張機能として提供されており、SQLを書ければ利用できるため学習コストが低いと感じています。

用語解説
・PostgreSQL:オープンソースのRDBMS。象のマークでおなじみ
・GIS:Geographic Information Systemの略。地図を作るためのソフトウェアの総称
・PostGIS:PostgreSQL上でGISオブジェクトを利用できるようにした拡張機能

今後、Geo系データの利用は増えていく傾向がありそうですので、PostGISを利用したGeo系データの扱い方を紹介します。

PostGISのはじめかた

今回はDockerを使って環境を整えていきたいと思います。

①docker-composeファイルを用意する

version: '3.7'
services:
 postgis:
   image: mdillon/postgis:11
   container_name: postgis
   ports:
     - 5432:5432
   volumes:
     - ./docker/postgres/init.d:/docker-entrypoint-initdb.d
     - ./docker/postgres/pgdata:/var/lib/postgresql/data
   environment:
     POSTGRES_USER: root
     POSTGRES_PASSWORD: root
     POSTGRES_INITDB_ARGS: "--encoding=UTF-8"
   hostname: postgres
   restart: always
   user: root
 pgadmin4:
   image: dpage/pgadmin4
   container_name: pgadmin4
   ports:
     - 8000:80
   volumes:
     - ./docker/pgadmin4:/var/lib/pgadmin
   environment:
     PGADMIN_DEFAULT_EMAIL: root
     PGADMIN_DEFAULT_PASSWORD: root
   hostname: pgadmin4
   depends_on:
     - postgis
   restart: always

②コンテナを起動

docker-compose up -d

③PostGISをインストール

$ psql -h localhost -U root
$ CREATE EXTENSION IF NOT EXISTS postgis;

④テーブルを作成

CREATE TABLE geo_sample (
 id integer PRIMARY KEY,
 name varchar(255),
 geom geometry(POINT, 4326)
);

⑤データを投入

INSERT INTO geo_sample VALUES (1, '表参道駅', ST_GeomFromText('POINT(139.712288 35.664342)',4326));
INSERT INTO geo_sample VALUES (2, '青山一丁目駅', ST_GeomFromText('POINT(139.725146 35.672963)',4326));
INSERT INTO geo_sample VALUES (3, '赤坂駅', ST_GeomFromText('POINT(139.7365419 35.671949)',4326));

知っておきたいキーワード① geometry

PostGISのgeometry型では様々な形を表現することができます。geo_sampleテーブルに出てきた、点を表すPOINTの他にも、線を表すLINESTRINGや図形を表すPOLYGONがあります。また、それらを複合的に保持するMULTIタイプもあります。

スクリーンショット 2020-04-07 15.59.00

スクリーンショット 2020-04-07 15.59.06

画像はWikipediaより引用
https://ja.wikipedia.org/wiki/Well-known_text

知っておきたいキーワード② SRID

SRIDは空間参照系の識別コードです。PostGISにはSRIDが多数登録されているため、用途によって使い分けます。
4326(GPSで得られる位置)、3857(Open Street MapやGoogle MapsなどのWeb地図アプリケーションで利用)、2163(距離をメートルで測るときに利用)などがあります。地図上に描画する目的であれば4326を使えば大丈夫だと思います(この辺についてはあまり詳しくないです)。

知っておきたいキーワード③ WKT

geomety型のデータは、WKT(Well-known text)形式で保存されています。WKTはベクタ形式幾何学オブジェクトを投影法(地図)を基に変換し地図上に表現させるマークアップ言語です。緯度経度とWKTはPostGISの関数により相互に変換可能となっています。

例えば、表参道駅の緯度経度 "139.712288,35.664342"は
"0101000020E6100000AA2A3410CB766140FBAD9D2809D54140"
という形で保存されます。

pgAdminの使い方

PostGISの初期設定はコマンドで実行しましたが、geometry型のオブジェクトを参照する時にはpgAdminが便利です。pgAdminのコンテナも起動済みですので、 以下にアクセスして利用してください。

http://localhost:8000/

こんな感じで利用できます。SRIDは4326を使わないと地図上にマッピングできないので注意してください。

スクリーンショット 2020-04-07 16.11.46

POINTだけでなく、LINESTRINGやPOLYGONも描画可能です。

スクリーンショット 2020-04-07 16.13.27

POSTGISの使い方

ここからいくつか使い方をまとめていきます。その他のPostGISの関数についてはこちらをご参照ください。いくつかはサンプルSQL付きで紹介します。

SRIDを確認する / 変更する

SRIDを確認する:ST_SRID()

select id,name,ST_SRID(geom) from geo_sample;

スクリーンショット 2020-04-07 16.24.48

SRIDを変更する:ST_Transform()

select id,name,ST_SRID(geom),
ST_SRID(ST_Transform(geom,2163)) from geo_sample;

スクリーンショット 2020-04-07 16.27.45

Text to WKT / WKT to Text

WKT to Text:ST_AsText()

select 'ミクロネシア連邦大使館',
ST_AsText('0101000020E610000004BBAB68BD7761409013268C66D54140');

スクリーンショット 2020-04-07 16.29.16

Text to WKT:ST_GeomFromText()

select 'ミクロネシア連邦大使館',
ST_GeomFromText('SRID=4326;POINT(139.7418712 35.667192)');

スクリーンショット 2020-04-07 16.29.22

2点間の距離を求める: ST_Distance()

2点間の距離を求める:ST_Distance()  もしくは <->。<->の方が高速らしい。
SRIDには2163(米国ナショナルアトラス正積図法)を利用する。

select a.name || ' to ' || b.name,
ST_Distance(
 ST_Transform(a.geom, 2163),
 ST_Transform(b.geom, 2163))
from geo_sample a, geo_sample b
where a.name = '表参道駅' and b.name = '青山一丁目駅';

スクリーンショット 2020-04-07 16.32.16

ポリゴンに含まれているか判定する 

ポリゴンに含まれているか判定する:ST_Within() 。この辺りからgeo_sampleに含まれていないPOLYGONを利用するのでサンプルSQLはなしです。

スクリーンショット 2020-04-07 16.34.00

LINESTRINGの距離を求める

LINESTRINGの距離を求める:ST_Length()

スクリーンショット 2020-04-07 16.35.39

Polygonの面積を求める

Polygonの面積を求める:ST_Area()

スクリーンショット 2020-04-07 16.36.30

Polygonを結合する

Polygonを結合する:ST_Union()

スクリーンショット 2020-04-07 16.37.25

まとめ

PostGISの機能や使い方について紹介しました。SQLで操作できるため比較的簡単に使い始めることができます。Geo系のデータの利用は今後拡大していくと考えられますので、使えると便利な起動だと思います。

この記事が気に入ったらサポートをしてみませんか?