PostGIS Layers

提供: OSGeo.JP Wiki
2009年9月5日 (土) 03:18時点におけるYellow 73 (トーク | 投稿記録)による版

移動: 案内検索

PostGISレイヤは、PostgreSQLデータベースに格納されているものです。 PostGISの利点は、空間インデクス、フィルタリング、クエリの機能が提供されている点です。 PostGISを用いると、選択や識別といったベクタ機能が、QGISのOGRレイヤよりも精度良くなります。

PostGISレイヤを使うために必要なことは次の通りです。

  • QGIS内に、PostgreSQLデータベースに接続するための設定を保存します (まだひとつも設定されていない場合)。
  • データベースに接続します。
  • マップに追加するレイヤを選択します。
  • 必要なら、SQLのWHERE節でレイヤからどのフィーチャーをロードするかを定義します。
  • レイヤをロードします。

接続設定を保存する

PostGISデータソースを使うには、まずはじめに、 データを持っているPostgreSQLデータベースへの接続を作成する必要があります。 ツールバーの「Add PostGIS Layer」をクリックするか、 「レイヤ」メニューから「Add PostGIS Layer」を選択するか、「d」キーを押して下さい。 「Add Vector Layer」ダイアログを開いて、「データベース」を選択しても良いです。 「PostGIS テーブルを追加」というダイアログが表示されます。 接続マネージャにアクセスするには、 「新規」ボタンをクリックします。 「新規 PostGIS 接続を作成」ダイアログが表示されます。 接続に必要なパラメータを表1に示します。

表1: PostGIS接続パラメータ名
名称 この接続に付ける名前。データベース名と同じにすることができます。
ホスト データベースのホスト名。telnet接続を開いたり、pingを打ったりするのに使われるのと同じもので、名前解決可能でなくてはなりません。データベースがQGISと同じコンピュータ上にある場合は、'localhost'するだけです。
データベース データベース名。
ポート PostgreSQLデータベースサーバが待機しているポート番号。デフォルトでは5432になっています。
ユーザ名 データベースにログインするためのユーザ名。
パスワード Usernameでデータベースに接続する際に使われるパスワード
SSL mode SSL接続のサーバとのネゴシエート方法。次のオプションがあります。
 * disable: 非暗号化SSL接続のみ試みます。
 * allow: 非SSQL接続を試し、失敗した場合にSSL接続を試みます。
 * prefer (デフォルト): SSL接続をためし、失敗した場合に非SSL接続を試みます。
 * require: SSL接続のみ試みます。
 接続エディタでSSL接続を切るとPostGISレイヤのレンダリングが強力にスピードアップします。

必要なら、次に示すチェックボックスにチェックを入れることができます。

  • パスワード保存
  • Only look in the geometry_columns table
  • Only look in the 'public' schema

全てのパラメータとオプションを設定したら、「接続テスト」ボタンをクリックして接続のテストを行うことができます。

Tip 9 QGISユーザ設定とセキュリティ

ご自身のQGISの設定は、オペレーティングシステムに基づいて保存されます。 Linusでは、設定は.qt/qgisrc内のホームディレクトリにストアされます。 Windowsでは、レジストリに保存されます。 コンピュータ環境に依存して、QGIS設定内にパスワードを保存することはセキュリティリスクとなるかも知れません。

PostGIS レイヤのロード

ひとつ以上の接続設定を作成したら、PostgreSQLデータベースからレイヤをロードすることができます。 もちろん、PostgreSQLにデータが存在する必要があります。 データベースにデータをインポートすることについては #PostgreSQL へのデータのインポート をご覧下さい。

PostGISからレイヤをロードするには、次のステップを実行します。

  • 「PostGIS テーブルを追加」ダイアログをまだ開いていない場合は、ツールバーの「Add PostGIS Layer」をクリックします。
  • ドロップダウンから接続を選択して「接続」ボタンをクリックします。
  • 使用可能なレイヤの一覧から追加したいレイヤを探します。
  • 追加したいレイヤをクリックすると選択できます。Shiftキーを押しながらクリックすると複数レイヤの選択ができます。

クエリビルダ で、より踏み込んだレイヤ定義を行うために使われるPostgreSQLクエリビルダに関する情報を記述しています。

PostgreSQL レイヤに関する詳細

