d3.jsのおべんきょうのためにやる。
データの取得
ベースとなる東京都の地図
http://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N03.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は以下のとおり。
<!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から取れる情報をのっけたい。