プログラマーのメモ書き

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

OpenStreetMap のタイルサーバーの更新設定

前の記事で、OpenStreetMap のタイルサーバー立てた話を書きました。

でも、 OpenStreetMap のデータはどんどん更新されていくので、ほっとくとせっかく立ち上げたタイルサーバーのデータが更新されず、使えないサーバーとなってしまいます。 ということで、データの更新ができるように設定したのですが、思いの他苦労したので、メモ書き残しておきます。

セットアップ手順

セットアップは基本的に、下記記事の Updating のセクションを参考にしているのですが、いろいろと違っているところもあるので、自分がやったものを順を追って書いていきます。

Building a tile server from packages | switch2osm

osmosis のインストール

まず最初に osmosis をインストールします。

mor@map:~$ sudo apt-get install osmosis

アップデート実施の準備

次に、アップデート実施のための準備を行います。OSMデータの更新は、 mod_tile/openstreetmap-tiles-update-expire を利用して行います。

なお、今回使っている mod_tile は前の記事が参考にしているセットアップ手順だと、

github.com

になります。オリジナルの mod_tile とスクリプトの内容が異なっているので、ご注意ください。

ログ用のディレクトリの作成

まず、ログ用のディレクトリを作ります

mor@map:~$ sudo mkdir /var/log/tiles
[sudo] mor のパスワード: 
mor@map:~$ sudo chown osm /var/log/tiles
スクリプトの修正

osm ユーザーに切り替えます

mor@map:~$ su - osm
パスワード: 
osm@map:~$ cd src/mod_tile/

mod_tile/openstreetmap-tiles-update-expire スクリプトを修正します。

osm@map:~$ cd src/mod_tile/
osm@map:~/src/mod_tile$ vi openstreetmap-tiles-update-expire 

修正箇所が複数あるので、修正前後の diff を示しておきます。

osm@map:~/src/mod_tile$ diff openstreetmap-tiles-update-expire.org openstreetmap-tiles-update-expire
11c11,12
< cd /home/renderaccount/src/mod_tile/
---
> RENDERACCOUNT=osm
> cd /home/$RENDERACCOUNT/src/mod_tile/
36a38,39
> POLYFILE=$WORKOSM_DIR/region.poly
> 
140c143
< if ! /home/renderaccount/src/regional/trim_osc.py -d gis -b -14.17 48.85 2.12 61.27 -z $CHANGE_FILE $CHANGE_FILE 1>&2 2>> "$RUNLOG"; then
---
> if ! /home/$RENDERACCOUNT/src/regional/trim_osc.py -d gis -p $POLYFILE -z $CHANGE_FILE $CHANGE_FILE 1>&2 2>> "$RUNLOG"; then
osm@map:~/src/mod_tile$ 
初期化のために実行

ここまでの準備ができたら、下記のコマンドを実行します。

osm@map:~/src/mod_tile$ ./openstreetmap-tiles-update-expire 2017-12-27
osm@map:~/src/mod_tile$ 

コマンド実行後、 /var/lib/mod_tile/.osmosis に設定ファイルや更新状態を管理するための通し番号や日時が記載されたファイル (state.txt) が作られます。

state.txt の書き換え

さて、上記の初期化の実行で生成される state.txt は minutely (分毎の差分)のものになっています。 しかし、今回は時間ごとに更新を行い、反映させる差分データは1時間単位のものを使おうと思うので、hourly のものに差し替えます。

