D3で地図を描こう!

D3.jsで表示する

データセットを読み込む


	d3.json("dataset/japank.geojson", function(geojson){
		d3.csv("dataset/jinkou.csv", function(csv){
			d3main(geojson, csv);    
		});
	});
	
	function d3main(geojson, csv){
		//ここに地図を表示する処理を書く	
	}
	

D3.js Geo(Geography) ライブラリ

投影法

3次元の立法体を2次元の平面上にに表現する方法
平面の紙に地図を描く場合、必ず歪みが生じてしまい面積・角度・距離を同時に全て正しく表示することはできない。そのため地図の使用用途に合わせて投影法を選ぶ必要がある。

D3で使える投影法

D3 Geo Projections

D3にはプラグインを含め非常に多くの投影法をあつかう機能があります。目的や用途に合わせて選択しましょう。

また、表示した地図の投影法を変更して描画をアップデートすることで、投影法から別の投影法へアニメーションしながら変更する演出なども行えます

今回は、投影法として一般的によく使用されるメルカトル図法を使用します

メルカトル図方

一般によく見かける地図はこの投影法を用いて描かれていることが多い。
正角円筒図法と呼ばれる投影法の一つ、任意の二点間を結んだ直線と経線のなす角度が正しく描かれるが、面積や方位、距離に関して歪みが出る。(経度が高い場所ほど面積や距離が拡大される)

参照:メルカトルの呪い?地図のおはなし

projection関数の生成



	var projection = d3.geo
		.mercator()		//投影法の指定
		.scale(サイズ指定)	//スケール(ズーム)の指定
		.center([経度(long), 緯度(lat)]); //中心の座標を指定
	
	

path関数の生成



	var path = d3.geo.path()
		.projection(projection); //projection関数を渡す
	
	

地図を表示する


	var svg = d3.select("svg");

	var g = svg.append('g')
		.attr("transform", "translate("+[-100, 100]+")"); //地図の表示位置調整

	g.selectAll("path")
		.data(geojson.features) //フィーチャーオブジェクトを渡す
		.enter()
		.append("path")
		.attr("d", path); //d属性にpath関数を指定 function(d){ return path(d) } を省略
	
	

地図に色を塗る

各PathにClass名を付ける

geoJSON(地形データ)の属性データPREFの値をクラス名に設定します


	svg.selectAll("path")
		.data(geoJson.features)
		.enter()
		.append("path")
		.attr("d", path)
		.attr("class", function(d){ return d.properties.PREF }); //PREFの値をpathのclass名として適用 
	

データの最小値、最大値を取得する

csv(人口データ)の最少値、最大値を取得します。


	var min = d3.min(csv, function(d){ return +d["人口"] });
	var max = d3.max(csv, function(d){ return +d["人口"] });
	

戻り値に「+」を付けているのはイデオムです。効果はparseInt関数と同じ。
数値型へ型変換を行っています。

カラースケールを設定します

人口の最少値から最大値までの範囲を色で返す関数を作成します。


	var colorScale = d3.scale.linear()
		.domain([min, max]) //人口値の範囲
		.range(["#0000cc", "#cc0000"]); //カラー値
	

地図に色を塗ります

csvデータを一つづつ処理しながら該当するクラス名のPath要素にfill属性を適応します。


	csv.map(function(d){
		var color = colorScale(d['人口']); //人口の値を元にカラーを取得
		d3.select("."+d['都道府県']) //該当するクラス名をセレクト
			.attr("fill", color); //カラーを適用
	});
	

全コード


d3.json('dataset/japank.geojson', function(json){
    d3.csv('dataset/jinkou.csv', function(csv){
        d3main(geojson, csv);    
    });
});

function d3main(geojson, csv){

    var projection = d3.geo.mercator()
        .center([139, 35])
        .scale(1200);
	
    var path = d3.geo.path().projection(projection);
    
    var svg = d3.select('svg');
    
    var g = svg.append('g')
        .attr("transform", "translate("+[-100, 100]+")");
    
    var map = g.selectAll('path')
        .data(geojson.features)
        .enter()
        .append('path')
        .attr({
            "class":function(d){ return d.properties.PREF},
            d: path,
            stroke: 'blue'
        });
    
    var min = d3.min(csv, function(d){ return +d['人口'] });
    var max = d3.max(csv, function(d){ return +d['人口'] });

    var colorScale = d3.scale.linear()
	.domain([min, max])
	.range(["#FFcccc", "#cc0000"]);
    
    csv.map(function(d){
        var color = colorScale(d['人口']);
        d3.select("."+d['都道府県']).attr("fill", color);
    });
    
}

完成!

でも?

人口の多い県と、少ない県の見分けが難しい

もっと見やすくしてみよう!

カラースケールを改良します

最少値、最大値の他に中央値を取得し、中央値以下の県と以上の件で色を変える。


	var median = d3.median(csv, function(d){ return +d['人口'] }) //中央値の取得
	
	var colorScale = d3.scale.linear()
		.domain([min, median, max]) 
		.range(["blue","green", "red"]); 
	

最小値に近い県は青く、中央値に近い県は緑に、最大値に近い県は赤く表示されます。

D3で地図をつくろう まとめ

参考

/

#