Ubuntu 18.04を使用する場合
シングルボードコンピューターにOpenStreetMapのタイルサーバーを立ててみる
ラズベリーパイ 4 Model B + Ubuntu 20.04.1 LTS Serverを使用する場合
Raspberry Pi Imager for Windowsで32GB MicroSDにUbuntu 20.04.1 LTS Server をインストール。
MicroSDは32GB以上を使用。
64-bit server OS for arm64 architecture を選びます。
MicroSDの質や回線状況などの条件がよければ5分ほどで終了します。
初期設定
tileserverという新規ユーザーを作成してログインするようにしておいてください。
以下のページではUbuntu 18.04になっていますが、そこは無視してください。
最後のDesktop環境の構築は不要です。後の作業はSSH接続したコンソール上で行います。
タイルサーバーの構成
元ネタはこちら – Switch2OSM
Switch2OSMは18.04を対象に記述されています。20.04 LTS のリポジトリにはないパッケージもあるので注意する必要があります。
1:Softwareインストール
メインのOpenStreetMap.orgタイルサーバーで使用されているものと同様の最も標準的なバージョンについて説明します。
タイルサーバーはmod_tile、rendered、mapnik、osm2pgsql、postgresql / postgisデータベースという5つの主要コンポーネントで構成されています。
Mod_tileは、キャッシュされたタイルを提供し、どのタイルがまだキャッシュされていないか、または古くなっているため、再レンダリングが必要なタイルを決定するApacheモジュールです。
Renderedは、さまざまな種類のリクエストに優先キューイングシステムを提供し、レンダリングリクエストからの負荷を管理および平滑化します。
Mapnikは、実際のレンダリングを行うソフトウェアライブラリで、renderedによって使用されます。
osm2pgsql、postgresql / postgisはタイリング用のOpenStreetMapデータをデータベース化するためのコンポーネントです。
そしてApacheウェブサーバーが要求に従ってタイルデータを配信します。
これらのコンポーネントをビルドするために、さまざまな依存関係を最初にインストールしておきます。
20.04のリポジトリリストにはfocalしか記述されていませんが、bionicのリポジトリを見ないといけないパッケージもあるようです。
リポジトリのリストを編集します。
以下を追加(多分不要なのもあるとは思いますが、気にしない)。
deb http://ports.ubuntu.com/ubuntu-ports bionic universe
deb http://ports.ubuntu.com/ubuntu-ports bionic multiverse
deb http://ports.ubuntu.com/ubuntu-ports bionic-security universe
deb http://ports.ubuntu.com/ubuntu-ports bionic-security multiverse
deb http://ports.ubuntu.com/ubuntu-ports bionic-updates universe
deb http://ports.ubuntu.com/ubuntu-ports bionic-updates multiverse
deb http://ports.ubuntu.com/ubuntu-ports bionic-backports universe
deb http://ports.ubuntu.com/ubuntu-ports bionic-backports multiverse
アップデートしておきます。
Switch2OSMにあったlibprotobuf-c0-devについては、
libprotobuf-c0-dev は仮想パッケージで、libprotobuf-c-devで提供されるとのことなので、libprotobuf-c-devに変更。
以下を実行。
2:postgresql / postgisインストール
Switch2OSMでは10を使っていますが、バージョン12に変更します。
「postgresql」は地図データを保存するデータベースであり、「postgis」はグラフィカルサポートを追加します。
postgisデータベースを作成します。
「postgres」ユーザーとして作業しながら、PostgreSQLデータベースでPostGISを設定します。
3:データベースのチューニング
デフォルトのPostgreSQL設定は、OSMデータベースなどの非常に大規模なデータベースには適していません。 適切なチューニングにより、パフォーマンスが約2倍になります。
推奨される最小設定
shared_buffers = 128MB
max_wal_size = 2GB
min_wal_size = 1GB
work_mem = 32MB
maintenance_work_mem = 256MB
autovacuum = off
fsync = off
再起動
4:osm2pgsqlインストール
OpenStreetMapデータをデータベースにインポートおよび管理するためのツールosm2pgsqlを使用します。
前提条件をいくつかインストールしておきます。
ビルドします。
5:Mapnikをインストール
デフォルトバージョンを使用します。
Switch2OSMではPython2を使うようになっていますが、Python3に変更します。
Python3を使ってインストールされたか確認します。
python3
>>> import mapnik
エラーが起きなければOKです。
Pythonコンソールから抜けます。
>>>quit()
6:mod_tile と renderdインストール
レンダリング用のmod_tileをインストールします。 「mod_tile」は、タイルのリクエストを処理するApacheモジュールです。 「renderd」は、「mod_tile」がタイルを要求したときに実際にタイルをレンダリングするデーモンです。
mod_tileのソースをコンパイル
7:スタイルシート構成
スタイルシートをダウンロードして構成します。
cartoのインストール
Switch2OSMでは最新のcartoをインストールするようになっていますが、これだと構成に失敗します。
cartoはバージョン0のものを使います。
mapnik-referenceで表示された中ならmapnikのバージョンに一番近いものをつかいます。
インストールされたmapnikのバージョンは3.0(正確には3.0.19)なので3.0.20を使います。
cartoプロジェクトをMapnikが理解できるものに変換します。
(実行中は何も返ってこないダンマリ状態ですが進捗はしています)
8:データのロード
各国のデータはOpenStreetMap Data Extractsで提供されています。
文字表示用にロケールが適切に設定できれば、お好きな国のタイルサーバーが構成できると思います。
データをロードしてみます。日本全体だとosm.pbfファイル自体は1.5GB程度のサイズですがロードして展開すると40GBくらい消費します。7~8時間くらいかかります。
日本リージョンは、さらに8つのサブリージョンに分けられています。
(中部地方、中国地方、北海道、関西、関東、九州、四国、東北)
関西サブリージョンのみやってみます、30分弱で終わります。
ロードに続いてデータがソートされ、インデックスが作成されます。
osm2pgsqlではappendもできますし、createで実行すればデータベースは新規に再作成されます。
osm2pgsqlのオプションパラメータや使い方についてはこのページ参照
9:シェープファイルのダウンロード
ズーム率の低い、国の国境線などのためのシェープファイルがまだ必要です。
これらをダウンロードしてインデックスに登録します。
このプロセスにはかなりのダウンロードが含まれ、時間がかかる場合があります。実行中は画面にほとんど表示されません。 「openstreetmap-carto」の下の「data」ディレクトリに実際にデータが入力されます。
INFO:root:Checking table simplified_water_polygons
INFO:root:Checking table water_polygons
INFO:root:Checking table icesheet_polygons
INFO:root:Checking table icesheet_outlines
INFO:root:Checking table ne_110m_admin_0_boundary_land
だいたい12分くらいで終了。
たまにConnectionErrorで失敗することがあります。
ちょっと時間をおいて再実行してみましょう。
10:Fontsのインストール
世界中の場所で使用されている名前は、常にラテン文字で書かれているとは限りません(使い慣れた西洋のアルファベットa〜z)。
必要なフォントをインストールするには、次の手順を実行します。
11:webサーバーのセットアップ
renderdの構成
「renderd」の設定ファイルは「/usr/local/etc/renderd.conf」です。
[renderd]のセクション
num_threads=4
[ajt]セクションは、「ajt」と呼ばれる「名前付きマップスタイル」に対応しています。 XML=/home/tileserver/src/openstreetmap-carto/mapnik.xml
URI=/hot/
Apacheの構成
Apacheに「mod_tile」について通知する必要があります。
mod_tile.confを新規に作成します。
以下を追記
mod_tileを起動
次に、Apacheに「レンダリング」について通知する必要があります。
000-default.confをnanoなどのテキストエディターで編集します。
「ServerAdmin」行と「DocumentRoot」行の間に次を追加します。
Apacheを2回リロードします。
(Apacheは、実行時に再構成すると「混乱」するため、2回実行する必要があります)
12:renderdをバックグラウンドで実行
renderd.initを編集
以下のように変更
RUNASUSER=tileserver
パーミッションを変更してシステムディレクトリにコピーします。
13:タイル表示用のWebページ作成
Leafletライブラリを使ったサンプルが用意されています。
タイルを表示するために、mod_tileの「extras」フォルダーにある「sample_leaflet.html」というHTMLファイルを使ってみます。
Webのドキュメントルートは/var/www/htmlですので、ここにコピーします。
sample_leaflet.htmlはLeafletライブラリを使った地図表示用のWebアプリです。
lf.htmlという名前にしてみます。
編集してIPアドレスなどを変更します。
2か所変更
後でここにアクセスしてタイルを表示してみます。
14:レンダリングしたタイルを表示してみる
on-the-flyで実行してもストレスの元です。マニュアルでレンダリングしたデータを使ってみましょう。
事前にディレクトリを作っておきます。
8で関西サブリージョンのデータベースを作っておきましたので、大阪のごく狭いエリアをレンダリングしてみます。
その前にズームレベル0から9までのタイルデータをダウンロードしておきます。このデータはWisteriaHillが作成したものですが、時間を短縮できます。
解凍すると80MBくらいのものです。0~9というフォルダー名のものをSAMBAなどで/var/lib/mod_tileにコピーしておきます。
コピー後のディレクトリ構成はこんな感じです。
/var/lib/mod_tile/ajt/0 1 2 ….. 9
レンダリングにrender_list_geo.plという名前でalx77によって開発されたコマンドラインPerlスクリプトを使用すると、地理座標を使用して特定の領域のタイルを自動的にプレレンダリングできます。
関連するGithub READMEには、使用方法とサンプルが記載されています。
render_list_geo.plコマンドの主なオプション
-n スレッド数、Jetsonやラズパイの場合は1CPU 4Core 、1thread/1core なので4
-m タイルの保存場所、デフォルトは’default’ですが、現設定では’ajt’になっているので、明示的に指定
参考ファイルー>/usr/local/etc/renderd.conf
-z ズームレベルの最小値
-Z ズームレベルの最大値
-x 指定範囲の経度の最小値
-X 指定範囲の経度の最大値
-y 指定範囲の緯度の最小値
-Y 指定範囲の緯度の最大値
その他のオプション(通常使わない)
-a 標準入力から読み取る代わりに、指定されたズームレベル範囲内のすべてのタイルをレンダリングする
-t タイルディレクトリ、デフォルトは/var/lib/mod_tile
-f タイルが最新なように見えても強制的にレンダリングを実行
-l 負荷がこの値より高い場合はスリープ(デフォルトは16)
-s レンダリングに接続するためのUNIXドメインソケット名
念のためApacheとrenderdを再起動しておきます。
本来レンダリングは最大ズームレベル18まで実行するのですが、18はタイル数が半端じゃないくらい多いです。で、17と18は見た目にはそんなに差はないですので、ここでは10~17までを実行してみます。
レンダリングの矩形範囲を確認するにはOpenstreeMapのExportサイトが便利です。
大阪のこの辺りをレンダリングしてみます。
事前にレベル0~9のフォルダーをコピーしたので、再度パーミッションを指定しておきます。
13で作成したページにアクセス
http://<IPアドレス>/lf.html
大阪にアクセス、こんな感じです。
パワーやリソースがあるPCやワークステーション、AWSなどのクラウド環境を使えば、ズームしたりスクロールするごとにキャッシュに無かったり有効期限の切れたタイルは都度(On-The-Fly)レンダリングが実行されますがラズパイなどの、ちと非力なリソースしかないコンピュータの場合は、プレレンダリングしてキャッシュしておくという使い方がいいと思います(このサイトの眼目の一つは、地図をポータブルに使いたい……ということもあるんで ^^)。
レンダリングしたタイルをキャッシュする先を確保
上記の方法はラズパイのシステムがあるMicroSD内にタイルをキャッシュしていますが、日本全体のような、あるいは世界全体というようなタイルデータとなると容量が不足します。
外部ストレージを利用しましょう。これをマウントして利用します。
実際にタイルを作る前に保存先を決めます。
基本はどちらも、/var/lib/mod_tile/ajtをマウントポイントにしてストレージのディレクトリをマウントしてタイルデータをここにキャッシュします。
将来的にデータの増大などを顧慮するならNASやUSB接続のHDD(SSD)を使い、地域を限定して使うならUSBメモリで十分でしょう。
ストレージをマウントします。
NASの場合
試してみた実機はバッファローのLS210D021G(2TB)
cifsを使います。
マウントポイントを読み書き可能にしておきます。
NASのIPアドレスを調べておきます、例えば192.168.0.33だったとします。
NASのデータ保存先ディレクトリは共用フォルダー内のTileフォルダーだとします。
idコマンドでuidとgidを調べておきます。
NASのユーザー名(XXXXX)とパスワード(YYYYY)も確認しておいてください。
ラズパイの場合、例えばこんな感じになります。
Jetsonの場合エラーになりました。
マウントエラーのログを確認
無効な引数があったので削除しました。
USBストレージの場合
NASより簡単です。
Disk情報を確認
多分外部ストレージは
/dev/sda とか /dev/sdb と表示されると思います。
次にNASと同様にidコマンドでuidとgidを調べておきます。
例えばこんな感じでマウントします。
mount: unknown filesystem type ‘exfat’ というエラーが出た場合
Ubuntuはデフォルトでは「exfat」のフォーマットに対応していない….。
以下を実行して、再度マウント
Appendix
osmconvertのインストール
適当なフォルダーへ移動
sudo apt install osmctools
wget -O – http://m.m.i24.cc/osmconvert.c | sudo cc -x c – -lz -O3 -o osmconvert
osmosisのインストール
sudo apt install osmosis
Leave a Reply