Edited at

Mapbox GL JSを使って自転車事故場所マップをWebGLな地図で描画するの巻

More than 3 years have passed since last update.


はじめに

Mapbox GL JSは、WebGLとJavaScriptを使ってベクトル地図を描画するライブラリです。ラスタ地図と比較して、滑らかに動かしたり地図を傾けたりなどすることができます。今回はこれを使って鳥取県オープンデータを使って自転車事故の発生場所のデータをマッピングしてみました。

Mapbox GL JSがどんなものかを知るには、Mapbox GL JS Examplesにいろんなサンプルがあるのでこちらを見ると楽しいです。例えば、Google Earthっぽくスムーズに指定した地点へ飛んだり(Slowly fly to location)、地図を傾けたり(Set initial pitch and bearing)できる地図を簡単に扱えます。

今回は、前回のアドベントカレンダー(鳥取県オープンデータで自転車事故の発生場所マップを作ってみたの巻)のデータをMapboxでWebGLな地図で表示するようにしてみました。

先にできたものをお見せします。

実際に動くデモは http://tottori.2574.jp で公開しています。またソースコードも https://github.com/mh61503891/2574 に公開しています。

(※この記事を書いた後に機能追加などしているので、記事とデモが少し違う点はご了承ください。)


開発


準備

まず、MapboxのアカウントとAPI access tokensを取得します。API access tokensが無いとMapboxの地図データを受け取ることができません。

開発に必要なドキュメントは、主に以下の2つかと思います。APIリファレンスとExamplesです。

ちなみに、Mapbox JS APIのAPIとは異なるのでごちゃ混ぜにならないように注意しましょう。(なりました。)


必要なファイル一覧

今回はこの4つです。.geojson.jsに入れてしまってもいいし、.js.css.htmlに入れてしまって1ファイルでやってしまう手もありますが、4つくらい分けておいたほうが無難かと思います。


  • example.html

  • example.js

  • example.css

  • example.geojson


ウェブサーバの起動

example.geojsonを読むにあたって、ウェブブラウザではローカルファイルは何かと参照させてくれないので、とりあえずウェブサーバを起動してしまいます。私は、ちょっとサンプルを動かしたりする時や面倒な時はRubyで以下のようにしてWebサーバを立ち上げてコーディングしています。もちろん、ウェブブラウザのオプションでローカルファイルへのアクセスを許可する仕方も良いかもです。

ruby -rwebrick -e 'WEBrick::HTTPServer.new({DocumentRoot:"./", Port:3000}).start'


GeoJSONの作成

マップに表示したいピンのデータを作成します。の前回のアドベントカレンダー(鳥取県オープンデータで自転車事故の発生場所マップを作ってみたの巻)で作成した https://gist.github.com/mh61503891/a2572598fa40f5bd0c08 を使います。

GistもMapboxを使ってGeoJSONを地図に表示してくれますので、Gistでうまく地図が表示されていれば、まずデータに問題はないっぽいです。

必要であれば以下のコマンドでダウンロードしてみてください。

wget 'https://gist.githubusercontent.com/mh61503891/a2572598fa40f5bd0c08/raw/b1068ed744137575faf4b36f7c7af5ab66b50406/tottori-opendata-bicycle-accident-2014.geojson' -O example.geojson


HTMLの作成

Exampleから少し加工したものです。mapbox-gl.jsmapbox-gl.cssを読み込むのと、<div id='map'></div>を書いておくのがポイントです。


example.html

<!DOCTYPE html>

<html>
<head>
<meta charset=utf-8 />
<title>Example</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.12.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.12.0/mapbox-gl.css' rel='stylesheet' />
<link href='example.css' rel='stylesheet' />
</head>
<body>
<div id='map'></div>
<script src='example.js'></script>
</body>
</html>


CSSの作成

スマートフォンで全画面っぽく見えるようにmarginやらpaddingやらを0に詰めています。まあこれが無いと根本的に動かないといったものではないです。


example.css

body {

margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}


JavaScriptの作成

ここからが重要です。以下の4つが必要です。


example.js

// アクセストークンの設定

mapboxgl.accessToken = '<API access token>';

// 鳥取県の真ん中あたりの場所
var position = new mapboxgl.LngLat(133.842941, 35.375086).wrap();

// 地図のインスタンスを作成
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v8',
center: [position.lng, position.lat],
zoom: 8
});

// データのソースファイル
var source = new mapboxgl.GeoJSONSource({
data: './example.geojson'
});

// 地図へのデータソースとレイヤのバインド
map.on('style.load', function() {
map.addSource("example-data", source);
map.addLayer({
type: 'symbol',
source: 'example-data',
layout: {
'icon-image': 'marker-15'
}
});
});


あとはウェブブラウザでアクセスすればOKです。


おわりに

Mapbox GL JSでWebGLの地図を作ってみました。気になった点がいろいろ。


  • Mapbox GL JSのAPIリファレンスをもう少し親切にしてほしい。わかりづらさあり。


  • Mapbox JSのExamplesMapbox GL JSのExampleのサンプルのバリエーションをある程度は揃えてほしい。Mapbox JSのサンプルコードはあるけどMapbox GL JSには無いんだけどやり方わからん〜。むき〜。

  • マーカーの色の変え方がわからん〜。JSはできるけどGL JSはなんか動かへん。なんでや。

  • WebGL、結構、重たい。


    • iPhone 5s → けっこう重い。ネイティブのマップに比べると重すぎ。iPhone 3の頃のレスポンス感。iPhone 6sだともうちょいましなのかな?iPhone 6sは持ってないので未確認。

    • Nexus 6 → まぁまぁ。さくさく。



  • iOSで「ホームボタンに追加」してから起動するとまぁまぁ良い感じ。

  • Androidで「ホーム画面に追加」してから起動するとほぼアプリっぽくて良い。AndroidのChromeは、ウェブブラウザから通知機能とかも使えるらいしAndroidに変えようかなと気持ちがゆらぐなど。ウェブブラウザだけそこそこ実用的なカーナビとか作れそう。

  • どっちも横向き対応。

次回は現在地の追従などにトライしようかとおもっています。