lisia's diary

思いつきでVimとか、その他プログラミングとか…

D3.jsで地図を回転させる

前回まで弄っていた日本地図から少し離れ、今回は別の投影法を試してみます。

orthographic

D3.jsには、様々な投影法が用意されています。
その中でも今回はorthographicを使用してみます。
この投影法を使うと、地球儀みたいなものが作れちゃいそうです。 exampleはこちら

地図を描画し、回転させるところまでやってみます。

投影法の指定

前回の日本地図ではメルカトル図法を採用していました。
今回はこのような指定をします。

var projection = d3.geo.orthographic()
  .scale(200)
  .translate([w / 2, h / 2])
  .clipAngle(90)
  .rotate([x, y, z]);

d3.geo.orthographic()とした部分と、clipAngle()rotate()以外は前回と同じです。

clipAngle(度数)は、指定した角度分の陸地が見えるようなイメージです。
90と指定すると、90度分だけ描画されます。
180を指定すると、180度分描画されるので、裏側で見えないはずの陸地まで描画されます。
なかなか面白いことになります。

海に色をつける

陸地以外が白では味気ないので、海に色をつけてみます。
こちらを参考にさせていただきました。
ということで、地図を描画する前に円を描画しておきます。

svg.append('circle')
  .attr({
    cx: w / 2,
    cy: h / 2,
    r: 200,
    fill: '#333399'
  });

描画する

世界の地形データから、あらかじめtopojsonを作成しておきます。
あとは、日本地図の時と同じです。
マウスオーバーで国を赤で表示します。

var features = topojson(data, data.objects.world).features;

var earth = svg.selectAll('path')
  .data(features)
  .enter()
  .append('path')
  .attr({
    // いろいろ指定
  })
  .on({
    'mouseover': function () {
      // 処理
    },
    'mouseout': function () {
      // 処理
    }
  }); 

回転させる

ここまではほぼほぼ日本地図の時と同じです。
次は地図を回転させてみます。
d3.timer()使用し、一定時間ごとに処理させます。

d3.timer(function () {
  x += 5;
  y += 1;
  z += 1;
  projection.rotate([x, y, z]);
  earth.attr('d', path);
}, 500);

500ミリ秒毎に、xを+5、yとzを+1させるようにしてみました。
動きはしているのですが、どうもError: Invalid value for attribute d=""が出ているようで...。
まだ解決はできていません。つらみ。

作ったサンプル

次回は何をしよう。。。