[Mapbox]世界地図のGeoJSONデータをマップに表示する。

前回の記事で、世界地図ポリゴンデータのGeoJSONを取得しました。
これを使って、Mapboxの地図上に表示します。

また、Nextjsはセットアップ済みの前提で解説します。
本記事のNextjsのバージョンは”13.5.4″となります。

目次

Layerを作成

MapboxはLayerをつかって読み込んだGeoJSONデータを可視化します。

ここでは、ポリゴンとラインに分けて、それぞれ定義します。

GeoJSONがもつプロパティ「WOE_ID」が特定の値に一致した時にredの色にします。それ以外は#abdda4としています。
「WOE_ID」とは、Yahooによって割り当てられている地球上のあらゆる地物を識別する32ビット識別子です。
ここでは、日本をredにしています。

export const polygonLayer: FillLayer = {
  id: "polygon",
  type: "fill",
  paint: {
    "fill-color": [
      "match",
      ["get", "WOE_ID"],
      23424856,
      "red", // Red when WOE_ID is 23424856
      "#abdda4", // Otherwise, default color
    ],
    "fill-opacity": 0.7,
  },
};

ラインの色も定義していきます。
黒色に2pxのライン幅にしています。

export const lineLayer: LineLayer = {
  id: "outline",
  type: "line",
  paint: {
    "line-color": "#3b3b3b",
    "line-width": 2,
  },
};

まとめるとこんな感じです。

import type { FillLayer, LineLayer } from "react-map-gl";

export const polygonLayer: FillLayer = {
  id: "polygon",
  type: "fill",
  paint: {
    "fill-color": [
      "match",
      ["get", "WOE_ID"],
      23424856,
      "red",
      "#abdda4",
    ],
    "fill-opacity": 0.7,
  },
};

export const lineLayer: LineLayer = {
  id: "outline",
  type: "line",
  paint: {
    "line-color": "#3b3b3b",
    "line-width": 2,
  },
};

GeoJSONを読み込む

今回は、GeoJsonデータをプロジェクト内に置いておきます。
それを参照して、FeatureCollection型をつけて読み込みます。

asで型付けしていますが、API経由などの時は別途、型付けをしたほうが良さそうです。

react-map-glでは、Sourceコンポーネントのdataプロパティに渡すことでマップ上に展開できます。

import * as React from "react";
import { useRef } from "react";
import Map, { NavigationControl, Source } from "react-map-gl";
import type { FeatureCollection } from "geojson";
/**
 * Original data for GeoJson 
 * https://www.naturalearthdata.com/
 */
import CountriesData from "@/data/ne_50m_admin_0_countries.json";

export default React.memo(function MapboxComponent() {
  const CountryFeatureCollection = useRef<FeatureCollection>(CountriesData as FeatureCollection);

  return (
    <Map
      id="map"
      mapboxAccessToken={process.env.NEXT_PUBLIC_MAP_BOX_TOKEN}
      initialViewState={{
        zoom: 1,
      }}
      reuseMaps
      mapStyle="mapbox://styles/mapbox/streets-v11"
    >
      <NavigationControl />
      <Source type="geojson" data={CountryFeatureCollection.current}></Source>
    </Map>
  );
});

Layerを読み込んでMapに表示する。

Sourceコンポーネントに作成したLayerコンポーネントを渡します。
今回は色付けしたポリゴンデータ、ラインデータを利用します。
ここで定義することで、Sourceのdataプロパティに渡したデータを元に、Layerを使って表示できるようになります。

      <Source type="geojson" data={CountryFeatureCollection.current}>
        <Layer {...polygonLayer} />
        <Layer {...lineLayer} />
      </Source>

コードの全体はこんな感じです。

import * as React from "react";
import { useRef } from "react";
import Map, { Layer, NavigationControl, Source } from "react-map-gl";
import type { FeatureCollection } from "geojson";
/**
 * Original data for GeoJson 
 * https://www.naturalearthdata.com/
 */
import CountriesData from "@/data/ne_50m_admin_0_countries.json";
import { lineLayer, polygonLayer } from "./mapStyle";

export default React.memo(function MapboxComponent() {
  const CountryFeatureCollection = useRef<FeatureCollection>(CountriesData as FeatureCollection);

  return (
    <Map
      id="map"
      mapboxAccessToken={process.env.NEXT_PUBLIC_MAP_BOX_TOKEN}
      initialViewState={{
        zoom: 1,
      }}
      reuseMaps
      mapStyle="mapbox://styles/mapbox/streets-v11"
    >
      <NavigationControl />
      <Source type="geojson" data={CountryFeatureCollection.current}>
        <Layer {...polygonLayer} />
        <Layer {...lineLayer} />
      </Source>
    </Map>
  );
});

作成したコンポーネントを表示したいページで呼び出します。
無事、MapboxにGeoJsonデータを表示できました。

Summary

簡単に表示できるのがMapboxの強みかなと思います。でも、公式ドキュメントのLayerのExpressionsはわかりにくいと思う。

よかったらシェアしてね!
目次