Polymerでgoogle mapsのHeatmap layerを使う

2015/08/11 bassy_devops
favorite
Heatmap layer知ってますか

Google Maps JavaScript APIにはHeatmap Layerというものがあります。 これを使うと複数の緯度経度を元に簡単に地図上にヒートマップを表示することができます。 今回はこれをPolymerのgoogle-map elementを使いつつHeatmapの表示とデータの切り替えについて紹介したいと思います。

Polymerとは

Polymerは古いブラウザでもWebComponentsの各技術要素を動作させるためのpolyfillと、その上で実装されたPolymerライブラリ群のことを指します。 詳しくは公式サイトをみてもらうと良いかと思います。 Polymerを使うメリットの一つに宣言的に記述できることがあります。 例えばGoogleMapを表示したい場合、公式サイトにもあるようにgoogle-mapエレメントをimportしたうえで下記のコードを記述するだけで、マーカー付きのGoogleMapを表示することができます。

  <google-map id="gmap" latitude="37.77493" longitude="-122.41942" fit-to-markers>
    <google-map-marker latitude="37.779" longitude="-122.3892"
        draggable="true" title="Go Giants!"></google-map-marker>
    <google-map-marker latitude="37.777" longitude="-122.38911"></google-map-marker>
  </google-map>

今回はPolymerを使いgoogle maps上にheatmap layerを表示するやり方を紹介したいと思います。

Polymer elementを作る

必ずしもPolymerを使う際にimport用にPolymer elementを作成しなくても良いのですが、それだとせっかくの再利用性が失われてしまうので、今回はPolymer elementとして作成していきます。 まずは heatmap-element.html を作成します。

<dom-module id="heatmap-element">

  <style>
    :host {
      width:80%;
      height: 250px;
    }
  </style>
  
  <template>
    <google-map id='gmap2' 
      latitude="37.77493" 
      longitude="-122.41942" 
      libraries="places,visualization" 
      on-google-map-ready="_mapLoaded">
    </google-map>
    <button on-click="handleHeat1">heatmap1</button>
  </template>

  <script>
    Polymer({
      is: "heatmap-element"
    });
  </script>

</dom-module>

ここで作成したheatmap-element.htmlをimportします。

<link rel="import" href="path/to/heatmap-element.html">

次に地図を表示したい場所に読み込んだheatmap-elementタグを入力します。

<heatmap-element></heatmap-element>

すると先ほどと同じようにgoogle-mapが表示されます。

Heatmapを表示する

まずはじめにheatmapを使う場合はlibrariesにvisualizationを指定する必要があります。 指定できるlibrariesはこちらのDocumentを参照してください。 またここで、マップ読み込み完了時に実行されるメソッドも設定します。 ここで気をつける点は、位置データを切り替える時にheatmapをnewして位置データを再設定し、heatmap.setMap(map)しないことです。 setMapするとmap自体に前回のデータをもっているせいか今回設定した分が追加されて表示されてしまいます。 データを切り替える際はheatmap.setData()を使いましょう。 詳細はコードのコメントを参照してください。


<dom-module id="heatmap-element">

  <style>
    :host {
      width:80%;
      height: 250px;
    }
  </style>
  
  <template>
    // librariesにvisualizationを指定します
    // on-google-map-readyにマップ読み込み完了時に実行されるメソッド名を設定します
    <google-map 
      id='gmap2' 
      latitude="37.77493" 
      longitude="-122.41942" 
      libraries="visualization" 
      on-google-map-ready="_mapLoaded">
    </google-map>
    <button on-click="handleHeat1">heatmap1</button>
    <button on-click="handleHeat2">heatmap2</button>
  </template>

  <script>
    // element registration
    Polymer({
      is: "heatmap-element",

      properties: {
        heatmap: Object
      },
      // heatmap1ボタンをクリックすると処理されます。
      handleHeat1: function() {
        var spotData =[];
        spotData.push(new google.maps.LatLng(37.76493, -122.42942));
        var pointArray = new google.maps.MVCArray(spotData);
        this.heatmap.setData(pointArray);
      },
      // heatmap2ボタンをクリックすると処理されます。
      handleHeat2: function() {
        // 位置情報を設定します。
        var spotData =[];
        spotData.push(new google.maps.LatLng(37.77493, -122.41942));
        spotData.push(new google.maps.LatLng(37.77593, -122.41842));
        spotData.push(new google.maps.LatLng(37.77693, -122.41742));
        spotData.push(new google.maps.LatLng(37.77793, -122.41642));
        spotData.push(new google.maps.LatLng(37.77893, -122.41542));
        spotData.push(new google.maps.LatLng(37.78493, -122.40942));
        var pointArray = new google.maps.MVCArray(spotData);
        // ここで、表示するheatmapの内容を切り替えます。
        this.heatmap.setData(pointArray);
      },
      // マップ読み込み完了時に処理されます。
      _mapLoaded: function() {
        var map = this.$.gmap2.map;
        map.zoom = 13;
        this.heatmap = new google.maps.visualization.HeatmapLayer({
          data: []
        });
        // heatmapのインスタンスは使いまわすので、ここでプロパティにセットします。
        this.heatmap.setMap(map);
      }
    });
  </script>

</dom-module>
// 位置データ切り替え時の注意点
  // ダメなパターン
  var spotData.push(new google.maps.LatLng(37.76493, -122.42942));
  var pointArray = new google.maps.MVCArray(spotData);
  this.heatmap = new google.maps.visualization.HeatmapLayer({data: pointArray })
  this.heatmap.setMap(map);
  // 適切な書き方
  var spotData.push(new google.maps.LatLng(37.76493, -122.42942));
  var pointArray = new google.maps.MVCArray(spotData);
  heatmap.setData(pointArray);
  // ※言われれば当たり前のように感じるかとは思いますが、Heatmapに関しての情報も少なくハマるとなかなか苦労します。。。

上記のコードを読み込むとこんな感じの地図が表示されると思います。



最後に

今回はPolymerを使ってHeatmap layerを使う方法を紹介しました。 作成したコードはgithubにも公開してあります。 私が一般的なブログサイトで記事を書かない理由の一つに自由にスクリプトががりがり書けないことがあります。 技術ブログであれば、同じページ内でデモが見れた方が効率的でストレスも少なく見れると思います。 CMSを使うとその辺がどうも難しいので、このサイトは全てHtmlタグから書き起こしています。

最後まで読んで頂きありがとうございました。