この記事は、
にポストする記事として書いています。
先月、Geoloniaメンバーが一同に会する合宿が香川県高松市にある男木島でおこなわれました。特にエンジニア以外のメンバーもGeoloniaの中核技術であるベクトルタイルの仕組みを手を動かして理解しようということで、OpenStreetMapで適当な地物を登録した上で、ゼロからベクトルタイルを作成し、地物を実際に表示してみようというミニワークショップをおこないました。Geoloniaにジョインして間もない私にとっても非常に役立ったのですが、Geolonia社員でなくてもベクトルタイトルってなんぞやと思っている方にも有用で楽しい経験になるんじゃないかと思ったので、その手順を紹介しようと思います。
なお、環境はMacOSを想定しているのでWindowsなどそのほかの環境の方はツールのインストール方法などは適宜読み替えてください。またベクトルタイルを実際にホスティングするにはhttpでなくhttpsで接続できる場所が必要ということで、タイルをGitHub Pagesで配信するためGitHubアカウントを持っていることが前提ではありますが、私が用意したタイルの配信元を公開しているので、それを代わりに使っていただくこともできます。
手順が少し多いので、各手順ごとに章立てしました。以下の5つの手順を順に紹介していきます。
まずはOpenStreetMap上に新たに地物を登録します。離島である男木島といえども、道路や建物などの普通の地物はすでにほぼ登録されているので、まだ登録されていないようなマイナーなものはなんだろう?と周りを見まわしてみます。
目に止まった電柱がまだ登録されていなそうだったので、集会所の周りにある電柱を登録してみることにしました。OpenStreetMapのアカウントを作成し、iPhoneから地物の情報を登録できるGo Map!!をインストールして利用します。
上記はGo Map!!から登録した電柱です。電柱のメーカーや素材、高さといった情報も登録できるので、iPhoneの「計測」アプリを使って実際に電柱の高さを測ってみたりもしました。
電柱やベンチの情報も登録してみるフィールドワークを終えたあと、集会所に戻ってきて続きの作業はPCからおこないます。
OpenStreetMapでベクトルタイル化したいエリアを表示し、左上メニューの「エクスポート」ボタンをクリックします。あまり広いエリアを選択してしまうとベクトルタイルのサイズが巨大になってしまうので、適当なエリアにとどめておきます。今回の例では男木島全体が入るくらいのエリアにしています。
左メニューの「エクスポート」をクリックするとmap.osmというファイルがダウンロードできます。
次にこのmap.osmをGeoJSON形式のファイルに変換します。この変換処理にはosmiumというツールが必要なので、brewでインストールします。
brew install osmium-tool
以下のコマンドでmap.osmをGeoJSON形式のファイルmap.osm.geojsonに変換します。
osmium export map.osm -o map.osm.geojson
ここまで作業を進めてきて、自分が登録した電柱のデータはちゃんとこのファイルに入っているのだろうか?と心配になってきました。Visual Studio Codeを使っている方には、GeoJSONファイルのデータを地図上で簡単に確認できるVSCode Map Previewという拡張機能がおすすめです。この拡張機能を使って確認した結果が以下です。「大日」という登録したメーカー名までちゃんと表示されました。
いよいよベクトルタイルを作成します。tippecanoeというツールが必要なので、brewでインストールします。
brew install tippecanoe
以下のコマンドを実行し、map.osm.geojsonからベクトルタイルを作成します。–output-to-directory=./ogijimaで指定していることによって、タイルはogijimaというフォルダの中に作成されます。–layer=mapによって、後述するレイヤ名をmapに指定しています。
tippecanoe --layer=map --output-to-directory=./ogijima --no-tile-compression --force -P ./map.osm.geojson
ogijimaフォルダ以下をhttps接続できる場所にホスティングします。たとえばGitHubのリポジトリに追加して、GitHub Pagesで公開します。ここの手順は煩雑なので省略しますが、もし自分でベクトルタイルを配置する手順が面倒であれば、男木島周辺のベクトルタイルをGitHub上に置いたhttps://github.com/champierre/ogijimaを代わりにご利用ください。
ここまでの手順で、ベクトルタイルを配信することに成功しました。私が用意したタイルはhttps://champierre.github.io/ogijimaより配信されていますが、このURLをブラウザで開いてもなにも表示されません。実はベクトルタイルはhttps://champierre.github.io/ogijima/14/14292/6521.pbfといった形で配信されており、末尾のスラッシュで区切られた数字は順にz(ズームレベル、0から始まり地図をズームインしていくたびに数が大きくなる)、x(世界全体を正方形のマス目で区切ったとき左端から何個目のタイルにあたるかを示す番号)、y(世界全体を正方形のマス目で区切ったとき上端から何個目のタイルにあたるかを示す番号)をあらわしています。
そしてタイルの中身は地図に表示するあらゆる物(地物)の情報なのですが、後述するレイヤの情報を合わせないとどういった線や色だったり、どういうアイコンとして表示するかが定まっていません。いわばウェブページのHTMLの中身のようなもので、CSSで表すスタイルの情報がないと見た目が定まらないのと似ています。
レイヤの情報を編集するためにMaputnikというツールを使います。次のURLで、Geoloniaで用意しているnotebookというシンプルなスタイルを読み込んだ状態でMaputnikを開きます。
メニューより[Data Sources]を選び、Add New Sourceに以下の情報を入力して、Add Sourceボタンをクリックします。
Source IDはData Sourceの名前なので、ここではこのタイルのデータを表す適当な名前、ogijimaと入力します。Source Typeには、Vector(XYZ URLs)を選択し、URLにはベクトルタイルのURLをxyzの並び順とともに入力します。私の用意したタイルの例では、https://champierre.github.io/ogijima/{z}/{x}/{y}.pbfとなります。zが先頭で、xとyがその次に続くことに注意してください。Min Zoomは0、Max Zoomは14を入力します。tippecanoeを実行したとき、ひとつのタイルのファイルサイズが大きすぎないように最大のズームレベルが自動で調節されます。今回の場合は14のフォルダまでしかできていないので、Max Zoomは14としていますが、それぞれの環境で適宜読み替えてください。
次にレイヤの情報を作成します。左上ロゴの下、Layersの横の[Add Layer]ボタンを押して、以下の情報を入力したあとAdd Layerボタンをクリックします。
IDには、これがogijimaデータソースのpole(電柱)のレイヤ情報であることを示すpole_ogijimaを、TypeにはCircle(円)を選び、Sourceにはさきほど追加したData SourceのIDであるogijimaを入力します。Source Layerは注意が必要で、作成したベクトルタイルのレイヤ名と一致していないといけません。tippecanoeのコマンドを実行するときに、
--layer=map
のように指定したmapを入力しています。
pole_ogijimaを追加すると、男木島のすべてのPoint(点)の情報が表示されるので、Add filterボタンを押して、
power == pole
というフィルタを追加することで、電柱だけをフィルタリングします。最後にPaint propertiesのColorを変更して、赤色にしておきます。
MaputnikでのGUI操作は文章ではわかりにくいかもしれないので、動画でキャプチャしてみました。
最後にメニューの[Export]をクリックし、スタイルの情報が保存されたstyle.jsonとしてファイルにエクスポートします。ダウンロードしたstyle.jsonにアクセスできるように内容をGistにコピーします。
https://gist.github.com/champierre/f3679e2fa8d02051e00af6233b71bfaf
HTMLとCSSで書かれたページを実際に表示して確認するにはブラウザを使います。ベクトルタイルの内容とMaputnikで追加したレイヤの情報を確認するため、ここではGeolonia Mapsを使います。つまり、ウェブページにおけるブラウザの役割を担うのがGeolonia Mapsです。Geolonia Mapsのチュートリアルでも紹介しているEmbed APIを使って地図を表示し、Gist上のstyle.jsonを読み込んで、男木島の電柱を表示するサンプルをCodePenに用意しました。ぜひみなさんが作成したstyle.jsonに置き換えて、自分で追加した地物が表示されるかどうかを確認してみてください。
See the Pen GSI Japan + OSM by Geolonia (@geolonia) on CodePen.
OpenStreetMapで適当な地物を登録した上で、ゼロからベクトルタイルを作成し、地物を実際に表示する方法を紹介しました。できるだけわかりやすく紹介したつもりですが、もしわかりにくところがあったりご質問などあれば@geoloniamapまでお願いいたします。