見出し画像

JavaScriptフレームワークを使わずDeck.GLを動かす最小限のサンプル

配車アプリ世界最大手のひとつであるUberが提供しているDeck.GLというライブラリがあります。地理データ可視化を助けるJavaScriptライブラリで、3Dマップや経路図などの可視化が簡単にできることで知られています。一例として、こんな地理データ可視化が可能です。

Deck.GLは描画のパフォーマンスも非常に高く、優れたライブラリですが、英語・日本語の情報やサンプルコードを見ると、Reactフレームワークで導入している事例が多いようです。今回は、特にフレームワークなどを使わずDeck.GLを動かすための最小限のサンプルを作ってみたいと思います。

(1)データ
取り急ぎ緯度・経度の列を持つCSVなら何でもよいですが、今回はサンプルとして先ほどの例からデータを取得します(GitHub)。中身は緯度経度、地点の種類(RE=住宅地/BS=商業地)、各時点での価格など色々ありますが、今回は緯度経度だけ使います。

"longitude","latitude","landtype","price19","price18","price09","price99","price89","station"
136.54112,35.15128,"RE",22800,22900,26700,NULL,NULL,"麻生田、2300"
136.51900,35.15349,"RE",29400,29500,33800,NULL,NULL,"阿下喜、500"

(2)HTML
HTMLファイルでは関連するJavaScript・CSSライブラリを読み込みます。

<!doctype html>
<html class="no-js" lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.css">
    <link rel="stylesheet" href="style.css"/>
  </head>
  <body>
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.js'></script>
    <script src='https://unpkg.com/deck.gl@5.2.5/deckgl.min.js'></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js'></script>
    <script  src="script.js"></script>
  </body>
</html>

(3)CSS
CSSはスタイルをリセットしてbodyを全画面に表示させるだけです。

@charset "UTF-8";

html, body {
  padding: 0;
  margin: 0;
  width: 100%;
  height: 100%;
}

(4)JavaScript
ここで各種の設定を行います。まず、初期画面で表示される中心座標の緯度経度、およびDeck.GLオブジェクトの設定を行います。ここでズームや表示角度の指定ができます。Deck.GLはMapBoxという地図ライブラリを使っているので、MapBoxのAPIキーを持っていない方は公式ページからアクセストークンを取得してください。

const LAT = 35.8;
const LNG = 139.2;

const deckgl = new deck.DeckGL({
  mapboxApiAccessToken: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
  mapStyle: 'mapbox://styles/mapbox/dark-v9',
  longitude: LNG,
  latitude: LAT,
  zoom: 8,
  pitch: 40,
  bearing: -10
});

次に、データを読み込む関数loadDataの設定をします。ここではd3.jsでCSVファイルを読み込み、配列に変換しています。今回使う列は緯度経度だけなので、dataに格納するのも2列だけです。

const loadData = () => {
  d3.csv("data.csv", (error, response) => {
    data = response.map(function(d) {
      return [
        Number(d.longitude),
        Number(d.latitude)
      ];
    });

    renderLayer(data);
  });
};

続いて、読み込まれたデータをもとにレイヤーを描画します。Deck.GLにはデータ描画のためのレイヤーが何種類も用意されていますが、ここでは座標として与えられたデータを六角形のバーに変換するHexagonLayerというレイヤーを使います。radiusは六角形の半径です。ここでは2000メートルとしています。

const renderLayer = (data) => {
  const hexagonLayer = new deck.HexagonLayer({
    data,
    getPosition: d => d,
    radius: 2000
  });

  deckgl.setProps({
    layers: [hexagonLayer]
  });
}

最後にloadDataの実行部分が入ります。

loadData();

これらのプログラムをすべてコピー&ペーストして実行すると、このような画面が表示されるはずです。

デフォルト設定だと高さは設定されず、色は六角形の中にいくつデータがあるかで決まります。もし各行のデータ(今回の例では地価)を基準として色や高さを設定したい場合、getElevationValueやgetColorValueを使って色・高さの基準となる数値を決めます。他にも光源、カメラの位置・角度、レイヤーの種類など、様々な描画設定を決めることができるので、ぜひ公式ドキュメントも参考にしつつ試してみてください。

いいなと思ったら応援しよう!