この節では、QGISがPostgreSQLレイヤにどのように接続するかの詳細に触れます。 ほとんどの場合は、QGISは、単純にデータベースのロード可能なテーブル一覧を提示し、求めに応じてロードします。 しかし、PostgreSQLテーブルをQGISにロードする時にトラブルが発生した場合、 この節の情報が、QGISのメッセージを理解する助けとなり、また、PostgreSQLテーブルの変更や、GISがロードできるビューの定義に関する方向性を得る助けとなります。

QGISには、一意のキーとして使用するカラムを持つPostgreSQLレイヤが必要です。 テーブルから見れば、テーブルにはプライマリキーまたは一意制限が課せられているカラムが求められる、という意味です。 QGISでは、このカラムには、int4(4バイト整数)型である必要があります。 もしくは、ctidカラム(訳注: 物理的な行位置が入っているシステムカラム) を主キーに使うことができます。 テーブルがこれらのアイテムを欠如させると、 oidカラム(訳注: 論理的識別子が入っているシステムカラム、PostgreSQL 8.1.0以降はデフォルトでは作成されなくなりました)が代わりに用いられます。 カラムにインデクスを作成すると実行速度が改善します(PostgreSQLでは主キーには自動的にインデクスが作成されます)。

PostgreSQLレイヤがビューの場合、同じ要件となりますが、 ビューに主キーや一意性制限が課せられたカラムはありません。 この場合、QGISは適切なテーブルカラムから派生したビューカラムを発見しようと試みます。 ビュー定義SQLの構文解析を行うことで実現しています。 しかし、QGISは、テーブル別名の使用やSQL関数で生成されたカラムなどといった、SQLのいくつかの面を無視します。

適切なカラムが見つからなかった場合は、QGISはレイヤをロードしません。 こうなった場合、ビュー定義の変更を行い適切なカラム(int4型で主キーか、一意性制限があるカラムであって、インデクスが作られていることが望ましい)を含ませることで解決します。

When dealing with views, QGIS parses the view definition and (ここで切れてます)

Tip 10 PostGISレイヤ

通常PostGISレイヤは、geometry_columnsテーブルのエントリに定義されています。 1.0.0版から、QGISはgeometry_columnsテーブル内にエントリが無いレイヤをロードすることができます。 これは、テーブルとビューの両方について言えます。 空間ビューの定義によって、データを強力に可視化する手段が供給されます。 ビューの生成についてはPostgreSQLマニュアルをご覧下さい。

PostgreSQL へのデータのインポート

shp2pgsql

データをPostgreSQLにインポートするには、いくつかの方法があります。 PostGISは、shp2pgsqlというシェープファイルをPostGISにインポートするためのユーティリティを持っています。 たとえば、lakes.shpという名前のシェープファイルを、gis_dataという名前のPostgreSQLデータベースにインポートするには、次のコマンドを使います。

  shp2pgsql -s 2964 lakes.shp lakes_new | psql gis_data

(訳注: これだと整数がint2型になり、また、空間インデクスが付加されませんので、shp2pgsqlに"-i"および"-I"オプションを付けるべきです)

これによって、lakes_newという名前の新しいレイヤがgis_dataデータベース内に作成されます。 新しいレイヤは空間参照識別子(SRID)は2964となります。 空間参照系と投影法に関する情報については、{Working with Projections}をご覧下さい。

Tip 11 PostGISからのデータセットのエクスポート

インポートツールのshp2pgsqlと同じような、 PostGISデータベースをシェープファイルにエクスポートするツールの pgsql2shp があります。 これは、PostGISのディストリビューションに同梱されています。

SPITプラグイン

SPIT (Shapefile to PostGIS Import Tools)という名前のプラグインがQGISにあります。 SPITは、一度に複数のシェープファイルをロードでき、スキーマのサポートもします。 SPITを使うには、「プラグイン」メニューからプラグインマネージャを開き、 SPITのチェックボックスにチェックを入れて、「OK」をクリックします。 SPITアイコンがツールバーに追加されます。

シェープファイルをインポートするには、ツールバーのSPITツールをクリックして、 「SPIT - Shapefile to PostGIS Import Tool」ダイアログを開きます。 接続したいPostGISデータベースを選択して「接続」をクリックします。 「追加」ボタンをクリックしてひとつまたは複数のファイルをキューに追加することができます。 「OK」のボタンをクリックするとファイルの処理が行われます。 エラー、警告やインポートの進行状況は、シェープファイルごとに表示されます。

Tip 12 PostgreSQL予約語を含むシェープファイルのインポート

