Edited at

d3.jsで東京メトロの地下鉄路線図を作成する

More than 3 years have passed since last update.

d3.jsのおべんきょうのためにやる。


データの取得


ベースとなる東京都の地図

http://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N03.html から取得。チェックボックスで東京だけを指定する。


路線図

http://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N02-v2_2.html


ツールの取得

QGISを落とす。

http://qgis.org/ja/site/


データの加工


GeoJSONへの変換


23区地図

地図データはshpファイルとなっているので、これをGeoJsonに変換する。ogr2ogrコマンドでやる方法もあるが、せっかくなのでツールを使う。

QGISを起動して、「レイヤ -> ベクタレイヤの追加」を選択し、ダウンロードした地図データのshpファイルを読み込ませる。すると、東京都の地図が表示される(小笠原諸島も表示されるので小さくみえる

東京メトロは23区が表示できればだいたいこと足りるので、23区のみをフィルターする。

レイヤパネルで今読み込んだレイヤを右クリックして「フィルタ」を選ぶ。

で、「プロバイダ特有フィルタ式」に

"N03_003" LIKE "%区%"

と指定する。"N03_003"には行政区域名が入っているので、これで23区に絞り込める。

最後に、レイヤパネルで今読み込んだレイヤを選択した状態で、「レイヤ -> 名前をつけて保存」で、エンコーディングをUTF-8にして、GeoJSON形式で保存する。


路線図

読み込む際に形式を空間参照システムを聞かれたら、JGD2000を選択。

フィルタの条件は

"N02_004" = '東京地下鉄'

フィルタをかけたら、地図のときと同様に、GeoJSONとして保存する。


GeoJSONをTopoJSONに変換

GeoJSONに http://www.pasco.co.jp/recommend/word/word040/ にあるようなトポロジー情報をエンコードしたもの(たぶん)

必要なツールは

http://ja.d3js.node.ws/blocks/mike/map/

ここを参考に。

topojson -p name=N03_003 -o tokyo.json tokyo.geojson

topojson -p name=N02_003 -o metro_road.json metro_road.geojson

N03_003に記載されている区/路線名をname属性に変換して出力します。


地図への出力

HTMLは以下のとおり。


index.html

<!DOCTYPE html>

<meta charset="utf-8">
<style>
.subunit-boundary {
fill: none;
stroke: #777;
stroke-dasharray: 2,2;
stroke-linejoin: round;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v0.min.js"></script>
<script>
var width = 400,
height = 400;

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

d3.json("tokyo.json", function(error, json) {
var tokyo = topojson.object(json, json.objects.tokyo);
// 2Dへのマッピング方法を定義
var projection = d3.geo.mercator()
.center([139.7531, 35.6859])
.scale(50000)
.translate([width / 2, height / 2]);

// path生成
var path = d3.geo.path().projection(projection);
svg.append("path")
.datum(tokyo)
.attr("d", path);

// 境界線
svg.append("path")
.datum(topojson.mesh(tjson, json.objects.tokyo, function(a, b) { return a !== b; }))
.attr("d", path)
.attr("class", "subunit-boundary");

// 路線図
// 描画順の保障のために、地図表示後に実施
d3.json("metro_road.json", function(error, json) {
var path = d3.geo.path().projection(projection);
var road = topojson.object(json, json.objects.metro_road).geometries;
svg.selectAll("path")
.data(road)
.enter()
.append('path')
.attr('d', path)
.attr('fill-opacity', 0)
.attr('stroke', "#777")
.attr('stroke-opacity', 1)
.attr('stroke-width', '1px');
});
});
</script>
</body>
</html>


とりあえず表示できた。


感想


  • 各メソッドをとてもふわったとした理解でやっているので、d3.jsの仕様をちゃんと理解したい。

  • 路線ごとに色分けとかもやりたい。

  • メトロAPIから取れる情報をのっけたい。