MapLibre GL JS と japanmesh で地域メッシュを表示する
はじめに
はじめまして、最近 MapLibre を使い始めた @qazsato です。
今まで Leaflet や Google Maps を使って地図サービスを作っていましたが、
ベクトルタイルの触り心地に感動し、現在 MapLibre に書き直しています。
カスタマイズ性も高く、あれこれ触っているうちに、気づけば地図の沼に浸かり始めてます🫠
今回は MapLibre GL JS 上に、地域メッシュを表示する方法をまとめます。
地域メッシュとは
地域メッシュとは、日本全土を緯度・経度に基づき地域を隙間なく網の目(メッシュ)に分けたものです。
このように日本をすっぽり覆います。
80km 地域メッシュ
また各メッシュには、 地域メッシュコード と呼ばれる 4 桁から 11 桁の一意な数字が割り振られており、桁数が大きくなるほど詳細なメッシュとなります。
大きさ毎に以下の8つに分類されます。
一辺の長さ | 区画の種類 | コード桁数 | コード例 |
---|---|---|---|
80km | 第 1 次地域区画 | 4 桁 | 5339 |
10km | 10 倍地域メッシュ (第 2 次地域区画) | 6 桁 | 533945 |
5km | 5 倍地域メッシュ | 7 桁 | 5339452 |
2km | 2 倍地域メッシュ | 9 桁 (末尾 5 固定) | 533945465 |
1km | 基準地域メッシュ(第 3 次地域区画) | 8 桁 | 53394529 |
500m | 2 分の 1 地域メッシュ | 9 桁 | 533945292 |
250m | 4 分の 1 地域メッシュ | 10 桁 | 5339452922 |
125m | 8 分の 1 地域メッシュ | 11 桁 | 53394529221 |
広域から狭域まで幅広くカバーされていますね。
今回はこの地域メッシュを簡単に扱える japanmesh[1] というライブラリを使って MapLibre 上に表示をしてみます。
japanmesh の使い方
何はともあれインストール。
npm install japanmesh
1.緯度経度から地域メッシュコードに変換
一行です。
import { japanmesh } from 'japanmesh'
japanmesh.toCode(35.70078, 139.71475)
=> '53394547112'
2.地域メッシュコードからGeoJSONに変換
これまた一行。
import { japanmesh } from 'japanmesh'
japanmesh.toGeoJSON('53394547112')
=> {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[139.7156250, 35.7010416],
[139.7140625, 35.7010416],
[139.7140625, 35.6999999],
[139.7156250, 35.6999999],
[139.7156250, 35.7010416]
]
]
}
}
今回は、この2つのメソッドを使います。
複数の緯度経度を、地域メッシュコードに変換 (japanmesh.toCode
) し、さらにGeoJSON に変換(japanmesh.toGeoJSON
)し、 MapLibre 上に表示してみます。
MapLibre GL JS への組み込み
まずは地図の生成です。
<div id="map"></div>
import { Map } from 'maplibre-gl'
import { japanmesh } from 'japanmesh'
type Coordinate = [number, number]
type MeshCount = { code: string; count: number }
const MESH_LEVEL = 2000 // 計測したいメッシュレベル。メートルで指定。
// 解析したい緯度経度の配列
const coordinates: Coordinate[] = [
[139.681973, 35.713801],
[139.429988, 35.561738],
// ...
]
const map = new Map({
container: 'map',
style: 'https://tile.openstreetmap.jp/styles/osm-bright-ja/style.json',
center: [139.767125, 35.681236],
zoom: 10
})
次に、地図読み込み後の処理を追加します。
load
後、メッシュ毎に件数を集計して地図に描画します。
map.on('load', () => {
const meshCounts = calcMeshCounts(coordinates, MESH_LEVEL)
const maxCount = Math.max(...meshCounts.map(({ count }) => count))
meshCounts.forEach(meshCount => createGeoJSONLayer(meshCount, maxCount))
})
// メッシュコード毎の件数を集計
function calcMeshCounts (coordinates: Coordinate[], level: number) {
const count: Record<string, number> = {}
coordinates.forEach(([lng, lat]) => {
const code = japanmesh.toCode(lat, lng, level)
count[code] = count[code] ? count[code] + 1 : 1
})
return Object.entries(count).map(([code, count]) => ({ code, count }))
}
// メッシュコード毎の GeoJSON を作成
function createGeoJSONLayer (meshCount: MeshCount, maxCount: number) {
map.addSource(meshCount.code, {
type: 'geojson',
data: japanmesh.toGeoJSON(meshCount.code)
})
map.addLayer({
id: meshCount.code,
type: 'fill',
source: meshCount.code,
paint: {
'fill-color': '#00B0FF',
'fill-opacity': meshCount.count / maxCount
}
})
}
東京23区の銭湯 (2km 地域メッシュ)
出力例です。
東京23区の銭湯の緯度経度を、 2km 地域メッシュで表示してみました。
色が濃いほど銭湯が密集しています。
台東区には銭湯がまだまだ多く残っていそうですね。
おわりに
以上、MapLibre と japanmesh による地域メッシュの可視化でした。
50行程度のコードで、メッシュによる可視化が作成できるのはお手軽ではないでしょうか。
また、地域メッシュコードは国が定めたコード体系であるため、地域メッシュに基づいた統計データ[2]も数多く提供されています。
ぜひ、様々なデータを japanmesh で可視化してみてください。
蛇足
今回取り上げなかったですが、 MapLibre はベクトルタイルなので 3D 表示も可能です。
そのため、テレビでよく見かける 3D 降水量マップも作れます。
MapLibre の fill-extrusion レイヤーを使うことになると思います。
また、気象庁はデータ[3]だけでなく、カラーコード[4]も公開しています。
3D グラフに興味のある方は、この記事の応用編として試してみてはいかがでしょうか。
結果を共有していただければ幸いです😊
Discussion