D3.jsで世界地図を表示
世界地図に行ったところの国でも色塗りしようと思いD3.jsで試してみました。
地図データの準備
NatualEarthからダウンロード
今回は、110m Cultural Vectors の Admin 0 – Details / map units を使用。 https://www.naturalearthdata.com/downloads/110m-cultural-vectors/
データの変換
ダウンロードしたshapefileをtopojsonに変換します
使用するパッケージのインストール
npm install -g topojson shapefile
変換(shapefile > geojson > topojson)
shp2json ne_110m_admin_0_map_units.shp | geo2topo -q 1e6 > countries.topojson
ちょい圧縮
toposimplify -P 0.5 -f countries.topojson > countries.min.topojson
不要言語などを削除する場合は、ndjson-cli をインストールして「ndjson-filter "delete d.properties.NAME_AR" 」などでフィルタ。
地図を表示
データが出来たので、あとはD3.jsを使って表示すれば完了です。今回はTypeScript (+Vue.js)で地図を表示。
index.vue
<template> <div id="inspire"> <svg id="svg" :width="width" :height="height" :viewBox="viewBox"> </svg> </div> </template> <script src="./index.ts"></script>
index.ts
import * as d3 from 'd3'; import * as topojson from "topojson-client"; import { Vue, Component } from "vue-property-decorator"; @Component export default class DefaultComponent extends Vue { private width: number = 900; private height: number = 450; private viewBox: string = "0, 0, 900, 450"; private mounted() { // projectionを定義 let projection = d3.geoEquirectangular() // 正距円筒図法(Equirectangular) .translate([this.width / 2, this.height / 2]) // svgの中心 .scale(150); let path = d3.geoPath(projection); // svgに描画 let svg = d3.select("#svg"); d3.json("assets/map.json").then(function (json) { var countries = (topojson.feature(json, json.objects.countries) as any); var view = svg.append("g").selectAll("path") .data(countries.features) .enter() .append("path") .attr("stroke", "black") .attr("stroke-width", 0.5) .attr("fill", function (c: any) { if (c.properties.GU_A3 === "JPN") { return "#0277BD"; } else { return "#ffffff"; } }) .attr("d", path as any); }); } }
日本だけ色塗りされた世界地図の出来上がりです。
Vuetifyできちんと作ってみました(2020/03/27)。
地図の色塗り