ちなみに、取得するファイル(ここでは http://planet.openstreetmap.org/replication/hour/000/046/359.state.txt )は1時間ごと(や1分毎)の単位で、通し番号で管理されているようです。 で、その通し番号が3桁ごとに区切られてディレクトリに割り当てられているという構造のようです。このため、同じ state.txt であっても、分単位の差分と時間単位の差分、日単位の差分ではその通し番号が異なります。 このため、この節の作業が必要になります。もし、分単位の更新でよければ、この作業は不要です。

今回、タイルサーバー構築時にダウンロードしたファイルの日時が 2017-12-27 8:42 頃 (JST) のものだったので、UTC の 2017-12-26T22:00:00Z 頃のファイルを持ってきました。

osm@map:~/src/mod_tile$ cd /var/lib/mod_tile/.osmosis
osm@map:/var/lib/mod_tile/.osmosis$ wget http://planet.openstreetmap.org/replication/hour/000/046/359.state.txt
osm@map:/var/lib/mod_tile/.osmosis$ cat 359.state.txt 
#Tue Dec 26 22:02:11 UTC 2017
sequenceNumber=46359
timestamp=2017-12-26T22\:00\:00Z
osm@map:/var/lib/mod_tile/.osmosis$ 
osm@map:/var/lib/mod_tile/.osmosis$ mv 359.state.txt state.txt 
設定ファイルの編集

初期化のための実行により作成された設定ファイル /var/lib/mod_tile/.osmosis/configuration.txt を編集します。

利用する差分データとして時間毎ごとものを使うようにするのと、一回の更新で最大2時間分のデータを取得できるようにします。

osm@map:/var/lib/mod_tile/.osmosis$ vi configuration.txt
osm@map:/var/lib/mod_tile/.osmosis$ 
osm@map:/var/lib/mod_tile/.osmosis$ cat configuration.txt
# The URL of the directory containing change files.
baseUrl=http://planet.openstreetmap.org/replication/hour

# Defines the maximum time interval in seconds to download in a single invocation.
# Setting to 0 disables this feature.
maxInterval = 7200
osm@map:/var/lib/mod_tile/.osmosis$ 

一部地域のデータ更新への対応

元々の openstreetmap-tiles-update-expire は全世界の差分を処理する形のようです。 https://github.com/SomeoneElseOSM/mod_tile の openstreetmap-tiles-update-expire はこれに対して、一部地域の差分データだけを処理できるように修正が加えられています。

GitHub - Zverik/regional: Scripts for regional OSM extracts support

この機能を利用するための設定を行います。

パッケージの追加

追加でいくつかパッケージをインストールします。

mor@map:~$ sudo apt-get install python-psycopg2
mor@map:~$ sudo apt-get install python-shapely 
mor@map:~$ sudo apt-get install python-lxml 

lxml はgithubのページには明記が無かったのですが、実行時にエラーとなったため、追加しています。

スクリプトのインストール

Github から clone しておきます。

mor@map:~$ su - osm
パスワード: 
osm@map:~$ cd src/
osm@map:~/src$ 
osm@map:~/src$ git clone https://github.com/Zverik/regional.git 
osm@map:~/src$ cd regional/
osm@map:~/src/regional$ chmod u+x trim_osc.py 
ポリゴンファイルのダウンロード

差分データを一部地域に限定する際、矩形での指定に加えて、ポリゴンで指定もできるようです。 今回立てたタイルサーバーは geofabrik のダウンロードサイトから日本のみのデータをダウンロードして使っています。

http://download.geofabrik.de/asia/japan.html

なので、日本の領域を表すポリゴンデータをダウンロードしておきます。

osm@map:~/src/mod_tile$ cd /var/lib/mod_tile/.osmosis/
osm@map:/var/lib/mod_tile/.osmosis$ 
osm@map:/var/lib/mod_tile/.osmosis$ wget http://download.geofabrik.de/asia/japan.poly
osm@map:/var/lib/mod_tile/.osmosis$ ln -s japan.poly region.poly
osm@map:/var/lib/mod_tile/.osmosis$ 

マニュアル実行

ここまでできれば、準備完了です。

まずは手作業で実行させてみます。

osm@map:~$ cd src/mod_tile/
osm@map:~/src/mod_tile$ 
osm@map:~/src/mod_tile$ ./openstreetmap-tiles-update-expire

問題がなければ、そのまま終了します。ログファイルをみると

mor@map:/var/log/tiles$ cat run.log 
[2017-12-29 00:47:38] 10124 start import from seq-nr 46359, replag is 1 day(s) and 17 hour(s)
[2017-12-29 00:47:38] 10124 downloading diff
[2017-12-29 00:47:49] 10124 filtering diff
[2017-12-29 00:48:06] 10124 importing diff
[2017-12-29 00:49:01] 10124 expiring tiles
[2017-12-29 00:49:01] 10124 Done with import
mor@map:/var/log/tiles$ 

のようになっていて、インポートが完了しているようです。

作業時点の最新の状態へ更新

/var/lib/mod_tile/.osmosis/configuration.txt にある maxInterval はデフォルトでは 3600 になっています。

これは、1回の処理につき、指定秒数分のデータの更新を行うという設定です。つまり、一度 openstreetmap-tiles-update-expire を実行すると1時間分(3600秒分)のデータが更新されるということです。 今の設定ですと、対象のデータが hourly のデータなので、一回の更新で1つ分(1時間分)しか更新されません。

通常は、これで問題ないと思いますが、初回のインポートからある程度時間が経っていると、なかなか最新の状態に追いつくことができません。 そこで、 maxInterval を適当に大きな値にして、数回 openstreetmap-tiles-update-expire を実行しておきます。

こうすることで、最新の状態に設定することができます。 現在時刻まで追いついたら、元の値(今回の設定値は 7200 )に戻しておきます。

cron を設定

ここまでできれば、定期的に cron で上記のスクリプトを動かせばOKです。

osm@map:~$ crontab -l
6 */1 * * *  /home/osm/src/mod_tile/openstreetmap-tiles-update-expire > /dev/null 2>&1
osm@map:~$ 

参考

基本的な方法

基本的な考え方(下記の Updating セクション) Building a tile server from packages | switch2osm

記述の前提が、Ubuntu 12.04 を対象にしたパッケージによりセットアップしたタイルサーバーのため、今回作成したタイルサーバーと細かく違っている。

なお、上記の Updating セクションには

As the packaged script currently uses an outdated service to determine the correct replication start-point, you will need to manually choose and download the correct state.txt from the base_url (see below) which corresponds to slightly before the age of the extract to make sure all modifications are included in your db. This needs to be copied to /var/lib/mod_tile/.osmosis/state.txt

とあります。ざっと意訳すると、スクリプト中の更新開始地点を決めるために使っているサービスは古いものなので、自分で対応するファイルを取ってきてね、という感じです。

これは、オリジナルの mod_tile の openstreetmap-tiles-update-expire についての話で、今回使った https://github.com/SomeoneElseOSM/mod_tile の openstreetmap-tiles-update-expire だと既に修正されています。

その元ネタ?

openstreetmap-tiles-update-expire スクリプトが行っている処理は、下記のページの手順をまとめて実施してくれているような感じのようです。

HowTo minutely hstore - OpenStreetMap Wiki

osmosis

osmosis のリファレンスはこちら --read-replication-interval-init に飛びます

Osmosis/Detailed Usage 0.46 - OpenStreetMap Wiki