OpenStreetMapデータを使って地図サーバを構築してみた

みなさんはOpenStreetMapをご存知ですか?
私は今まで実際に使ったことはなかったのですが、先日日本語版の利用者ガイドがリリースされたのでとりあえず目を通してみると、どうもOpenStreetMapデータを使って自前で地図サーバを公開できるという記載があったので試しにやってみたところ、いくつかマニュアル通りにはいかない部分があったものの構築に成功したので記事にしてみました。

今回参考にしたのは「OpenStreetMap 利用者ガイド(v1.0)の「あなたのウェブサイトでマップを提供する」(P.105)です。

「システム要件」

「一般的には、要件は10-20GBのストレージで4GBのメモリ、都市サイズの地域用には最近のデュアルコアプロセッサーを300GB超の高速ストレージに、24GBのメモリ、そして全世界用にはクアッドコアプロセッサー、といった範囲になります」

とありますが、全世界用のデータや日本全国だと大変そうですが例えば埼玉に限ったデータであれば一般的なマシンでなんとかなりそうだと思ったので、以下の仮想OSを作成しました。

  • Ubuntu 12.04 LTS (利用者ガイドでは10.04)
  • メモリ2GB、HDD15GB程度
  • mini.isoでインストールしてssh ServerとXbuntu Desktopだけ選択 ※これは個人的な趣味

で、OSセットアップ完了後に利用者ガイドを見ながら作業を進めます。

「最新のOpenStreetMapデータを取得する」

おや?はやくも危険な香りが…

「http://planet.openstreetmap.org/ からOpenStreetMapデータを少しだけ参照します。planet全体では圧縮して18GBあるため、このページには小さな国や州サイズに抽出されたものへのリンクがあります。取り扱うのに小さくて早いので、できればPBFファイル形式が望ましいです。この場合、我々は次のコマンドを発行してplanetファイル全体をダウンロードします」

ということでこのまま利用者ガイド通りに続けると圧縮状態で18GBという巨大なデータを取得してしまうので、「CloudMade」から欲しいデータを取得します。今回は埼玉のデータがほしいので

wget http://downloads.cloudmade.com/asia/eastern_asia/japan/saitama/saitama.osm.bz2

というように欲しいデータを指定して取得します。※もちろん埼玉以外にも取れます。

「PostgreSQL データベースをインストールして構成設定」

利用者ガイドではPostgreSLは8.4となっていますが現時点(2012/5/16)では9.1が最新なので最新を入れてみます。

sudo apt-get install postgresql-9.1-postgis postgresql-contrib-9.1 postgresql-server-dev-9.1 build-essential libxml2-dev libtool libgeos-dev libpq-dev libbz2-dev proj

また、利用者ガイドではPostgresの認証設定を変更していませんが、私の環境では最後の「renderd」で接続問題が発生したのでを変更しておきます。

vi /etc/postgresql/9.1/main/pg_hba.conf
# "local" is for Unix domain socket connections only
local all all trust

「OpenStreetMap データをデータベースにロードする」

git clone git://github.com/openstreetmap/osm2pgsql.git

※2013/5/10 リポジトリが変更になったようです。(xDさん、ありがとうございました。)

※apt-getでも「osm2pgsql」はインストールできますが、現時点(2012/5/16)ではバージョンが異なるため、今後の作業で失敗します。面倒ですがソースをビルドしましょう。

なお、都道府県単位でOpenStreetMapデータをPostGISに投入するのには10分もかかりませんでした(ホストPCはCorei5)。

「mapnikライブラリのインストール」

まず依存関係のインストールで指定したboost関連のバージョンが古いと怒られ上にソースがsvnからgithubに移動しており、さらにバージョンが変わって色々とビルド手順が変わっています。

sudo apt-get install libltdl3-dev libpng12-dev libtiff4-dev libicu-dev python-cairo-dev python-nose libboost-dev libboost-filesystem-dev libboost-iostreams-dev libboost-regex-dev libboost-thread-dev libboost-program-options-dev libboost-python-dev libfreetype6-dev libcairo2-dev libcairomm-1.0-dev libgeotiff-dev libtiff4 libtiff4-dev libtiffxx0c2 libsigc++-dev libsigc++0c2 libsigx-2.0-2 libsigx-2.0-dev libgdal1-dev python-gdal imagemagick ttf-dejavu
cd src
wget https://github.com/downloads/mapnik/mapnik/mapnik-v2.0.1.tar.bz2
tar jxvf mapnik-v2.0.1.tar.bz2
cd mapnik-v2.0.1/
./configure
make
sudo make install

