Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Mapbox Japan Weather Layers を使った雨雲レーダーのデモ
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Mapbox Japan Weather Layers を使った雨雲レーダーのデモ

地図上で雨雲の現在位置、未来において予測される位置を表示する雨雲レーダーは、日本においてポピュラーなサービスです。気象災害、交通、マーケティングなど様々な分野で活用されています。本ブログでは、気象タイルセットを配信するサービスであるMapbox Japan Weather Layers(以降JWLとも表記)と、Mapbox GLJSを用いて、雨雲レーダーを作成した記録についてお話しします。実際に動くデモをこちらからご覧いただけます。またデモのコードをこちらのGithubレポジトリにて公開しております。

基本的に雨雲等の気象データはGRIB2と呼ばれるバイナリデータで気象庁等から提供されています。これを地図に表示する際には、GRIB2の解析、及びタイルセットへの変換が必要です。このための複雑なパイプラインの構築のほか、絶え間なく更新される気象データをタイルセット化に変換し続けるための高額なインフラストラクチャコストへの対処が必要でした。JWLは、Mapboxで気象データをタイルセット化にして配信するため、従来と異なり、どなたでも気軽に気象データを地図に表示ができます。また、Mapbox Tilequery APIを併用することで、気象データをjson形式で取得可能です。Mapbox Japan Weather Layersについてはこちらをご参考ください。
本ブログで紹介する雨雲レーダーは、次の5つの要素で構成されます。一番下にあるのがベースマップ、その上にJWLのタイルセット、降水量の凡例、表示するタイルセットのband(バンドとも表記)を切り替えるためのタイムスライダー、そして表示されているbandの時刻を表示する時刻ボックスです。
バンドとは、JWLタイルセットの単一時間スライスを指します。各バンドは異なる時間データを表します。例えば、mapbox.weather-jp-nowcastには13の異なる時間バンドが含まれます。これは現在降水量と、5分刻みで最大60分先までの将来降水量をカバーしているためです。データが9:00に開始すると仮定すると、最初のバンドは9:00時点の観測降水量を表します。続くバンドは予測降水量を表し、2番目のバンドは9:05の予測値となります。このパターンはデータの終了時刻である10:00まで続きます。
重要なポイント:ベースマップにはMapboxが提供するmapbox://styles/mapbox/light-v11スタイルを利用しています。レジェンドはJWLタイルセットの色設定に合わせて表示されます。タイムダイアログでは、表示中のバンド(時刻)を日本標準時(JST)に変換して表示します。JWLのタイルセットは以下の4つのタイルセットを利用しており、タイムスライダーで表示するタイルセットのbandを切り替えます。


本デモで利用するタイルセット以外にも、複数のタイルセットが存在します。JWLのタイルセット一覧をご覧ください。
JWL の降水値を「どのように色で表現するか」は、ユーザー体験に直結します。本実装では、気象庁の一般的な降水階級に基づいたカラー表現を採用します。下記では値がない場合や、値が0の場合は、rgbaを0にして透明になるようにしています。また、Mapboxの仕様により、例えば降水強度1mmに相当する色を指定したい場合は、1より低い値(下記では0.99)をコード内で記述する必要があります。
const rasterColorExpression = [
'step',
['raster-value'],
Transparent black
0.05, 'rgba(242, 242, 255, 0.9)',
0.99, 'rgba(160, 210, 255, 0.9)',
4.99, 'rgba(33, 140, 255, 0.9)',
9.99, 'rgba(0, 65, 255, 0.9)',
19.99, 'rgba(250, 245, 0, 0.9)',
29.99, 'rgba(255, 153, 0, 0.9)',
49.99, 'rgba(255, 40, 0, 0.9)',
79.99, 'rgba(180, 0, 104, 0.9)'
];raster-resamplingを'nearest'にすると、一般的な雨雲レーダーと同様に四角いメッシュが並ぶ表現になります。'interpolate'に設定すると、スムージングがかかったような表現になります。
map.addLayer({
id: `rain-layer-${tileset.id}`,
type: 'grid',
source: `rain-source-${tileset.id}`,
paint: {
'raster-array-band': '',
'raster-color': rasterColorExpression,
'raster-color-range': [0, 100],
'raster-opacity': 0,
'raster-resampling': 'nearest',
'raster-color-range-transition': {
duration: 0
}
}
});下の最初の画像は、'nearest'が使用された場合のメッシュの外観を表し、2番目の画像は代わりに'interpolate'が設定された場合を示しています。


