JavaScript
d3.js
地図
geojson
topojson

D3.jsで埼玉県地図を描くときの基本(topojson)

More than 1 year has passed since last update.

D3.jsで日本地図を描くときの基本(geojson)
D3.jsで埼玉県地図を描くときの基本(topojson)
D3.jsで埼玉県の地図上に市町村ラベルを描く

 前回はGeoJSONフォーマットのデータを使って、D3.js(v4)で日本地図を描く方法を紹介しました。今回はTopoJSONフォーマットのデータを使って地図を描く方法を紹介したいと思います。同じ日本地図ではアレなので、今回は埼玉県の地図を描くことにします。

今回作成した埼玉県地図
https://s3-ap-northeast-1.amazonaws.com/kuki-app-bucket/japanmap/saitama.html

1.TopoJSONについて

 GeoJSONは経度緯度の配列をデータとして持っていて、ポイントやライン、ポリゴンを描くことができました。TopoJSONはアーク(弧線)の配列を持っています。しかも境界線のデータを共有するとかして、GeoJSONに比べてデータ量が格段に少なくなります。私が持っている埼玉県のデータで言えば、TopoJSONが422KBで、GeoJSONが3,449KBになります。全然違いますね。

 さてTopoJSONデータフォーマットに対して、そのままではd3.geoPath()を適用できません。D3.jsで地図を描くにはGeoJSONフォーマットに変換する必要があり、そのためにtopojson.jsライブラリを読み込みます。

 以上の注意点を除けば、GeoJSONの時と全く同じプログラムが適用されます。

2.D3.jsのプログラム

 念のためにソースコードを掲載します。TopoJSON=>GeoJSO変換、以外は前回の日本地図のソースと同じです。

<!doctype html>
<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.12.0/d3.min.js" type="text/JavaScript"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.20/topojson.min.js"></script>
  </head>
  <body>
    <svg></svg>
    <script>
      var width = 1200,
          height = 800;
      var scale = 40000;
      d3.json("./saitama.topojson", createMap);

      function createMap(topoSaitama) {
        var geoSaitama = topojson.feature(topoSaitama, topoSaitama.objects[11]); //TopoJSON=>GeoJSO変換
        var aProjection = d3.geoMercator()
            .center([ 139.5, 35.9 ])
            .translate([width/2, height/2])
            .scale(scale);
        var geoPath = d3.geoPath().projection(aProjection);
        var svg = d3.select("svg").attr("width",width).attr("height",height);

        //マップ描画
        var map = svg.selectAll("path").data(geoSaitama.features)
          .enter()
          .append("path")
            .attr("d", geoPath)
            .style("stroke", "#ffffff")
            .style("stroke-width", 0.1)
            .style("fill", "#5EAFC6");

        //ズームイベント設定    
        var zoom = d3.zoom().on('zoom', function(){
            aProjection.scale(scale * d3.event.transform.k);
            map.attr('d', geoPath);
        });
        svg.call(zoom);

        //ドラッグイベント設定
        var drag = d3.drag().on('drag', function(){
            var tl = aProjection.translate();
            aProjection.translate([tl[0] + d3.event.dx, tl[1] + d3.event.dy]);
            map.attr('d', geoPath);
        });
        map.call(drag);
      }
    </script>
  </body>
</html>

 まずtopojson.jsライブラリを読み込みます。

    <script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.20/topojson.min.js"></script>

TopJSONのデータをGeoJSONのフォーマットに変換します。

        var geoSaitama = topojson.feature(topoSaitama, topoSaitama.objects[11]); //TopoJSON=>GeoJSO変換

 それ以外は、前回のプログラムと全く同じです。