PostGIS、MapServer、OpenLayersを使って、Google Mapと自前の位置情報を重ね合わせてブラウザに表示する

PostgreSQLにPostGISを使って位置情報を入出力する。

MapServerは、PostgreSQLにアクセスして情報を取得、WEBへサービスする。

OpenLayersは、MapServerにアクセスして情報を取得、ブラウザ上に地図を描画する。

 

で、ここにいろいろと情報を載っけられるようにして行こうということで、とりあえずGoogle Mapの表示とPostGISに格納した自前の位置情報を重ね合わせるサーバをたててみる。

  1. 前提(インストール済み)
    • Ubuntu 10.10
    • Apache2
    • PostgreSQL 8.4
  2. インストールするパッケージ名
    • postgis (proj, geos, gdal)
    • postgresql-8.4-postgis (Ubuntu 10.10から。10.04だと8.3用しかない。)
    • cgi-mapserver
    • mapserver-bin
  3. 手動でダウンロード&設置するもの
    • OpenLayers
      http://openlayers.org/download/ からダウンロードする。
      現在(2010/11/05)のバージョンは2.10。
      ApacheのDocumentRoot(/var/www/)とか、お好きなところに展開、設置。
  4. PostGISの設定
    • PostgreSQLにテンプレートDBを作成する
      createdb template_postgis -E UTF-8
      createlang plpgsql template_postgis
      psql template_postgis -f /usr/share/postgresql/8.4/contrib/postgis.sql
      psql template_postgis -f /usr/share/postgresql/8.4/contrib/spatial_ref_sys.sql
      createdb -T template_postgis (データベース名)
      createuser (Apache実行ユーザ)
    • SQLを実行して確認
      select * from postgis_version();
                  postgis_version            
      ---------------------------------------
       1.5 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
      PostGISのバージョンが1.5で、GEOS、PROJが使用されていることが確認できる。
      ※参考 http://lets.postgresql.jp/documents/tutorial/PostGIS/1/
  5. 自前の地図情報をPostGISを使ってPostgreSQLにデータを入れる
    • 自前のデータを用意する
      サンプルとして植生のデータをダウンロードしてくる。
      http://www.vegetation.jp/
      ー>植生図を見る(全国)
      ->植生図をみる(地域)
      ->2次メッシュを選択
      ->2次メッシュ情報
      ->植生図GISデータ(シェープファイル)
      ->同意してダウンロード
      ->zipファイルがダウンロードされる
      ー>解凍した中の.shpファイルを利用するよ。
    • shpファイルからSQLファイルを作成する
      shp2pgsql -s 4612 -D -i -I -W (shpファイルの文字コード) (shpファイルパス) (テーブル名) > (SQLファイルパス)
      shpファイルの文字コードは、shpファイルを配布しているところで仕様を確認する。
      前述の植生図の場合はShift-JIS。Shift-JISの場合、cp932を指定したほうが無難とか。

      以下引用そのまま
      標準出力に出てきますので、リダイレクトして下さい。
      -Dはダンプ形式にするためのものです(これが無い場合はINSERT文が並べられ、叩き込むのに時間がかかります)。
      -iは整数を32ビットにするためのものです(これが無い場合は16ビットにされます)。
      -Iは作成されるGEOMETRY型カラムに空間インデックスを貼るSQL(CREATE INDEX)を生成するためのものです。
      -W cp932 は、シェープファイルの文字コードを指定します。なおShiftJISでなくcp932とする方が無難です。
      -s 4612 は「おまじない」です。(srid?座標系?要勉強ww)
    • データをPostgreSQLに入れる
      psql (データベース名) -f (SQLファイルパス)
    • テーブルアクセス権限付与
      GRANT SELECT ON (テーブル名) TO (ユーザ名);
  6. MapServerの設定
    • Apacheの設定
      /usr/lib/cgi-bin/mapserv にMapServerのCGIがインストールされているので、Apacheから実行できるようしておく。

      http://localhost/cgi-bin/mapserv をブラウザで開いてみて、
      No query information to decode. QUERY_STRING is set, but empty.
      とか表示されればOK。
    • Google Map向けの設定
      Google Mapで使われている投影(測地系)を設定する。
      /usr/share/proj/esri.extra の最後に記述してある、google用の設定(<900913>〜)を
      /usr/share/proj/epsg にコピペで追記する。
      参考 http://shigekun.blog.so-net.ne.jp/2009-04-10-1
    • 自前の地図情報用のMapファイルを作成する
      eda.map

      フォントの設定ファイル指定
         FONTSET "./fonts.txt" # フォント用ファイル
      fonts.txt

      PostGISで接続するための設定
          LAYER
            NAME "main"
            CONNECTIONTYPE POSTGIS
            CONNECTION "host=localhost user=(ユーザ名) password=(パスワード) dbname=(データベース名)"
            DATA "the_geom FROM (テーブル名)"
      ・・・・・

      Google Mapの上に重ねるので透過させるための設定
      TRANSPARENT on (3箇所www)

      Google Mapに座標系を揃えるための設定
         WEB
            METADATA
          WMS_SRS "EPSG:4326 EPSG:900913"
            END
         END

      Mapファイルのリファレンス
      http://mapserver.org/mapfile/map.html
    • Mapファイルの設置
      MapServerのCGI(mapserv)から読めるところにあればどこでもいいのだが、httpでmapservを呼ぶときにMapファイルのパスを指定することになるので、見られても構わないようにすること。

      mapservと同じディレクトリにシンボリックリンクを貼るとか
      ln -s (マップファイルの設置場所) (mapservと同じディレクトリ)/mapfiles

      ・・・測地系?座標系?よくわかってねぇwwww 勉強しなきゃだねwwww
      参考 http://bubble.atnifty.com/modules/bwiki/
  7. MapServer用ライブラリの言語別パッケージいろいろ(自分でMapServerアプリを作るときにお好みで)
    • perl-mapscript
    • php-mapscript
    • python-mapscript
    • libmapscript-ruby
  8. OpenLayersで表示してみる
    • Google Map(API v3)と自前の地図情報を重ねて表示してみる
      OpenLayersサンプル
      HTMLとJavaScriptのソースを見てね

      ベースに各種Google Mapを選択式で設定する。
      行22 // allOverlays: true, 
      マップをすべて重ねる(ベースなしにする)ための設定

      Google Mapの座標系変換とベースの指定
      行31  {"sphericalMercator": true, isBaseLayer: true}
      行35、39、43も同様

      自前の地図情報を重ねる設定
      行47〜51
      var wms = new OpenLayers.Layer.WMS( "eda",
      "http://recitativo-fant.asia/cgi-bin/mapserv?map=mapfiles/eda.map&SERVICE=WMS&VERSION=1.1.1&",
      {layers: "main", transparent: true},
      {isBaseLayer: false, visibility: true, opacity: 0.5, gutter: 15}
      );
      行47 OpenLayersで表示するレイヤ名
      行48 MapServerの呼び出し(Mapファイルのパス指定)
      行49 Mapファイルにしていしたレイヤ名、透過指定
      行50 ベース指定

      下記にサンプルがいっぱいあるのでのぞいてみると良いですな。
      http://openlayers.org/dev/examples/
      Google Mapのサンプルを参考にする場合は、API v3を見ると良いです。
      v2はキーが必要になり、そのままコピーして利用すると「キーを取得しろ」とかダイアログが表示されて、表示が遅延するため、一番上に表示されて、OpenLayersの地図操作コントロールが下になってしまったりする。