プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

OpenStreetMap のタイルサーバー立ててみました

OpenStreetMap をテスト的に利用するなら、OpenStreetMap が提供するタイルサーバーを使うこともできます(こちらなどをご参考にしてください)。 ですが、アプリで利用したり、本格的に利用するにあたっては、タイルサーバーを自分で用意しないといけません。

JA:タイル利用規約 - OpenStreetMap Wiki

(原文はこちらかな)

Tile Usage Policy

というわけで、自宅に余っていたサーバーを使って、タイルサーバーをセットアップしてみたので、メモを残しておきます。

サーバーの準備

サーバーは自宅に余っていた Dell の T105 を使います。 これ、昔 ESXi 4 とかでVM動かしていたやつなんですが、最近、VM使うときは作業PC上のVirtualBox使うし、常時稼働していたVPNサーバーは、QNAP上のVMに移したので、しばらく使っていませんでした。

でも、160GBぐらいのHDDついてるし、メモリも8GBあるので、タイルサーバーのお試しにはいいかな、という感じです。スペック書いておきます。

  • Dell T105
  • CPU: Opteron 3182 (Quad Core)
  • メモリ: 8GB
  • HDD: 160GB (ハードウェアミラーリングあり)

Ubuntu のインストール

まず最初に、Ubuntuをインストールします。 実は、このPC、少しでも安く買おうとしたので、CD/DVDドライブがついていないんですよね。なので、USBメモリにISOイメージを焼いて、それから起動させてセットアップします。

USBメモリにISOイメージを焼くのには Rufus を使いました。

Rufus - Create bootable USB drives the easy way

ISO イメージは、手元にあった ubuntuサーバー (64bit版) の16.04.02 を使いました(作業のタイミングで 16.04.3 が出てましたけどダウンロードするのに時間がかかったのでやめました)。

Ubuntuのセットアップは、特に問題ないので省略します。USBメモリ指して、PCの電源入れて、画面の指示に従えばokです。 あと、セットアップ画面では、

  • standard utilities
  • Open SSH Server

のみを選択しました。

あとはお決まりの

sudo apt-get update
sudo apt-get upgrade

をしておきます。 この時点で、 16.04.3 になってました。

タイルサーバーのセットアップ

さて、OSのセットアップが終わったので、早速タイルサーバーのセットアップを始めます。

最初、こちらの記事に従って、インストールしようとしたのですが、16.04では、お手軽にインストールできないようです。 12.04での方法のようですね(14.04なら同じ方法でできたという記事もありました)。

qiita.com

16.04でのタイルサーバーの構築をどうするんだろうか? と、調べてみると、そのものずばりの記事がありました。

Manually building a tile server (16.04.2 LTS) | switch2osm

ちなみに、ほぼ上記の記事通りの手順を日本語で説明してくれてる記事もありました。こちらも参考になりました。

Ubuntu 17でOpenStreetMap Tile Serverをたててみる - hinosita's diary

今回は上記の記事(主に英文のほう)を参考にインストールします。

ちなみに、上記以外にもインストール例はありましたので、そちらも参考にされるといいかもしれません(今回は試してないですが)。 リンクだけ貼っておきます。

Ubuntu 16.04 で OpenStreetMap タイルサーバを構築 – keizoh.com

インストール

さて、タイルサーバーのインストールとセットアップですが、上記の手順に従えば特に問題もなかったです。 一応、気になったポイントだけ書いておきます。

インストールした各種パッケージについて

上記の日本語のほうの記事では、セットアップの際、libpng12 の関係でパッケージリポジトリを追加したとありますが、今回試したときは特になにもしなくてもOKでした。 あと、postgresのバージョンも postgresql-9.5-postgis-2.2 のままとしました(警告メッセージ出てなかったような・・・私が気づいてないだけかな?)。

posgresql /potgis のインストール

手順通りにやれば問題なかったです。 日本語の説明記事では、データベースを作成する際の所有者(オーナー、 -O オプション)が既に作成されている前提で書かれていますが、英文の記事にあるようにこの時点ではまだ作成されていなくでも大丈夫でした。

今回は、 osm という名前にすることにしました。また、データベース名も英文記事で使っている gis としています。

mor@map:/etc$ sudo -u postgres -i
[sudo] mor のパスワード: 
postgres@map:~$ createuser osm
postgres@map:~$ createdb -E UTF8 -O osm gis
postgres@map:~$ psql
psql (9.5.10)
Type "help" for help.

postgres=# \c gis
You are now connected to database "gis" as user "postgres".
gis=# CREATE EXTENSION postgis;
CREATE EXTENSION
gis=# CREATE EXTENSION hstore;
CREATE EXTENSION
gis=# ALTER TABLE geometry_columns OWNER TO osm;
ALTER TABLE
gis=# ALTER TABLE spatial_ref_sys OWNER TO osm;
ALTER TABLE
gis=# \q
postgres@map:~$ exit
ログアウト
mor@map:/etc$ 

こんな感じです。 データベース作成後に osm というユーザーを作成すればOKです。

mor@map:/etc$ sudo useradd -m osm
mor@map:/etc$ sudo passwd osm
新しい UNIX パスワードを入力してください: 
新しい UNIX パスワードを再入力してください: 
passwd: password updated successfully
mor@map:/etc$ 
OSMデータのダウンロードとデータ投入

こちらは先ほどの日本語の記事を参考に、下記のように日本のデータをダウンロードしました。

