【OpenStreetMap】タイルサーバを立てる

なんか、急にやりたくなった。

背景

「そういえば、地図ってオープンソースであるのかな?」



そんなことを考えたらやりたくなった。

課題

OpenStreetMapを使って自前のタイルサーバを立てたい。

前提

OS:Ubuntu 20.04

手順

1. 必要なパッケージをインストール

$ sudo apt install libboost-all-dev git tar unzip wget bzip2 build-essential autoconf libtool libxml2-dev libgeos-dev libgeos++-dev libpq-dev libbz2-dev libproj-dev munin-node munin protobuf-c-compiler libfreetype6-dev libtiff5-dev libicu-dev libgdal-dev libcairo2-dev libcairomm-1.0-dev apache2 apache2-dev libagg-dev liblua5.2-dev ttf-unifont lua5.1 liblua5.1-0-dev

問題なく入る。

2. postgresql/postgisをインストール

$ sudo apt install postgresql postgresql-contrib postgis postgresql-12-postgis-3 postgresql-12-postgis-3-scripts

これも問題なく入る。

3. postgresユーザ&データベース作成

$ sudo -u postgres -i
postgres@hogehoge$ createuser renderaccount
postgres@hogehoge$ createdb -E UTF8 -O renderaccount gis

4. テーブル作成

postgres@hogehoge$ psql

以下、postgresqlのプロンプトで操作

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 renderaccount;
ALTER TABLE
gis=# ALTER TABLE spatial_ref_sys OWNER TO renderaccount;
ALTER TABLE
gis=# \q

ここまで終わったら、Linuxプロンプトに戻るので、exitでpostgresユーザから抜ける。

postgres@hogehoge$ exit

5. ユーザ作成

root以外のユーザがあれば任意だけど、一応作っておく。

$ sudo useradd -m fuga
$ sudo passwd fuga
新しいパスワード:
新しいパスワードを再入力してください:
passwd: パスワードは正しく更新されました

6. osm2pgsqlインストール

$ sudo apt install osm2pgsql

問題なく入る。

7. Mapnikインストール

sudo apt install autoconf apache2-dev libtool libxml2-dev libbz2-dev libgeos-dev libgeos++-dev libproj-dev gdal-bin libmapnik-dev mapnik-utils python3-mapnik python3-psycopg2

問題なく入る。

一応、pythonプロンプトからimportできるか確認。

$ python3
>>> import mapnik
>>>

エラーが出ないのでOK! pythonプロンプトから抜ける。

>>> quit()

8. mod_tileとrenderdインストール

$ mkdir ~/src
$ cd ~/src
$ git clone -b switch2osm git://github.com/SomeoneElseOSM/mod_tile.git
$ cd mod_tile
$ ./autogen.sh

