内容が古くなっている可能性がありますのでご注意下さい。
地理空間情報を活用したモバイルWebアプリケーションのサーバー環境構築の第2回では、地理空間情報を扱うためにPostgreSQLを拡張したPostGISをAzure上のCentOSにインストールします。
CentOSにPostGISをインストールする方法については、こちらのサイトを参考にします。
はじめに、yumリポジトリの設定を変更します。
/etc/yum.repos.d/CentOS-Base.repo ファイルの[base]セクションと[updates]セクションに
exclude=postgresql*
を追加します。さらに、以下のコマンドを実行して
# curl -O http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-centos93-9.3-1.noarch.rpm # rpm -ivh pgdg-centos93-9.3-1.noarch.rpm
リポジトリを追加します。EPEL 6リポジトリも必要ですが、前回既に追加してあるので省きます。
以下のコマンドでPostgreSQLとその拡張であるPostGISをインストールし、初期データベースを作成します。
# yum install postgresql93-server postgis2_93 # service postgresql-9.3 initdb
さらに
# service postgresql-9.3 start # chkconfig postgresql-9.3 on
PostgreSQLを起動し、システムの起動時にPostgreSQLも自動的に起動するよう設定します。
次に、地理空間情報用のデータベースを作成します。
# su - postgres
でpostgresユーザになり、
$ createdb postgis
postgisという名前のデータベースを作成します。
$ psql postgis
psqlコマンドでpostgisデータベースに接続し、
postgres=# CREATE EXTENSION postgis; postgres=# CREATE EXTENSION postgis_topology;
地理空間情報用の拡張機能をデータベースにインストールします。
ついでにpostgresユーザのパスワードを設定しておきます。
postgres=# alter role postgres password '■■■■';
psqlを終了し、rootユーザに戻り、
/var/lib/pgsql/9.3/data/pg_hba.conf ファイルの
local all all peer host all all 127.0.0.1/32 ident host all all ::1/128 ident
を
local all all md5 host all all 127.0.0.1/32 md5 host all all ::1/128 md5
と変更し、
# service postgresql-9.3 restart
PostgreSQLを再起動します。
次に、地理空間情報のテーブルを作成し、データを投入します。
用いるデータは、横浜オープンデータポータルで公開されている、応急給水拠点です。
ダウンロードしたXMLファイルから、以下のようなCSVファイルを作成しました。
配水池 恩田配水池 青葉区 榎が丘20 35.53907383 139.5113946 配水池 川井配水池 旭区 上川井2556 35.50028808 139.4903702 配水池 鶴ケ峰配水池 旭区 鶴ケ峰本町1197 35.48068913 139.5449766 配水池 中尾配水池 旭区 中尾町2-5 35.46891135 139.5211169 配水池 矢指配水池 旭区 矢指町1227 35.47799959 139.5078896
完全なCSVファイルはこちらにあります。元のXMLファイルのデータにあったNotes要素は省いています。
このデータを投入するためのwatersupplysitesテーブルはpsqlで以下のように定義します。
CREATE TABLE watersupplysites ( type character varying(50) NOT NULL, name character varying(50) NOT NULL, ward character varying(20), address character varying(100), latitude double precision, longitude double precision, geog geography, CONSTRAINT "PK_WaterSupplySite" PRIMARY KEY (type, name) );
geography型のカラムgeogは、CSVファイルにはないものです。
psqlで以下のコマンドを実行し、CSVファイルからテーブルにデータを投入します。
\copy watersupplysites(type, name, ward, address, latitude, longitude) from 'watersupplysites.csv';
さらに、以下のコマンドでgeogカラムにデータを投入します。
UPDATE watersupplysites SET geog = ST_Point(longitude, latitude);
数値型で入っている経度と緯度を、ST_Point()関数でgeography型に変換してgeogカラムに格納しています。
データの準備ができましたので、PostGISの空間関係関数を使用したクエリを実行してみます。
ST_DWithin(geography g1, geography g2, double precision d);
は、g1がg2からdメートル以内かどうかを判定します。
そこで、緑区総合庁舎(北緯35.51274191度、東経139.5377387度)から1,000メートル以内の応急給水拠点は以下のクエリで検索することができます。
SELECT name, type, ward FROM watersupplysites WHERE ST_DWithin(geog, ST_Point(139.5377387, 35.51274191), 1000);
実行すると、以下の結果が得られます。
距離を2,000メートルにすると、
件数が増え、緑区の隣の旭区にある応急給水拠点もヒットしました。