wget http://download.geofabrik.de/asia/japan-latest.osm.pbf

osm2pgsqlを使ってデータ投入をするのですが、キャッシュとコア数のオプションは、手元のPCに合わせて、-Cオプション(キャッシュ)は 7GB、 --number-processes (コア数)は 3 を指定しました。

osm@map:~$ osm2pgsql -d gis --create --slim  -G --hstore --tag-transform-script ~/src/openstreetmap-carto/openstreetmap-carto.lua -C 7000 --number-processes 3 -S ~/src/openstreetmap-carto/openstreetmap-carto.style ~/data/japan-latest.osm.pbf

このデータの投入にかなり時間がかかると思っていたのですが、今回の場合は2時間弱(105分だったかな)で終わりました。思ってたよりは早かったですね。

ちなみに、このデータ投入作業を実行するアカウントが、postgres の gis データベース(作成したデータベース)のオーナーのユーザーアカウントである必要がありました。 今回の場合、osmというユーザー名にしていたので、

mor@map:~$ su - osm

で osm ユーザーに切り替え後に実行しました。さらに、ここまでの作業を最初にログインしたユーザーでやってしまっていたので、

osm@map:~$ cp -p /homr/mor/data ~/
osm@map:~$ cp -p /home/mor/src ~/

のように、 osm ユーザーのホームにコピーしておきました。 その意味では、各種セットアップ作業も、osmアカウントで実行したほうが素直だったかもしれません(自分のユーザーアカウントでやってました)。もっとも、sudo 使えるように sudoers 触るのもどうかとちょっと嫌なので痛しかゆしかな。

シェイプファイルのダウンロード

シェイプファイルのダウンロードにもかなり時間がかかりました(約117分)。こっちのほうが、OSMのデータの投入より時間がかかってましたね。 ダウンロードは、 osm ユーザーの環境で実行しています。

これは、手順通りに作業を進めていると、スタイルシート(openstreetmap-carto)のインストールで、 mapnik.xml を作っていると思いますが、この内部にシェイプファイルのダウンロードで取得したファイル名が記載されています。シェイプファイルは、ダウンロードを実行したユーザーの ~/src/openstreetmap-carto/data 以下に保存されるようなので、 mapnik.xml を持っているユーザーとシェイプファイルのダウンロードユーザーが同じ必要がある、というわけです。

セットアップ

手順通りにすれば特に問題ありませんでした。

/usr/local/etc/renderd.conf の内容を示しておきます。XML= で mapnik.xml を持っているユーザー名の部分だけ書き換えています。

osm@map:~$ cat /usr/local/etc/renderd.conf
[renderd]
num_threads=4
tile_dir=/var/lib/mod_tile
stats_file=/var/run/renderd/renderd.stats

[mapnik]
plugins_dir=/usr/lib/mapnik/3.0/input
font_dir=/usr/share/fonts/truetype
font_dir_recurse=1

[ajt]
URI=/hot/
TILEDIR=/var/lib/mod_tile
XML=/home/osm/src/openstreetmap-carto/mapnik.xml
HOST=localhost
TILESIZE=256
MAXZOOM=20

osm@map:~$ 

動作確認

動作確認してみます。まず、ユーザーをosmに変更してから、renderd を対話で起動します。

mor@map:~$ su - osm
パスワード: 
osm@map:~$ 
osm@map:~$ renderd -f -c /usr/local/etc/renderd.conf
renderd[11573]: Rendering daemon started
renderd[11573]: Initiating request_queue
(後略)

ブラウザからアクセスしてみても何も表示されません。 コンソールを確認すると、

(前略)
renderd[11573]: Using web mercator projection settings
renderd[11573]: DEBUG: Got incoming connection, fd 8, number 1
renderd[11573]: DEBUG: Got incoming request with protocol version 2
renderd[11573]: DEBUG: Got command RenderPrio fd(8) xml(ajt), z(0), x(0), y(0), mime(image/png), options()
renderd[11573]: DEBUG: START TILE ajt 0 0-0 0-0, new metatile
renderd[11573]: Rendering projected coordinates 0 0 0 -> -20037508.342800|-20037508.342800 20037508.342800|20037508.342800 to a 1 x 1 tile
renderd[11573]: DEBUG: Connection 0, fd 8 closed, now 0 left
renderd[11573]: DEBUG: DONE TILE ajt 0 0-0 0-0 in 31.158 seconds
debug: Creating and writing a metatile to /var/lib/mod_tile/ajt/0/0/0/0/0/0.meta

DEBUG: DONE TILE とあるので、レンダリングには成功しています。でも、レンダリングに 31秒かかってますね。 ひょっとしたら、タイムアウトになっているのかもしれません。 ということで、ブラウザでリロードすると問題なく、画像が表示されました。やった!

f:id:junichim:20171228094157p:plain

renderd の自動起動設定

これも手順通りに行えば、特に問題ありません。 一度、サーバーを再起動して、再度ブラウザから接続して、地図が表示されることを確認しておきます。

まとめ

手順通りにやれば、時間はかかりますが、タイルサーバーの立ち上げそのものはそんなに難しくなかったです。 ただ、実際に地図を表示させてみると、なかなか重くて表示されないです。当面、試験的に使ってみていろいろと試したいと思います。

あと、せっかくタイルサーバーが立ち上がったので、

  • docker file にまとめる
  • OSM データが更新されたらそれを自動で反映する
  • 公開サーバーとする

あたりをやれればいいな、と思います。