PostGIS クイックスタート¶
PostGISは、PostgreSQLリレーショナルデータベースに空間機能を追加します。PostgreSQLを拡張して、空間データを格納、問い合わせ、操作できるようにします。このクイックスタートでは、一般的なデータベース関数を記述する場合は 'PostgreSQL' を使用し、PostGISによって提供される追加の空間機能を記述する場合は 'PostGIS' を使用します。
このクイックスタートでは、次の方法について説明します:
コマンドラインと QGIS グラフィカルクライアントから空間データベースを作成し、クエリーを実行します。
pgAdmin
クライアントからデータを管理します。
目次
クライアント/サーバ・アーキテクチャ¶
PostgreSQLは、多くのデータベースと同様に、クライアント/サーバシステムのサーバとして機能します。クライアントはサーバーに要求を行い、応答を受け取ります。これは、インターネットが動作するのと同じ方法です。つまり、ブラウザがクライアントで、WebサーバはWebページを送り返します。PostgreSQLでは、要求はSQL言語で行われ、応答は通常データベースからのデータのテーブルです。
サーバがクライアントと同じコンピュータ上にあることを止めるものは何もありません。これにより、単一のマシン上でPostgreSQLを使用することができます。クライアントは、内部の 'ループバック' ネットワーク接続を介してサーバに接続し、そのように設定しない限り、他のコンピュータからは見えません。
空間的に有効なデータベースの作成¶
コマンドラインクライアントは、ターミナルエミュレータウィンドウから実行します。
「システムツール」メニューからターミナルエミュレータ(現在はLXTerminal)を起動します。これにより、Unixシェルのコマンドプロンプトが表示されます。以下を入力し:
psql -V
Enterを押してPostgreSQLのバージョン番号を確認します。
単一のPostgreSQLサーバでは、作業を別々のデータベースに整理することができます。各データベースは、独自のテーブル、ビュー、ユーザなどを持つ独立したシステムです。PostgreSQLサーバに接続する場合、データベースを指定する必要があります。
次のコマンドを使用すると、サーバ上のデータベースのリストを取得できます:
psql -l
. システム上の一部のプロジェクトで使用されている複数のデータベースが表示されます。このクイックスタート用に新しいものを作成します。
ちなみに
このリストでは標準的なUNIXのページャの使いかたを示します - スペースで次のページ、 b は戻る、 q は終了、h はヘルプを表示します。
PostgreSQLは、データベースを作成するためのユーティリティプログラム createdb
を提供します。PostGIS拡張を追加する前に、データベースを作成する必要があります。私たちのデータベースを demo
と呼びます。コマンドは次のようになります:
createdb demo
ちなみに
通常、コマンドラインツールのヘルプを表示するには、 --help
オプションを使います。
ここで psql -l
を実行すると、リストに demo
データベースが表示されます。PostGIS拡張はまだ追加されていませんが、次のセクションでその方法を学習します。
PostGISデータベースは、SQL言語を使用して作成できます。最初に dropdb
コマンドを使って作成したデータベースを削除し、次に psql
コマンドを使ってSQLコマンドインタプリタを取得します。
dropdb demo
psql -d postgres
これは postgres
と呼ばれるコアシステムデータベースに接続します。次に、SQLを入力して新しいデータベースを作成します。
postgres=# CREATE DATABASE demo;
postgres
データベースから新しい demo
データベースに接続を切り替えます。将来的には psql -d demo
で直接接続することもできますが、 psql
コマンドラインで切り替えるには、次のような便利な方法があります。
postgres=# \c demo
ちなみに
returnを押してもpsqlプロンプトが表示され続ける場合は、 CTRL + C を押します。入力がクリアされ、再び起動します。おそらく、閉じる引用符やセミコロンなどを待っているのでしょう。
情報メッセージが表示され、 demo
データベースに接続したことを示すプロンプトが表示されます。
次に、PostGIS拡張を追加します。
demo=# create extension postgis;
postgisがインストールされていることを確認するには、次のクエリを実行します:
demo=# SELECT postgis_version();
postgis_version
---------------------------------------
2.3 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
(1 row)
PostGISは、多くの関数、テーブル、および複数のビューをインストールします。
\dt
と入力し、データベース内のテーブルを一覧表示します。次のように表示されます。
demo=# \dt
List of relations
Schema | Name | Type | Owner
--------+------------------+-------+-------
public | spatial_ref_sys | table | user
(1 row)
spatial_ref_sys
テーブルは、PostGISが異なる空間参照システム間の変換に使用します。 spatial_ref_sys
テーブルには、有効な空間参照システムに関する情報が格納されています。SQLを使用して簡単に確認できます。
demo=# SELECT srid, auth_name, proj4text FROM spatial_ref_sys LIMIT 10;
srid | auth_name | proj4text
------+-----------+--------------------------------------
3819 | EPSG | +proj=longlat +ellps=bessel +towgs...
3821 | EPSG | +proj=longlat +ellps=aust_SA +no_d...
3824 | EPSG | +proj=longlat +ellps=GRS80 +towgs8...
3889 | EPSG | +proj=longlat +ellps=GRS80 +towgs8...
3906 | EPSG | +proj=longlat +ellps=bessel +no_de...
4001 | EPSG | +proj=longlat +ellps=airy +no_defs...
4002 | EPSG | +proj=longlat +a=6377340.189 +b=63...
4003 | EPSG | +proj=longlat +ellps=aust_SA +no_d...
4004 | EPSG | +proj=longlat +ellps=bessel +no_de...
4005 | EPSG | +proj=longlat +a=6377492.018 +b=63...
(10 rows)
これにより、空間的に有効なデータベースがあることが確認されます。
この表に加えて、データベースでpostgisを有効にしたときに作成されるいくつかのビューがあります。
\dv
と入力すると、データベース内のビューの一覧が表示されます。次のように表示されます。
demo=# \dv
List of relations
Schema | Name | Type | Owner
--------+-------------------+------+----------
public | geography_columns | view | postgres
public | geometry_columns | view | postgres
public | raster_columns | view | postgres
public | raster_overviews | view | postgres
(4 rows)
PostGISは、いくつかの空間データタイプをサポートしています:
geometry - データを平面に描かれたベクトルとして格納するデータ型です。
geography - 回転楕円面上に描かれたベクトルとしてデータを保存するデータ型です。
- raster - データをn次元の行列として格納するデータ型で、各位置(ピクセル)は
空間の領域を示し、各バンド(次元)は各ピクセル空間の値を持つ。
geometry_columns
と、geography_columns
、raster_columns
ビューは、PostGISのジオメトリ、地理、およびラスター列を持つテーブルをPostGIS に伝える役割をもっています。
概要(Overviews)は、ラスタデータの低解像度テーブルです。raster_overviews
このようなテーブルとそのラスタ列がリストされ、それぞれのテーブルが概要を示しています。ラスタ概要テーブルは、QGISなどのツールで使用され、ラスタデータの低解像度バージョンを提供して、読み込みを高速化します。
PostGISジオメトリタイプは、PostGISユーザが使用する最初の最も一般的なタイプです。そのタイプに注目してみましょう。
SQLを使用した空間テーブルの作成¶
これで空間データベースが完成し、空間テーブルを作成できるようになりました。
まず、都市データを保存するための通常のデータベーステーブルを作成します。このテーブルには3つのフィールドがあります。1つは都市を識別する数値ID用、1つは都市名用、もう1つはジオメトリ列用です。
demo=# CREATE TABLE cities ( id int4 primary key, name varchar(50), geom geometry(POINT,4326) );
従来、このジオメトリカラムには geom
という名前(古いPostGISでは the_geom
でした)を使います。これにより、PostGISに、各フィーチャが持つジオメトリの種類(ポイント、ライン、ポリゴンなど)、次元の数(この場合は2、次元が3または4の場合はPOINTZ、POINTM、またはPOINTZMを使用)、および空間参照システムが通知されます。私たちの都市には、EPSG:4326座標を使用しました。
citiesテーブルをチェックすると、新しい列が表示され、テーブルに現在行が含まれていないことが通知されます。
demo=# SELECT * from cities;
id | name | geom
----+------+----------
(0 rows)
テーブルに行を追加するには、いくつかのSQL文を使用します。ジオメトリ列にジオメトリを取得するには、PostGISの ST_GeomFromText
関数を使用して、座標と空間参照システムIDを与えるテキスト形式から変換します:
demo=# INSERT INTO cities (id, geom, name) VALUES (1,ST_GeomFromText('POINT(-0.1257 51.508)',4326),'London, England');
demo=# INSERT INTO cities (id, geom, name) VALUES (2,ST_GeomFromText('POINT(-81.233 42.983)',4326),'London, Ontario');
demo=# INSERT INTO cities (id, geom, name) VALUES (3,ST_GeomFromText('POINT(27.91162491 -33.01529)',4326),'East London,SA');
ちなみに
矢印キーを使用して、コマンドラインを呼び出したり編集します。
ご覧のように、これは非常に時間のかかる作業になります。幸いなことに、PostGISテーブルにデータを取り込む方法は他にもあり、その方がずっと簡単です。しかし今では3つの都市がデータベースに登録されています。
単純なクエリー¶
通常のすべてのSQL操作を適用して、PostGISテーブルからデータを選択できます。
demo=# SELECT * FROM cities;
id | name | geom
----+-----------------+----------------------------------------------------
1 | London, England | 0101000020E6100000BBB88D06F016C0BF1B2FDD2406C14940
2 | London, Ontario | 0101000020E6100000F4FDD478E94E54C0E7FBA9F1D27D4540
3 | East London,SA | 0101000020E610000040AB064060E93B4059FAD005F58140C0
(3 rows)
これにより、座標のエンコードされた16進数バージョンが得られますが、人間にとってはあまり有用ではありません。
ジオメトリを再びWKT形式で表示する場合は、関数ST_AsText(geom)またはST_AsEwkt(geom)を使用できます。ST_X(geom)、ST_Y(geom)を使用して、座標の数値を取得することもできます。
demo=# SELECT id, ST_AsText(geom), ST_AsEwkt(geom), ST_X(geom), ST_Y(geom) FROM cities;
id | st_astext | st_asewkt | st_x | st_y
----+------------------------------+----------------------------------------+-------------+-----------
1 | POINT(-0.1257 51.508) | SRID=4326;POINT(-0.1257 51.508) | -0.1257 | 51.508
2 | POINT(-81.233 42.983) | SRID=4326;POINT(-81.233 42.983) | -81.233 | 42.983
3 | POINT(27.91162491 -33.01529) | SRID=4326;POINT(27.91162491 -33.01529) | 27.91162491 | -33.01529
(3 rows)
空間クエリー¶
PostGISはPostgreSQLに空間機能を持つ多くの関数を追加します。WKTをジオメトリに変換するST_GeomFromTextについては、すでに説明しました。そのほとんどはST(空間タイプ)で始まり、PostGISドキュメントのセクションにリストされています。ここでは、球形の地球を仮定して、これら3つのロンドンの場所が互いにどのくらい離れているのかという現実的な疑問に答えるために1つを使うことにしましょう。
demo=# SELECT p1.name,p2.name,ST_DistanceSphere(p1.geom,p2.geom) FROM cities AS p1, cities AS p2 WHERE p1.id > p2.id;
name | name | st_distancesphere
-----------------+-----------------+--------------------
London, Ontario | London, England | 5875766.85191657
East London,SA | London, England | 9789646.96784908
East London,SA | London, Ontario | 13892160.9525778
(3 rows)
これにより、都市間の距離がメートル単位でわかります。SQL行の 'WHERE' 部分が、都市からそれ自体までの距離(すべて0)または上記の表の逆方向の距離(英国ロンドンからオンタリオロンドンまでは、オンタリオロンドンからイギリスロンドンまでと同じ距離)を取得するのを停止することに注意してください。 'WHERE' の部分を外して試してみて、何が起こるか見てください。
また、別の関数を使用し、回転楕円体の名前、半長軸、および逆平坦化パラメータを指定して、回転楕円体を使用して距離を計算することもできます。
demo=# SELECT p1.name,p2.name,ST_DistanceSpheroid(
p1.geom,p2.geom, 'SPHEROID["GRS_1980",6378137,298.257222]'
)
FROM cities AS p1, cities AS p2 WHERE p1.id > p2.id;
name | name | st_distancespheroid
-----------------+-----------------+----------------------
London, Ontario | London, England | 5892413.63776489
East London,SA | London, England | 9756842.65711931
East London,SA | London, Ontario | 13884149.4140698
(3 rows)
PostgreSQLコマンドラインを終了するには、次のように入力します。
\q
システムコンソールに戻ります:
user@osgeolive:~$
マッピング¶
PostGISデータからマップを作成するには、データを取得できるクライアントが必要です。QGIS、gvSIG、uDigなど、オープンソースのデスクトップGISプログラムのほとんどがこれを実行できます。では、QGISから地図を作る方法を説明しましょう。
デスクトップGISメニューからQGISを起動し、レイヤメニューから PostGISレイヤを追加
を選択します。PostGISでNatural Earthデータに接続するためのパラメータは、[接続]ドロップダウンメニューで既に定義されています。ここで新しいサーバ接続を定義し、簡単に呼び出せるように設定を保存できます。[接続]ドロップダウンメニューをクリックし、[Natural Earth]を選択します。これらのパラメータがNatural Earthのパラメータであることを確認するには、 [編集]
をクリックします。続行するには、 [接続]
をクリックします。
データベース内の空間テーブルのリストが表示されます:
ne_10m_lakesテーブルを選択し、一番下にある [追加]
をクリックします(データベース接続パラメータをロードする [読み込み]
をクリックするのではなく)。QGISにロードする必要があります。
これで湖の地図が表示されます。QGISはそれらが湖であることを知らないので、あなたのためにそれらを青にしないかもしれません - QGISドキュメントを参照して、これを変更する方法を調べてください。カナダの有名な湖のグループを拡大表示します。
空間データをデータベースに読み込む¶
ほとんどのOSGeoデスクトップツールには、他の形式(例 ESRI Shape)から空間データをデータベースに読み込むための機能があります。ここでもQGISを使って説明します
シェープファイルをQGISに読み込むには、QGISデータベースマネージャを使用します。マネージャーはメニューにあります。Database -> DB Manager
に移動します。
Postgisアイテムを展開し、次にNaturalEarthアイテムを展開します。その後、Natural Earthデータベースに接続します。パスワードを確認するメッセージが表示されたら、空白のままにします。パブリックアイテムには、データベースによって提供されるレイヤのリストがあります。メインマネージャウィンドウが表示されます。左側では、データベースからテーブルを選択し、右側のタブを使用してテーブルについて調べることができます。[プレビュー]タブに小さなマップが表示されます。
次に、DBマネージャを使用して、シェープファイルをデータベースにインポートします。ここでは、R Statistics Packageアドオンの1つに含まれているNorth Carolina Sudden Infant Death Syndrome(SIDS)データを使用します。
Table
メニューから Import layer/file
オプションを選択します。...
ボタンを押して、R ディレクトリにある sids.shp
シェープファイルを参照します。(/home/user/data/vector/R/shapes にあります):
他のものはすべてそのままにして、 Load
を押します。
座標参照系セレクタのデフォルト値を(WGS 84 EPSG:4326)にして、 OK
を押します。シェープファイルは、エラーなしでPostGISにインポートする必要があります。DB Manager を閉じて、メインの QGIS ウィンドウに戻ります。
次に、 'PostGISマップを追加' オプションを使用して、SIDSデータをレイヤにロードします。レイヤの再配置と若干の色付けを行うことで、North Carolinaの乳幼児突然死症候群の発生数 (sid74またはsid79フィールド)の階級区分図を作成できるようになります。
警告
利用中のOSGeoLiveのバージョン(ISO または VMDK)によっては、同じクライアントが利用できない場合があります。pgAdmin
はPostgreSQLの公式クライアントですが、技術的な理由でISOでは利用できないため、VMDK版でのみ利用可能です。ISO版には phpPgAdmin
クライアントがあり、同じコア機能を提供します。
phpPgAdminを知る (ISO & VMDK)¶
どちらのバージョンでも、グラフィカルなデータベースクライアントphpPgAdminを使用することができます。
phpPgAdminでは、SQLを使用してデータテーブルを操作することができます。OSGeoLiveのデスクトップにあるDatabasesフォルダからphpPgAdminを起動することができます。
ここでは、PostgreSQLサーバへの新しい接続を作成するか、既存のサーバに接続するかを選択できます。PostgreSQL
サーバーの赤い "X" は、まだ接続されていないことを意味します。クリックしてユーザ名 user
とマスタパスワード user
を入力します。
接続が確立されると、システムにすでに存在するデータベースの一覧が表示されます。
この時点では、システム上の既存のデータベースしか表示できません。データベース名の左にあるプラス記号をクリックすると、接続することができます。データベース natural_earth2
に対して実行してみましょう。
このデータベースには public
という名前のスキーマが一つだけ存在することが分かります。Tables
の左側にあるプラスをクリックして展開すると、このスキーマに含まれるすべてのテーブルを見ることができます。
phpPgAdminからのSQLクエリの実行 (ISO & VMDK)¶
phpPgAdminは、リレーショナルデータベースへのクエリを実行する機能を提供します。
データベースにクエリを実行するには、 natural_earth2
データベースをクリックして戻り、メインツールバーの SQL
ボタン (左側のデータベースシンボルのあるボタン) を押します。
各都市の1974年の乳幼児突然死症候群の発生率を求めます。さらに、計算されたレートに基づいて結果を並べ替えます。そのためには、次のクエリを実行する必要があります(SQLウィンドウのテキストエディタで送信)。
select name, 1000*sid74/bir74 as rate from sids order by rate;
その後、実行ボタンを押します。
pgAdminを知る (VMDKのみ)¶
「データベース」メニューからグラフィカルデータベースクライアント pgAdmin
を使って、非空間的にデータベースのクエリと変更を行うことができます。これはPostgreSQLの公式クライアントです。
pgAdminでは、SQLを使用してデータテーブルを操作できます。pgAdminは、OSGeoLiveのデスクトップにあるDatabasesフォルダから検索して起動できます。
マスターパスワードは user
です。
ここでは、PostgreSQLサーバへの新しい接続を作成するか、既存のサーバに接続するかを選択できます。この場合、あらかじめ定義された localhost
サーバに接続します。
接続が確立されると、システムにすでに存在するデータベースの一覧が表示されます。
ほとんどのデータベースのイメージ上の赤い "X" は、まだどのデータベースにも接続していないことを示しています(あなたはデフォルトの postgres
データベースにのみ接続しています)。この時点では、システム上の既存のデータベースしか表示できません。データベースの名前をダブルクリックすることで接続できます。データベース natural_earth2
に対して実行してみましょう。
赤いXが消え、左側に ">" が表示されています。これを押すとツリーが表示され、データベースの内容が表示されます。
schemas
サブツリーに移動して展開します。その後、public
スキーマを展開します。 Tables
を移動して展開すると、このスキーマに含まれるすべてのテーブルを表示できます。
pgAdminからのSQLクエリの実行 (VMDKのみ)¶
pgAdminは、リレーショナルデータベースに対してクエリを実行する機能を提供します。
データベースに対してクエリを実行するには、メインツールバーの Query Tool
ボタン(左側にデータベースシンボルがある)を押す必要があります。
各都市の1974年の乳幼児突然死症候群の発生率を求めます。さらに、計算されたレートに基づいて結果を並べ替えます。そのためには、次のクエリを実行する必要があります(SQLウィンドウのテキストエディタで送信)。
select name, 1000*sid74/bir74 as rate from sids order by rate;
その後、右向きの矢印(実行)ボタンを押す必要があります。
外部データラッパー(FDW)について知る¶
データベースから、他のPostgreSQLデータベースからテーブルなどのリモートオブジェクトにアクセスしたり、Oracle、MySQL、MS SQL、CouchDBなどのリモートデータベースに接続したりできます。ODBC経由で接続したり、CSVや地理空間データに接続したり、Twitterに接続することもできます。
異なるFDWの一覧は次の場所にあります。
動作の仕組みを見てみましょう。異なるPostgreSQLデータベースに接続するのが一番簡単でしょう。
次の手順に従います。
最初に、使用する外部データラッパーの拡張機能をロードします。異なるPostgreSQLデータベースへの接続には、 postgres_fdw
が必要です。
CREATE EXTENSION postgres_fdw;
接続するデータソースの場所を通知する外部サーバーを作成
CREATE SERVER fdw_pg_server_osm_local
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host '127.0.0.1', port '5432', dbname 'osm_local');
外部サーバに接続するときに使用するユーザを定義
CREATE USER MAPPING FOR user
SERVER fdw_pg_server_osm_local
OPTIONS (user 'user', password 'user');
これで、外部テーブルを作成できます。
IMPORT FOREIGN SCHEMA public
LIMIT TO (planet_osm_polygon, planet_osm_point) -- or EXCEPT
FROM SERVER fdw_pg_server_osm_local
INTO public;
データベース内の新しいテーブルを検索し、外部テーブルのデータを参照します。
Select * from planet_osm_polygon limit 10;
ogr_fdw経由でリモートOGRデータソースに接続¶
拡張 ogr_fdw
は、KML、GeoPackage、WFS、GeoJSON、GPX、GMLなどのいくつかの地理データフォーマットの接続を可能にします。
ogr_fdw
の詳細:
拡張機能 ogr_fdw
をデータベースにインストールします。
データベースプロンプトで、次のように入力します。
CREATE EXTENSION ogr_fdw;
サポートされているフォーマットを確認:
端末を開き、ogr_fdw_infoを検索します:
locate ogr_fdw_info
/usr/lib/postgresql/10/bin/ogr_fdw_info -f
結果は次のようになります:
Supported Formats:
-> "OGR_GRASS" (readonly)
-> "PCIDSK" (read/write)
-> "netCDF" (read/write)
-> "JP2OpenJPEG" (readonly)
-> "PDF" (read/write)
-> "MBTiles" (read/write)
-> "EEDA" (readonly)
-> "ESRI Shapefile" (read/write)
-> "MapInfo File" (read/write)
.... many more
WFSへのFDWの作成
からGeoServerを起動します。
GeoServerを開く http://localhost:8082/geoserver/web/
GeoServer WFS GetCapabilities http://localhost:8082/geoserver/ows?service=wfs&version=2.0.0&request=GetCapabilities
GeoServer WFS DescribeFeatureType - topp:states http://localhost:8082/geoserver/ows?service=wfs&version=2.0.0&request=DescribeFeatureType&typename=topp:states
GeoServer WFS GetFeature - topp:states http://localhost:8082/geoserver/ows?service=wfs&version=2.0.0&request=GetFeature&typename=topp:states
接続するWFSを参照する外部サーバーを作成する
CREATE SERVER fdw_ogr_server_wfs
FOREIGN DATA WRAPPER ogr_fdw
OPTIONS ( datasource 'WFS:http://localhost:8082/geoserver/ows', format 'WFS' );
1つのコマンドで、すべてのWFS地物_タイプを外部テーブルとしてインポートします。
インポート後、スキーマに新しい外部テーブルがいくつか表示されます。
IMPORT FOREIGN SCHEMA ogr_all
FROM SERVER fdw_ogr_server_wfs
INTO public;
外部データテーブルを確認 topp_states
:
SELECT * FROM topp_states WHERE state_name = 'Minnesota';
試してみること¶
次に、試すべき追加の課題をいくつか示します。
st_buffer(geom)
,st_transform(geom,25831)
,st_x(geom)
- のようないくつかの空間関数を試してください。完全なドキュメントは http://postgis.net/documentation/コマンドラインで
pgsql2shp
を使用して、テーブルをシェープファイルにエクスポートします。データベースにデータをインポート/エクスポートするには、コマンドラインで
ogr2ogr
を試してください。コマンドラインで
shp2pgsql
を使用して、データベースにデータをインポートしてみてください。pgRouting を使用して、道路のルーティングを試みます。
次のステップは何?¶
これは、PostGISを使用するための最初のステップです。他にも多くの機能を試すことができます。
PostGISプロジェクトホーム - http://postgis.net
PostGISドキュメント - http://postgis.net/documentation/