世界の測量

Sibling of "Relevant, Timely, and Accurate, " but much lighter and shorter ※自らの所属する組織の見解を示すものでない

heroku chizujutsu

TileMill で作成した mbtiles ファイルを、heroku でホストする方法についてメモをまとめた。技術的には、Node.js で作成されたタイルサーバである tilestream を、heroku で動作させる話である。

基本的に、heroku で Node.js アプリケーションをホストしてもらう標準工程に従うが、mbtiles というデータの塊も含めて heroku の slug (上限100MB)にするので、mbtiles のサイズが大きすぎると heroku が slug を受け取ってくれない。うまくサイズを調整する必要がある。経験ではmbtiles ファイルの大きさは40MBが上限となるようだ。また、heroku とデベロッパーは git でコミュニケーションをするが、mbtiles のような巨大なバイナリファイルを git でやりとりしようとすると効率が悪い(古いデータも保存してしまうし、サーバにも送信してしまう。巨大なバイナリファイル又は多数のバイナリファイルをバージョン管理システムで管理してはならないというのは、ほとんど祖法である。)ので、git のバージョン管理機能は使用せず、mbtiles の送り込みは基本的に最初の一撃に限るべきである。以上2点、(バッド)ノウハウがある。

この記事は、基本的に、以下の3つのリソースをとりまとめたものである。

これらを取りまとめてくれた方に感謝。

準備

heroku にサインアップして、heroku toolbelt をインストールして、

$ heroku login

しておく。詳細は、Getting Started with Heroku | Heroku Dev Centerを参照。

ファイルの準備

tswicegood/tilestream-on-heroku · GitHub にあるとおり、Procfile と package.json、それから tiles フォルダに mbtiles ファイルを準備する。

. -+- Procfile
   +- package.json
   +- tiles --- [gmidn].mbtiles

Procfile は、heroku でどういうアプリケーションを立ち上げるか指示するファイルらしく、次の内容で用意しておく。(後で一部修正する。)

web: tilestream --host smooth-earth-5940.herokuapp.com --uiPort=$PORT --tilePort=$PORT --tiles=./tiles

package.json は、Node.js そのもののバージョンや、使用する拡張のバージョンを指示するもの。次の内容で用意しておく。(後で一部修正する。)

{
  "name": "smooth-earth-5940",
  "version": "0.0.1",
  "engines": {
    "node": "0.4.7",
    "npm": "1.0.106"
  },
  "dependencies": {
    "tilestream": "1.0.0"
  }
}

(ここで、念のため、過去の git 管理を無効化するよう rm -rf .git してみておいてもよい。)

次に、次のコマンドを実行する。

$ git init
$ git add .
$ heroku create -s cedar

最後の「heroku create -s cedar」によって、サーバの名前(「smooth-earth-5940」といったもの)が割り当てられてくるので、それに合わせて Procfile と package.json を修正する。なお、サーバのな前を指定する方法もあるが説明を省略する。ファイルを修正したら、

$ git commit -m "init"
$ git push heroku master

とすることで、ファイルが heroku 側にアップロードされ、heroku 側で Node.js 拡張がコンパイルされ、うまくいけばサーバが起動した旨メッセージが出る。

エラーのパターンはおそらく2つあって、Procfile または package.json の記述ミスによるか、あるいは mbtiles ファイルが大きすぎて slug が 100MB を超えてしまうことによる。

実例

実例サイトは、以下である。
TileStream

なお、このサイトの style.mss は以下のとおり。

Map {
  background-color: #fff;
}

#watrcrsl [zoom >= 8]{
  line-width:1;
  line-color:#66f;
}

#roadl [zoom > 8]{
  line-width:2;
  line-color:#ddd;
}

#polbndl {
  line-dasharray:6,2;
  line-join:round;
  line-color:#f24;
}

#polbndl[use=23] {
  line-width:3;
}

#polbndl[use=26] {
  line-width:2;
}

#polbndl[use=30] {
  line-width:1;
}

#coastl {
  line-width:1;
  line-color:#555;
}

#inwatera [zoom >= 8]{
  line-color:#66f;
  line-width:1;
  polygon-opacity:1;
  polygon-fill:#aaf;
}

#builtupa [zoom >= 8]{
  line-color:#d00;
  line-width:0.5;
  polygon-opacity:1;
  polygon-fill:#e66;
}

#builtupa [zoom > 8] {
  text-name: '[nam]';
  text-face-name: 'Baskerville Regular';
  text-size: 14;
  text-halo-radius: 0.8;
}

heroku を用いた方法は、 mbtiles ファイル(sqlite のデータベースだ)を実行形式である slug に固めることになるので、タイルセットが少量である場合にのみ有効だと思う。mapbox のホスティングも、個人で使用売るには比較的コストがかかる。おそらく、データを分解して Amazon S3 に置く方法が最も安価であるように思える。試算したところ、Amazon S3 の従量制料金も、heroku で出したような程度を出す分にはほとんど無視できるくらいしかかからないようだ。Amazon S3 を用いた場合については、あとで書く。