1923

都内と業界の隅っこで生活しているエンジニアのノート

D3.jsで世界地図を表示

世界地図に行ったところの国でも色塗りしようと思いD3.jsで試してみました。

地図データの準備

NatualEarthからダウンロード

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);
        });
    }
}

日本だけ色塗りされた世界地図の出来上がりです。

f:id:taka1923:20200119183924p:plain

Vuetifyできちんと作ってみました(2020/03/27)。
地図の色塗り