【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
にアクセスすると…
お疲れ様です。