“autoreconf: Leaving directory `.‘“という文字列が出たら以下のコマンドを実行

$ ./configure

“config.status: executing libtool commands”という文字列が出たら以下のコマンドを実行

$ make

“make[1]: ディレクトリ ‘/home/fuga/src/mod_tile’ から出ます”という文字列が出たら以下のコマンドを実行(“fuga”の部分は自分のユーザ名)

$ sudo make install

“make[1]: ディレクトリ ‘/home/fuga/src/mod_tile’ から出ます”という文字が出たら以下のコマンドを実行(“fuga”の部分は自分のユーザ名)

$ sudo make install-mod_tile

“chmod 644 /usr/lib/apache2/modules/mod_tile.so”という文字列が出たら以下のコマンドを実行

$ sudo ldconfig

9. stylecheet設定

この先はさっき作った”renderaccount”で実行するのが良いらしい。 が、これまでの手順を愚直に進めていると、”git”コマンドが使えない現象が発生するので、”fuga”ユーザのまま進める。

$ cd ~/src
$ git clone git://github.com/gravitystorm/openstreetmap-carto.git

ここで、所有者を”renderaccount”に変更しておく。(こういうのって、あんまりよくないんだろうな。)

$ sudo chown renderaccount:renderaccount -R openstreetmap-carto/

次に”carto”コンパイラをインストールする

$ cd openstreetmap-carto
$ sudo apt install npm
$ sudo npm install -g carto

バージョン確認。

$ carto -v
1.2.0

ここで、ちょっとズルをする。

$ sudo su -
# cd /home/fuga/src/openstreetmap
# carto project.mml > mapnik.xml
# exit
$ cd /home/fuga/src/openstreetmap
$ sudo chown renderaccount:renderaccount mapnik.xml

10. データロード

動作確認用にアゼルバイジャンの地図データを落としてみる。

mkdir ~/data
cd ~/data
wget https://download.geofabrik.de/asia/azerbaijan-latest.osm.pbf

とりあえず、postgresユーザになってみる。

$ sudo su postgres

そして以下を実行

$ osm2pgsql -d gis --create --slim  -G --hstore --tag-transform-script /home/fuga/src/openstreetmap-carto/openstreetmap-carto.lua -C 2500 --number-processes 1 -S /home/fuga/src/openstreetmap-carto/openstreetmap-carto.style /home/fuga/data/azerbaijan-latest.osm.pbf

ここで、データベースのテーブルを確認すると、見事にOwnerがちぐはぐになってしまった。

$ sudo su postgres
postgres=# \c gis
You are now connected to database "gis" as user "postgres".
gis=# ALTER TABLE planet_osm_nodes OWNER TO renderaccount;
ALTER TABLE
gis=# \dt
                          List of relations
 Schema |                Name                 | Type  |     Owner
--------+-------------------------------------+-------+---------------
 public | external_data                       | table | renderaccount
 public | icesheet_outlines                   | table | renderaccount
 public | icesheet_polygons                   | table | renderaccount
 public | ne_110m_admin_0_boundary_lines_land | table | renderaccount
 public | planet_osm_line                     | table | postgres
 public | planet_osm_nodes                    | table | postgres
 public | planet_osm_point                    | table | postgres
 public | planet_osm_polygon                  | table | postgres
 public | planet_osm_rels                     | table | postgres
 public | planet_osm_roads                    | table | postgres
 public | planet_osm_ways                     | table | postgres
 public | simplified_water_polygons           | table | renderaccount
 public | spatial_ref_sys                     | table | renderaccount
 public | water_polygons                      | table | renderaccount
(14 rows)

これでは起動時に困るので、全てのテーブルの所有者を”renderaccount”に変更

gis=# ALTER TABLE planet_osm_nodes OWNER TO renderaccount;
ALTER TABLE
gis=# ALTER TABLE planet_osm_line OWNER TO renderaccount;
ALTER TABLE
gis=# ALTER TABLE planet_osm_point OWNER TO renderaccount;
ALTER TABLE
gis=# ALTER TABLE planet_osm_polygon OWNER TO renderaccount;
ALTER TABLE
gis=# ALTER TABLE planet_osm_rels OWNER TO renderaccount;
ALTER TABLE
gis=# ALTER TABLE planet_osm_roads OWNER TO renderaccount;
ALTER TABLE
gis=# ALTER TABLE planet_osm_ways OWNER TO renderaccount;
ALTER TABLE
gis=# \q

11. Shapefileダウンロード

今度は”renderaccount”になってからpythonスクリプトを実行

$ sudo su renderaccount
$ scripts/get-external-data.py

しばらく時間がかかります。エラーがなければそのまま放置で大丈夫。

12. フォント

sudo apt install fonts-noto-cjk fonts-noto-hinted fonts-noto-unhinted ttf-unifont

13. Apacheの設定

Apacheを設定する。

$ sudo mkdir /var/lib/mod_tile
$ sudo chown renderaccount /var/lib/mod_tile

$ sudo mkdir /var/run/renderd
$ sudo chown renderaccount /var/run/renderd

“mode_tile.conf”を作成する。

$ sudo nano /etc/apache2/conf-available/mod_tile.conf
$ cat /etc/apache2/conf-available/mod_tile.conf
LoadModule tile_module /usr/lib/apache2/modules/mod_tile.so

その後、起動する

$ sudo a2enconf mod_tile

次にApacheの設定。 “000-default.conf”の”ServerAdmin”と”DocumentRoot”の間に数行追加する。

$ sudo nano /etc/apache2/sites-available/000-default.conf
$ cat /etc/apache2/sites-available/000-default.conf
    # (略)
	ServerAdmin webmaster@localhost
    # <<ここから>>
	LoadTileConfigFile /usr/local/etc/renderd.conf
	ModTileRenderdSocketName /var/run/renderd/renderd.sock
	# Timeout before giving up for a tile to be rendered
	ModTileRequestTimeout 0
	# Timeout before giving up for a tile to be rendered that is otherwise missing
	ModTileMissingRequestTimeout 30
    # <<ここまで追加する>>
	DocumentRoot /var/www/html
    #  (略)

ここまで終わったら、apacheを2回リロード

$ sudo service apache2 reload
$ sudo service apache2 reload

14. renderdを起動してみる

このまま初回起動してもエラーになるので、renderd.confを編集する

$ nano /usr/local/etc/renderd.conf

何を変えたかというとこれ↓

- XML=/home/renderaccount/src/openstreetmap-carto/mapnik.xml
+ XML=/home/fuga/src/openstreetmap-carto/mapnik.xml

“renderaccount”になって実行してみる。

$ sudo su renderaccount
renderaccount@hogehoge$  renderd -f -c /usr/local/etc/renderd.conf

ブラウザでhttp:// <<ipaddress>>/hot/0/0/0.pngを開いてみる。 多分、こんなのが開く。

15. renderdをバックグラウンド起動する

“renderd.init”の中身をみて、”RUNASUSER”が”renderaccount”になっていることを確認。

$ nano ~/src/mod_tile/debian/renderd.init
$ sudo cp ~/src/mod_tile/debian/renderd.init /etc/init.d/renderd
$ sudo chmod u+x /etc/init.d/renderd
$ sudo cp ~/src/mod_tile/debian/renderd.service /lib/systemd/system/

その後以下を実行

$ sudo /etc/init.d/renderd start

それでサービスの自動起動設定

$ sudo systemctl enable renderd

16. タイルを表示してみる

サンプルのhtmlがあるのでそれをApacheのDocumentRoot直下にコピー

$ sudo cp -p ~/src/mod_tile/extra/sample_leaflet.html /var/www/html/

その後、コピーしたhtmlを編集する

$ vi /var/www/html/sample_leaflet.html

何を編集したかというと、IPアドレスの部分

- L.tileLayer('http://127.0.0.1/hot/{z}/{x}/{y}.png', {
+ L.tileLayer('http://<<ipaddress>>/hot/{z}/{x}/{y}.png', {

ブラウザからhttp://<<ipaddress>>/sample_leaflet.htmlにアクセスすると…

お疲れ様です。

参考サイト