D3.js로 도도부현별 지도 그리기
시구정촌 레벨의 지도 데이터는 국토 지리원의 지구지도 이나 국토 교통성의 국토 수치 정보 에서 다운로드할 수 있습니다.
국토지리원의 데이터는, 정령 지정 도시(삿포로시라든지)의 구가 알려지지 않고, 시구정촌명도 로마자 표기였으므로, 국토 교통성의 국토 수치 정보를 사용하기로 했습니다.
행정구역 데이터의 전국을 선택하여 다운로드합니다. (도도부현별의 파일도 있습니다만, 귀찮아서 전국 데이터로부터 각 도도부현 데이터를 추출합니다.)
N03-160101_GML.zip
라는 파일이 다운로드되므로 (엄청 시간이 걸렸지만), 압축을 풀고 N03-16_160101.shp
라는 파일을 사용합니다.extract_pref.sh
#! /bin/sh
for i in `seq 1 47`
do
if [ $i -lt 10 ]; then
i=0$i
fi
ogr2ogr -f GeoJSON -where "N03_007 like '$i%'" pref/ward.json N03-16_160101.shp
topojson -s 0.000000001 -p N03_003 -p N03_004 -p N03_007 -o pref/pref$i.json pref/ward.json
rm pref/ward.json
done
이런 식으로 도도부현별 TopoJSON 파일을 47개 만듭니다.
덧붙여서 N03_003과 N03_004에 이름이, N03_007에 시구정촌 코드가 들어가 있습니다.
그대로는 너무 세세한 (파일이 커져 표시에 시간이 걸린다) 때문에, -s 옵션으로 조금 거칠게 하고 있습니다.
pref.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>D3 Test</title>
<style type="text/css">
.ward {
fill: #fff;
stroke: #aaa;
}
svg {
background: #eff;
padding: 40px;
}
</style>
</head>
<body>
<script src="http://d3js.org/d3.v4.min.js"></script>
<script src="http://d3js.org/topojson.v2.min.js"></script>
<script type="text/javascript">
var pref_code = location.search.match(/code=([0-9]+?)(&|$)/);
if (pref_code) {
pref_code = pref_code[1];
} else {
pref_code = '01';
}
var width = 960,
height = 640,
padding = 40;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var projection = d3.geoMercator()
.translate([width / 2, height / 2]);
var path = d3.geoPath()
.projection(projection);
d3.json("pref/pref" + pref_code + ".json", function(error, pref) {
var topo = topojson.feature(pref, pref.objects.ward);
projection
.center(d3.geoCentroid(topo))
.fitSize([width, height], topo);
svg.selectAll(".ward")
.data(topo.features)
.enter()
.append("path")
.attr("class", function(d) {
return "ward ward-" + d.properties.N03_007;
})
.attr("d", path)
.on("mouseover", function(d) {
d3.selectAll(".ward-" + d.properties.N03_007).style("fill", "#f99");
var label = d.properties.N03_003 ? d.properties.N03_003 : '';
label += d.properties.N03_004 ? d.properties.N03_004 : '';
svg.append("text")
.attr("x", d3.event.offsetX - padding - 20)
.attr("y", d3.event.offsetY - padding - 15)
.attr("class", "ward-label")
.text(label);
})
.on("mouseout", function(d) {
d3.selectAll(".ward-" + d.properties.N03_007).style("fill", "#fff");
svg.select(".ward-label").remove();
});
});
</script>
</body>
</html>
d3.js 버전 4라면
projection.fitSize()
에서 좋은 느낌의 scale로 해주는 것이 기쁘다! (scale을 어떻게 계산하면 좋을지 모르고 좌절했다…)pref.html?code=01
와 같이 액세스하면 홋카이도의 지도가 표시되고, 마우스 오버로 시구정촌명이 나옵니다.padding이 js로 잡히지 않아서 두 번 쓰고 있는 것이 이마이치입니다만…
Reference
이 문제에 관하여(D3.js로 도도부현별 지도 그리기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ran/items/711ce80207e67f98676a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)