時間スライダーを操作するたびに毎回タイルセットをロードすると、UI の遅延や視覚的なチラつきが生じます。そこで本実装では、最初にすべてのJWLのタイルセットを読み込み、タイムスライダーの操作に応じてband(時刻)だけを切り替えるアプローチを採用しています。
map.addSource(`rain-source-${tileset.id}`, {
type: 'raster-array',
url: `mapbox://${tileset.id}`,
tileSize: 1026
});4つの tileset は異なる時間帯をカバーしています。そのため、重複 band の削除、時系列のソート、現在時刻の位置づけを行い、「ひとつの連続した時間スライダー」として利用できる形式に統合します。ユーザーは過去から未来まで、一つの UI 上で自然に操作できます。今回の雨雲レーダーにおける重複bandについては、気象庁のデータの仕様上、現在~未来60分先の雨雲データであるmapbox.weather-jp-nowcastの最後のband(60分先)と、mapbox.weather-jp-rain-1-6の最初のband(1時間先=60分先)が同じ時刻を示す場合があるため、更新頻度がより高いmapbox.weather-jp-nowcastのbandを優先して表示するようにしています。
allBands = [];
let lastNowcastBandId = null;
for (const tileset of sortedTilesets) {
const result = results.find(r => r?.tileset.id === tileset.id);
if (!result || !result.metadata) continue;
const metadata = result.metadata;
if (metadata.raster_layers && metadata.raster_layers.length > 0) {
const layer = metadata.raster_layers[0];
const layerName = layer.name || 'precipitation';
const rawBands = layer.bands || layer.fields?.bands || [];
// Parse and sort bands once
let bandIds = rawBands
.map(b => {
if (typeof b === 'object' && b.band_id) return parseInt(b.band_id);
if (typeof b === 'string' || typeof b === 'number') return parseInt(b);
return NaN;
})
Filter the array to include only values that are not NaN.
.sort((a, b) => a - b);
// Apply filters based on tileset type
if (tileset.id === 'mapbox.weather-jp-nowcast-last-60m') {
// Remove last band (overlaps with nowcast)
if (bandIds.length > 0) {
bandIds = bandIds.slice(0, -1); // ← Remove last band
}
} else if (tileset.id === 'mapbox.weather-jp-rain-1-6') {
// Only keep bands after last nowcast band
if (lastNowcastBandId !== null) {
bandIds = bandIds.filter(b => b > lastNowcastBandId); // ← Filter overlapping bands
}
}
// Track last nowcast band for filtering next tileset
if (tileset.id === 'mapbox.weather-jp-nowcast' && bandIds.length > 0) {
lastNowcastBandId = bandIds[bandIds.length - 1]; // ← Store for comparison
}ユーザーがスライダーを動かすと、表示する band(=時刻)を即座に切り替えます。JWLのタイルセットのopacity(不透明度)を操作することで、表示するband以外のタイルセットは透明になるようにします。例えば、mapbox.weather-jp-nowcastのbandを表示している際は、他の3つのタイルセットのopacityを0にします。
map.setPaintProperty(layerId, 'raster-array-band', band.bandId.toString());
map.setPaintProperty(layerId, 'raster-opacity', 0.85);前述の通り、Mapbox Japan Weather Layersを利用すれば、最小限の技術的労力とコストで雨レーダーなどの天気マップコンテンツを簡単に実装できます。本ブログでご紹介したデモの完全なコードはGitHubリポジトリでご確認ください。
JWL で配信される降水タイルセットは、 日本の防災インフラを支える 気象庁(JMA) の数値予報・実況データが基になっています。

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.