OpenStreetMap タイルを自動生成する。

前回は
[タイルサーバの構築](http://qiita.com/Syn256/items/633aef930455bfd4be0d)
にて、OpenStreetMapのタイルサーバの構築を行いました。

ただ、この状態だと表示に結構時間が必要で、実用面では少し不満が残ります。
ですので、事前にタイル画像を生成し、キャッシュを表示できる様にしておくと
レスポンス良く地図が表示できる様になるため、今回はタイル画像のキャッシュ生成を行うことにしました。

---

手順
1. mapnik-stylesheetsのディレクトリに移動
2. mapnikモジュールをpipでインストール(easy_installでバージョンを指定する必要がありました）
3. 自分の環境情報に設定したlocal_osm.xmlを生成する
4. generate_tiles.pyまたはgenerate_tiles_multiprocess.pyを自分の環境に合わせて修正
5. generate_tiles_muliprocess.pyを実行
6. /etc/renderd.confの [renderd]セクションに記述した tile_dirのディレクトリに生成したタイル画像を上書き保存
7. apacheとrenderdを再起動（すぐには反映されないので、ちょっと時間がかかるみたいです）

---

タイルの生成はmpanik-stylesheetsの中に、
generate_tiles.py
generate_tiles_multiprocess.py
のふたつのスクリプトがあり、それを実行することでタイル画像を事前生成することができます。

どちらもタイル画像の生成スクリプトですが、multiprocessの方がマルチコア対応しているので、コア数の多いマシンで運用しているならこちらを利用した方が短時間に生成ができます。

---

###実行前の準備

generate_tilesスクリプトでは、mapnik2 またはmapnikモジュールが参照されていて、pipで事前にmapnik2かmapnikをインストールしておく必要がありますが、
pip install mapnikだと古いバージョンのライブラリが導入されてしまい、


```
python generate_tiles.py 
/usr/lib64/python2.7/site-packages/mapnik2/__init__.py:27: DeprecationWarning:  mapnik2 module has been deprecated,
        please use 'import mapnik' 
  warnings.warn(msg, DeprecationWarning)
render_tiles( (139.549763, 35.675632, 139.771898, 35.964519) /usr/local/src/mapnik-v2.0.2/mapnik-stylesheets/osm.xml /var/lib/mod_tile/default/ 10 16 unknown )
Traceback (most recent call last):
  File "generate_tiles.py", line 220, in <module>
    render_tiles(bbox, mapfile, tile_dir, minZoom, maxZoom)
  File "generate_tiles.py", line 136, in render_tiles
    renderer = RenderThread(tile_dir, mapfile, queue, printLock, maxZoom)
  File "generate_tiles.py", line 64, in __init__
    mapnik.load_map(self.m, mapfile, True)
RuntimeError: failed to initialize projection with: '&srs900913;' in Map of '/usr/local/src/mapnik-v2.0.2/mapnik-stylesheets/osm.xml'
```

こんなエラーに遭遇します。
そこでmapnik2をインストールするのですが・・・
pip install mapnik2
だとboost_pythonのライブラリがないと怒られます。
すでに boost_pythonもboost-develもインストール済みなのですが、それでもエラーが解決しないので、easy_installでバージョンを指定してインストールを行います。

```
yum -y install gdal-python gdal-devel
easy_install -U mapnik2==2.0.1.3
```
こうすればエラーなく完了するはずです。

インストールが完了したら

osmをタイル画像生成用のosm.xmlを作成します。
./generate_xml.py osm.xml local_osm.xml --host localhost --port 5432 --dbname gis --user postgres --password {パスワード}

これでlocal_osm.xmlが作成できるので、
generate_tiles.pyを編集します。

```
# mapfileのパスと tile_dirを現在設定している場所に変更します。

if __name__ == "__main__":

    home = os.environ['HOME']
    try:
        mapfile = "/usr/local/src/mapnik-v2.0.2/mapnik-stylesheets/local_osm.xml"
        #mapfile = os.environ['MAPNIK_MAP_FILE']
    except KeyError:
        mapfile = home + "/svn.openstreetmap.org/applications/rendering/mapnik/local_osm.xml"
    try:
        # render.confの場所でないところで生成した方が良いです。
        tile_dir = "~/tiles/"
        #tile_dir = os.environ['MAPNIK_TILE_DIR']
    except KeyError:
        tile_dir = home + "/osm/tiles/"

    if not tile_dir.endswith('/'):
        tile_dir = tile_dir + '/'

    #-------------------------------------------------------------------------
    #
    # Change the following for different bounding boxes and zoom levels
    #
    # Start with an overview
    # World

    # とりあえず今回は文京区だけで実施します。
    minZoom = 10
    maxZoom = 16
    bbox = (139.7277, 35.6969, 139.7779, 35.7372)
    render_tiles(bbox, mapfile, tile_dir, minZoom, maxZoom)

    #元のソースをコメントアウトします。この設定がタイル画像の生成範囲です。
    #bbox = (-180.0,-90.0, 180.0,90.0)
    #render_tiles(bbox, mapfile, tile_dir, 0, 5, "World")

    #minZoom = 10
    #maxZoom = 16
    #bbox = (-2, 50.0,1.0,52.0)
    #render_tiles(bbox, mapfile, tile_dir, minZoom, maxZoom)

    ## Muenchen
    #bbox = (11.4,48.07, 11.7,48.22)
    #render_tiles(bbox, mapfile, tile_dir, 1, 12 , "Muenchen")

    ## Muenchen+
    #bbox = (11.3,48.01, 12.15,48.44)
    #render_tiles(bbox, mapfile, tile_dir, 7, 12 , "Muenchen+")

    ## Muenchen++
    #bbox = (10.92,47.7, 12.24,48.61)
    #render_tiles(bbox, mapfile, tile_dir, 7, 12 , "Muenchen++")

    ## Nuernberg
    #bbox=(10.903198,49.560441,49.633534,11.038085)
    #render_tiles(bbox, mapfile, tile_dir, 10, 16, "Nuernberg")

    ## Karlsruhe
    #bbox=(8.179113,48.933617,8.489252,49.081707)
    #render_tiles(bbox, mapfile, tile_dir, 10, 16, "Karlsruhe")

    ## Karlsruhe+
    #bbox = (8.3,48.95,8.5,49.05)
    #render_tiles(bbox, mapfile, tile_dir, 1, 16, "Karlsruhe+")

    ## Augsburg
    #bbox = (8.3,48.95,8.5,49.05)
    #render_tiles(bbox, mapfile, tile_dir, 1, 16, "Augsburg")

    ## Augsburg+
    #bbox=(10.773251,48.369594,10.883834,48.438577)
    #render_tiles(bbox, mapfile, tile_dir, 10, 14, "Augsburg+")

    ## Europe+
    #bbox = (1.0,10.0, 20.6,50.0)
    #render_tiles(bbox, mapfile, tile_dir, 1, 11 , "Europe+")
```

```
python generate_tiles.py 
/usr/lib/python2.7/site-packages/mapnik2-2.0.1.3-py2.7-linux-x86_64.egg/mapnik2/__init__.py:27: DeprecationWarning:  mapnik2 module has been deprecated,
        please use 'import mapnik' 
  warnings.warn(msg, DeprecationWarning)
render_tiles( (139.7277, 35.6969, 139.7779, 35.7372) /usr/local/src/mapnik-v2.0.2/mapnik-stylesheets/osm.xml /var/lib/mod_tile/default/ 10 16 unknown )
unknown : 11 1819 806  
unknown : 11 1818 806  
unknown : 12 3637 1612  
unknown : 13 7275 3224  
unknown : 13 7275 3225  
unknown : 12 3638 1612  
unknown : 14 14551 6448  
unknown : 13 7276 3224  
unknown : 13 7276 3225  
unknown : 14 14551 6449  
unknown : 14 14551 6450  
unknown : 10 909 403  
unknown : 14 14552 6448  
unknown : 14 14552 6449  
unknown : 14 14553 6448  
```

もう一度実行すると

```
python generate_tiles.py 
/usr/lib/python2.7/site-packages/mapnik2-2.0.1.3-py2.7-linux-x86_64.egg/mapnik2/__init__.py:27: DeprecationWarning:  mapnik2 module has been deprecated,
        please use 'import mapnik' 
  warnings.warn(msg, DeprecationWarning)
render_tiles( (139.7277, 35.6969, 139.7779, 35.7372) /usr/local/src/mapnik-v2.0.2/mapnik-stylesheets/osm.xml /var/lib/mod_tile/default/ 10 16 unknown )
unknown : 10 909 403 exists 
unknown : 11 1818 806 exists 
unknown : 11 1819 806 exists 
unknown : 12 3637 1612 exists 
unknown : 13 7275 3225 exists 
unknown : 12 3638 1612 exists 
unknown : 13 7275 3224 exists 
unknown : 13 7276 3224 exists 
unknown : 13 7276 3225 exists 
unknown : 14 14551 6448 exists 
unknown : 14 14551 6449 exists 
```

すでに登録済みのため、existsが表示されます。

キャッシュを上書きしたい場合は、一度キャッシュ可能ディレクトリから作成済みのキャッシュファイルを削除する必要があります。
ですので、mod_tileのキャッシュ格納ディレクトリを吐き出し先に指定するより、
ブランクディレクトリに吐き出し、完了後に上書きした方が正しくキャッシュを更新できます。

実行したら、吐き出し先にキャッシュ画像が生成されるので、
ダウンロードするなりして確認してみてください。