地図に区名を表示する
前回作成した横浜市地図に、区名ラベルを入れてみたいと思います。
とりあえず、ラベルを貼るソースコードを追加してみます。L78-92が追記箇所です。
index.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="ja"> | |
<head> | |
<meta charset="utf-8"> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script src="http://d3js.org/topojson.v0.min.js"></script> | |
<style type="text/css"> | |
h1 { | |
font-size: 16px; | |
} | |
svg { | |
border: 1px solid #aaaaaa; | |
} | |
.subunit-boundary { | |
fill: none; | |
stroke: #777; | |
stroke-dasharray: 2,2; | |
stroke-linejoin: round; | |
} | |
.cityname-label { | |
fill-opacity: .5; | |
font-size: 8px; | |
font-weight: 300; | |
text-anchor: middle; | |
} | |
</style> | |
<title>Yokohama city map</title> | |
</head> | |
<body> | |
<h1>Yokohama city map</h1> | |
<div id="map"></div> | |
<script type="text/javascript"> | |
var map_width = 500; | |
var map_height = 650; | |
var svg; | |
d3.json("yokohama_topo.json", function(error, json) { | |
if( !error ) { | |
main(json); | |
} | |
return; | |
}); | |
function main(topo) { | |
var labelLineHight = 16; | |
// svgを追加 | |
svg = d3.select("body").append("svg") | |
.attr("width", map_width) | |
.attr("height", map_height); | |
// 横浜市のmapを描画する | |
var yokohama = topojson.object(topo, topo.objects.yokohama); | |
console.log(yokohama); | |
// 横浜市を中心に指定したメルカトル図法で10万分の1で描画する | |
var projection = d3.geo.mercator() | |
.center([139.59,35.45]) | |
.scale(100000) | |
.translate([map_width / 2, map_height / 2]); | |
// pathを作成する | |
var path = d3.geo.path().projection(projection); | |
svg.append("path") | |
.datum(yokohama) | |
.attr("d", path); | |
// 色を塗る | |
svg.selectAll("path").attr("fill", "#bee59e"); | |
// 内部境界に線を引く | |
svg.append("path") | |
.datum(topojson.mesh(topo, topo.objects.yokohama, function(a, b) { return a !== b; })) | |
.attr("d", path) | |
.attr("class", "subunit-boundary"); | |
// 区名ラベル貼り | |
svg.selectAll(".cityname-label") | |
.data(yokohama.geometries) | |
.enter() | |
.append("text") | |
.attr("class", function(d) { | |
return "cityname-label"; | |
}) | |
.attr("transform", function(d) { | |
return "translate(" + path.centroid(d) + ")"; | |
}) | |
.attr("dy", ".35em") | |
.text(function(d) { | |
return d.properties.name; | |
}); | |
} | |
</script> | |
</body> | |
</html> |
前回の記事でTopoJSONを作成するときに、区名をnameプロパティに設定して書き出していました。
topojson -p name=N03_004 -p name -o yokohama_topo.json yokohama.geojson
元のGeoJSONファイルのN03_004フィールドには区名が入っていたのでした。
Safariでプロパティを確認してみます。
確かに、データ要素を覗いてみると、d.properties.nameに”青葉区”と入っています。これをラベルとして素直に出力したのが今回のコードです。実行結果は次の通り。(下の画像をクリックすると、地図ページに飛びます)
出来た・・・と思ったら、区名が重複して出力されてしまいました。島など境界線が分かれている箇所は、データ上それぞれ別要素になっているので、余計なラベルまで貼られてしまいました。
次回は、この問題を解決しようと思います。
ではではまたね