OpenStreetMapで独自レンダリングをしよう

OpenStreetMapのデータを使って自分独自の地図表現をするためのチュートリアルです。

底本となっているのは以下のサイトです。

* [Switch2OSM](http://switch2osm.org/serving-tiles/building-a-tile-server-from-packages/ "Building a tile server from packages")

## 想定している環境
* ubuntu 12.04 LTS
* 日本データだけを扱う場合、ディスク容量はだいたい50Gくらいを見積ってください
* 全世界データを扱う場合はデータサイズが500G以上になりますので、800Gくらいは見積もっておきたいところです
* メモリは可能な限り多く割り振ったほうが良いです。仮想環境であっても、最低1G、2Gくらいは見ておきたいところです

## これから整えるOSM環境
そもそも論ではあるのですが、OSMでは地図画像を生成するためにどのようなアーキテクチャを構築しているのでしょうか。

まずは前提となる環境を説明します。

### クライアントからのデータの流れ

![ざっくりとした流れ](https://qiita-image-store.s3.amazonaws.com/0/9928/c0f33914-8037-7638-0cc8-3927792be452.png)

1.  クライアントが、Apache-A 上に設置されている地図表示アプリ(OpenLayers、あるいはLeafletなど)を読み込みます
2. Apache-A の表示アプリから、「この地域の地図画像が欲しい」というリクエストがApache-Bへ行われます
3. Apache-Bでは`mod_tile` というタイル生成モジュールが動いており、`renderd`がアプリからのリクエストに応答します
4. `renderd`は、すでに地図画像が生成済みでキャッシュ画像ファイルが存在する場合は、その画像をApache-Aへ送ります
5. 生成済みの地図画像ファイルが無い場合、 `renderd`は`mapnik`を使って画像の生成を試みます
6. `mapnik`は対象地域のデータを得るため、PostGISに対してクエリを発行します
7. PostGISから返されたデータを元にして`mapnik`はレンダリングのルールどおりに地図画像を生成します
8. Apache-Bは、生成された画像をApache-Aへ返します
9. Apache-Aの地図表示ソフトは、生成された地図を座標毎に正しく並べ替えて表示します

今回の手順で、ひと通りの部分は自動的に設定することが可能です。

## 必要となるソフトのインストール
kakruegerさんというかたが、必要なソフトをまとめたPPAを用意してくれています。
apt-lineに追加して、必要な環境のインストールを行います。

https://launchpad.net/~kakrueger/+archive/openstreetmap

```
sudo apt-get install python-software-properties
sudo add-apt-repository ppa:kakrueger/openstreetmap
sudo apt-get update
sudo apt-get install libapache2-mod-tile
```
インストール中に、いくつかの質問が表示されます。

今回の Apacheはwww-dataユーザの権限で動作します。
www-dataユーザは、PostGISへのアクセス権を持つように設定されます。

PostGISへのアクセス権をwww-dataユーザ以外に与える場合は、www-dataの後にスペースを1つ空けて自分のアカウント名を入れてください。

例えば、以下の様な感じです。
![スクリーンショット](https://qiita-image-store.s3.amazonaws.com/0/9928/78464e2d-3efb-e843-650b-17981a3bc3c7.png)

```
www-data nyampire
```
パッケージの量が多いので時間が必要ですが、インストールが完了するまで気長に待ちましょう。

## 地図データのインポート
PostGISへ、日本のOpenStreetMapデータをインポートしましょう。

まずは、Geofabrik社が配布しているOpenStreetMapの地域別ダンプファイルを取得します。
自分がわかりやすいディレクトリで wgetしてください。
だいたい1GB前後の圧縮データがダウンロードされます。
http://download.geofabrik.de/asia/japan.html

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

ダウンロードしたデータを、PostGISへ格納します。
ダウンロードしたファイルを解凍する必要はありません。

以下のコマンドを実行してください。
データの格納には、だいたい数時間ほど必要です。
(メモリを1G割り振ったCore-i 5上のVMで、5時間ほどでした)

```
osm2pgsql --slim -C 1500 japan-latest.osm.pbf
```
インポート中に以下のようなエラーが表示されてインストールできない場合は、パッケージを reconfigureします。

* エラーメッセージ

```
Connection to database Failed: FATAL: Ident authentication failed for user “YOUR_USER_NAME”
```

* reconfigureの実施

```
sudo dpkg-reconfigure openstreetmap-postgis-db-setup
```

* あるいは、明示的に権限を与えてください。(DB名が "gis"だと仮定)

```
sudo /usr/bin/install-postgis-osm-user.sh gis [YOUR_USER_NAME]
```

www-data以外のユーザでPostGISへのデータ格納を実施した場合、格納が完了した後、以下のコマンドをもう一度叩いておいてください。
www-dataユーザに対して、PostGIS上のデータへのアクセス権をもう一度明示的にGRANTします。

```
sudo /usr/bin/install-postgis-osm-user.sh gis www-data
```

## Slippymapによるデータ表示
インポートが終わったら、いちど renderdを再起動します。

```
sudo /etc/init.d/renderd restart
```

renderdの再起動が終わったら、ブラウザを開いて以下のhtmlファイルを開いてください。
このhtmlファイルにはテスト用の Openlayersが組み込まれています。

```
http://localhost/osm/slippymap.html
```
mod_tileが動作しているサーバのアドレスがlocalhostではない場合は、`slippymap.html`ファイルの以下の部分を適切なアドレスやFQDNへ書き換えてください。
43行目あたりにあります。

```
            // This is the layer that uses the locally stored tiles
            var newLayer = new OpenLayers.Layer.OSM("Local Tiles", "http://localhost/osm/${z}/${x}/${y}.png", {numZoomLevels: 19});
            map.addLayer(newLayer);
```
また、デフォルトの表示位置はヨーロッパになっています。
デフォルトの表示位置を変更したい場合は、16行目あたりで座標指定されているので、その部分を例えば以下のように書き換えてください。

```
 // Start position for the map (hardcoded here for simplicity)
         var lat=35.35;
         var lon=135.5;
         var zoom=6;
```

タイル画像の生成には時間がかかります。サクサクと表示させるには相当のマシンパワーが必要です。
一度地図画像が生成された場所を表示する場合は、生成済みの画像が呼び出されるため、やや高速に表示が可能です。

ブラウザに地図画像が無事表示されたでしょうか？
デフォルトでは日本語用フォントが指定されていないため、2byte部分がトーフになっていると思います。

フォントの変更方法についてはまた別途記事を書く予定です。

また、地図データの定期的な更新 (osmosis)については、Switch2osmを参照してください。

## 各種設定ファイルの位置
パッケージで導入される各種設定ファイルは、以下のディレクトリに存在します。

```
地図スタイルシートと海岸線データ: /etc/mapnik-osm-data
生成済みのタイル画像: /var/lib/mod_tile
Renderd設定ファイル: /etc/renderd.conf
mod_tile設定ファイル: /etc/apache2/sites-available/tileserver_site
各種設定スクリプト: /usr/bin
データベース設定: /etc/postgresql/X.X/main (X.X は PostgreSQLのバージョンによって可変。2013/05現在では 9.1)
osm2pgsql設定とstate.txt:  /var/lib/mod_tile/.osmosis