「Mapnikツールのインストール」

再びsvnのURLが切れてますが、慌てず正しいURLを入れましょう。

svn co http://svn.openstreetmap.org/applications/rendering/mapnik/

ツール自体はPythonスクリプトですが、Mapnikのバージョンの違うのか依存ライブラリが足らないと怒られたので以下も入れます。

sudo apt-get install python-setuptools libxslt-dev
sudo easy_install lxml

Mapnikのバージョンが上がってしまったのでアップグレード手順が増えますが、以下手順でimage.pngが生成されます。

./generate_xml.py --dbname データベース名 --user DBユーザ名 --accept-none
upgrade_map_xml.py osm.xml osm-mapnik2.xml
./generate_image.py

「Apache ウェブサーバと mod_tileのインストールと構成」

mod_tileのsvnのURLが切れてますので迷うことなく正しいURLを入れましょう。
そしてビルド方法も異なるのですが以下手順でビルドできます。

svn co http://svn.openstreetmap.org/applications/utils/mod_tile
cd mod_tile
./autogen.sh
./configure
make
sudo make install
sudo make install-mod_tile
sudo ldconfig

「/etc/renderd.conf」も確か/etcにはコピーされなかった気がするので存在しない場合は「mod_tile/」にあるファイルをコピーしましょう。
最後にrenderdを起動するときは最初はforegroundで起動したほうが問題発生時にわかりやすいので以下オプション付きで起動しましょう

sudo renderd -f

利用者ガイドの記載の通り、「http://localhost/osm_tiles2/0/0/0.png」で地図画像が表示され、renderdも気になるようなエラーを吐いていないようならば成功です。

OpenLayersで表示してみる

これは利用者ガイドにのっていませんが、本家のWikiに載っていたのでやってみたところ動いたので載せておきます。
Apacheで参照できるところに以下のHTMLを作成します。私はドキュメントルートに「/var/www/map.html」として作成しました。

<html>
  <head>
    <title>OpenLayers Demo</title>
    <style type="text/css">
      html, body, #basicMap {
          width: 100%;
          height: 100%;
          margin: 0;
      }
    </style>
    <script src="http://www.openlayers.org/api/OpenLayers.js"></script>
    <script>
      function init() {
           var options = {
                projection: new OpenLayers.Projection("EPSG:900913"),
                displayProjection: new OpenLayers.Projection("EPSG:4326"),
                units: "m",
                maxResolution: 156543.0339,
                maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34,
                                                 20037508.34, 20037508.34),
                numZoomLevels: 20,
                controls: [
                        new OpenLayers.Control.Navigation(),
                        new OpenLayers.Control.PanZoomBar(),
                        new OpenLayers.Control.Permalink(),
                        new OpenLayers.Control.ScaleLine(),
                        new OpenLayers.Control.MousePosition(),
                        new OpenLayers.Control.KeyboardDefaults()

                  ]
            };
        map = new OpenLayers.Map("basicMap",options);
        var newL = new OpenLayers.Layer.OSM("Default", "/osm_tiles2/${z}/${x}/${y}.png", {numZoomLevels: 19});
        map.addLayer(newL);
        map.zoomIn();
      }
    </script>
  </head>
  <body onload="init();">
    <div id="basicMap"></div>
  </body>
</html>

「http://localhost/map.html」にアクセスすると世界地図が表示され左上のコントローラで地図を操作できます。

初回(まだ地図画像が生成されていない場合)は地図生成に時間がかるのでもっさりしていますが、一度地図画像が生成されるとレスポンスは気になりません。
皆さんもこれを機会に自宅で地図サーバを構築してみてはいかがでしょうか?

4 Comments

  1. はじめまして。利用者ガイド翻訳者のひとり、東と申します。
    早速のご利用ありがとうございます!記載内容に不備が多くてすみません。実際に試して頂いて、大変嬉しいです。
    貴重な情報なので、リリースのアナウンスサイトからこの記事にリンクを貼らさせて頂いてもよろしいでしょうか。
    よろしくお願いします。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*