PostgreSQLの予約語となるフィールド名を含むシェープファイルがキューに追加されている場合、 それぞれのフィールドの状態を表示するダイアログが現れます。

重要性の高いフィールド名を編集して、 予約後 (または求められる他のフィールド名を変更する)

予約語のフィールド名を持つシェープファイルをインポートしようとすると、失敗するでしょう。


ogr2ogr

shp2pgsqlとSPITの他にも、PostGISに地理データを送りこむツールがあります。 これはGDALに入っています。シェープファイルをPostGISにインポートするには、次のコマンドを実行します。

  ogr2ogr -f "PostgreSQL" PG:"dbname=postgis host=myhost.de user=postgres \
  password=topsecret" alaska.shp

これによって、alaska.shpというシェープファイルが、 postgresというユーザ名で、myhost.deというホストにある、postgis という PostGISデータベースにインポートされます。

OGRはPostgreSQLとともにビルドして、PostGISをサポートするようにしなければなりませんので、ご注意ください。 次のように入力して確認できます。

ogrinfo --formats | grep -i post

通常使われるINSERT INTOメソッドの替わりにPostgreSQLのCOPYコマンドを使いたい場合は、 次のような環境変数を設定して下さい。

  export PG_USE_COPY=YES

ogr2ogrでは、shp2pgsqlのように空間インデクスを生成しません。 インポート後の追加手順として、通常のSQLコマンドのCREATE INDEXを使って、手動で生成して下さい ({#性能の改善|次節}で記述します)。

性能の改善

PostgreSQLデータベースからフィーチャーを検索する際に、特にネットワーク経由の場合には、時間を浪費します。 空間インデクスがデータベース内のそれぞれのレイヤに生成するなら、 PostgreSQLレイヤの描画性能向上が改善できます。 PostGISは、空間データ検索の速度向上のために、GiST(Generalized Search Tree)の生成をサポートします。

GiST生成の構文は、次のようになります<ref>GiSTインデクスの情報は http://postgis.refractions.net にあるPostGISドキュメントから得ました。</ref>。

    CREATE INDEX [indexname] ON [tablename] 
      USING GIST ( [geometryfield] GIST_GEOMETRY_OPS );

大きなテーブルでは、インデクスの生成に時間がかかります。 インデクスを生成したら、VACUUM ANALYZEを実行すべきです。 詳細情報はPostGISドキュメントをご覧下さい。

次にGiSTインデクス生成の例を示します。

gsherman@madison:~/current$ psql gis_data
Welcome to psql 8.3.0, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
        \h for help with SQL commands
        \? for help with psql commands
        \g or terminate with semicolon to execute query
        \q to quit

gis_data=# CREATE INDEX sidx_alaska_lakes ON alaska_lakes
gis_data-# USING GIST (the_geom GIST_GEOMETRY_OPS);
CREATE INDEX
gis_data=# VACUUM ANALYZE alaska_lakes;
VACUUM
gis_data=# \q
gsherman@madison:~/current$


経度180度をまたぐベクタレイヤ

(PDFファイルには存在しません)

多くのGIS製品では、地理参照系(緯度/経度)で、経度180度をまたぐベクタ地図をラップできません。 QGISで開くと、お互いの位置は近いはずなのに二つの離れた別個の位置となります。 図8で、地図の左端にある小さい点(チャタム諸島)は、ニュージーランドの主たる島の右側のグリッド内にあるべきものです。

回避策は、PostGISのST_ShiftLongitude関数を使用して経度値を変換することです。 この関数はすべてのフィーチャーのすべての構成要素のすべてのポイント/バーテックスを読み込んで、経度 < 0 なら360を足すものです。 この処理の結果、180度を中心とした地図にプロットされた、0 - 360 版ができます。

[図: ST_ShiftLongitude関数を適用した後の経度180度を超えた地図]

使用法は次の通りです。

  • PostGIS ManagerプラグインやSPITプラグインを使うなどしてPostGISにデータをインポートします(PostGIS レイヤのロード参照)。
  • PostGISのコマンドラインインタフェースを使って、次のコマンドを実行します

(これは実際のテーブル名が"TABLE"であるとした場合の例です) gis_data=# update TABLE set the_geom=ST_shift_longitude(the_geom);

  • 全てうまくいけば、更新したフィーチャー数に関する確認情報を受信します。マップをロードして違いを見ることができます(図9)。