今年もゲリラ豪雨や激しい気象変化に悪戦苦闘した感がある。これら変化に迅速に対応すべく、ご多分に漏れず、筆者も各種アプリを通じてデスクトップやスマートフォン、スマートウオッチにアラートが飛んだり、地震を含みササっと確認する仕組みをいくつか使っている。

防災庁も発足し、災害に対する備えにも一層の拍車がかかる昨今だが、身の回りの多くの機器に気象や地震情報が表示されていると、気も引き締まる。二年前にRaspberry PIにリアルタイム地震情報を表示するだけの端末にしておいた(記事)が、強震モニタ(防災科研)なども合わせて表示させておくと、遠方での大きな地震が伝わるまでのリアルタイムな可視化を提供してくれる。気象庁の防災ページ(https://www.jma.go.jp/bosai/)からは地震や天気等様々な情報が可視化されてた形で情報を得られるので、こちらも素早く表示できるようにブックマークしておくと良いだろう。

  • 気象庁の防災ページの衛星

    気象庁の防災ページの衛星

"雲"情報を試験的にのせてみる

さて、現在位置情報をブラウザから取得して、Leaflet.jsとJavaScriptで地図上にメモを残せるHTMLファイルを作成してみた筆者であったが、ここに気象情報を試験的にでものせられないものか?と考えた。なお、気象庁のデータ利用は、気象データ高度利用ポータルサイト(https://www.data.jma.go.jp/developer/index.html)、気象衛星(https://www.data.jma.go.jp/suishin/cgi-bin/catalogue/makeproductpage.cgi?id=Eisei)、公共データ利用規約(第1.0版)(https://www.digital.go.jp/resources/opendata/publicdatalicensev1.0)など一読すべきデータもあるので読んでおくとよいだろう。

さきのページをブラウザで表示させた状態でF12キーを押すとおもだったブラウザではネットワーク解析が行えるがJSONのエンドポイント(https://www.jma.go.jp/bosai/himawari/data/satimg/targetTimes_jp.json)が見える。これを調べていくとhttps://www.jma.go.jp/bosai/himawari/data/satimg/20261111000000/jp/20261111000000/REP/ETC/{z}/{x}/{y}.jpgの形で雲の情報が配置されている。

  • FirefoxでF12の開発者ツールでネットワークをサーチ

    FirefoxでF12の開発者ツールでネットワークをサーチ

https://www.jma.go.jp/bosai/himawari/data/satimg/targetTimes_jp.json

を開くと、JSON形式のデータが表示される。

ここでは、スキル向上の目的で試験的にこのJSONからひまわりの雲データをのせてみる。前回のコードに以下の部分を追記する。

// ひまわり雲画像
fetch("https://www.jma.go.jp/bosai/himawari/data/satimg/targetTimes_jp.json")
.then(r=>r.json())
.then(t=>{
  const d=t.at(-1);

  L.tileLayer(
    `https://www.jma.go.jp/bosai/himawari/data/satimg/${d.basetime}/jp/${d.validtime}/REP/ETC/{z}/{x}/{y}.jpg`,
    {
      opacity:0.4,
      attribution:'気象庁 ひまわり'
    }
  ).addTo(map);
});

fetch(Mozilla.org内API)でjsonファイルから抜き出した情報から.then(Mozilla.org内API)で通信終了後のデータ取り出しを行い、d=t.at(-1)で配列の最後の値を得る。これで最新のひまわりデータをLeaflet.jsのL.tileLayerで接続する。

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Leaflet Test</title>
  <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
  <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
  <style>
    #map { height: 400px; }
    #memos {
      margin-top: 10px;
      font-family: sans-serif;
    }
  </style>
</head>
<body>
  <div id="map"></div>



  <div id="memos"></div>
<script>
  const map = L.map('map').setView([35.68, 139.76], 13);

L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg', {
attribution: '<a href="https://maps.gsi.go.jp/development/ichiran.html">国土地理院タイル</a>'
}).addTo(map);


  //  永続化されたメモを復元(最短3行)
  const list = JSON.parse(localStorage.getItem("memoList") || "[]");
  list.forEach(m => {
    L.marker([m.lat, m.lng]).addTo(map).bindPopup(m.memo);
  });
  // メモ一覧表示
 document.getElementById("memos").innerHTML = list.map(m => m.date + " " + m.lat + "," + m.lng + " " + m.memo).join("<br>");
  const locateControl = L.control({ position: 'topleft' });

  locateControl.onAdd = function () {
    const btn = L.DomUtil.create('button', '');
    btn.innerHTML = '🚩 現在地';

    btn.onclick = function () {
      navigator.geolocation.getCurrentPosition((pos) => {
        const lat = pos.coords.latitude;
        const lng = pos.coords.longitude;

        L.marker([lat, lng]).addTo(map)
          .bindPopup('あなたの現在地')
          .openPopup();

        map.setView([lat, lng], 15);

        //  メモ追加(永続化3行だけ)
        const memo = prompt("この場所のメモを入力");
        if (memo) {
          L.marker([lat, lng]).addTo(map).bindPopup(memo);

          const list = JSON.parse(localStorage.getItem("memoList") || "[]");
          list.push({
             lat,
             lng,
             memo,
             date: new Date().toLocaleString()
          });
          localStorage.setItem("memoList", JSON.stringify(list));

        // ★一覧更新
          document.getElementById("memos").innerHTML = list.map(m => m.date + " " + m.lat + "," + m.lng + " " + m.memo).join("<br>");
        }
      });
    };

    return btn;
  };

  locateControl.addTo(map);

// ひまわり雲画像
fetch("https://www.jma.go.jp/bosai/himawari/data/satimg/targetTimes_jp.json")
.then(r=>r.json())
.then(t=>{
  const d=t.at(-1);

  L.tileLayer(
    `https://www.jma.go.jp/bosai/himawari/data/satimg/${d.basetime}/jp/${d.validtime}/REP/ETC/{z}/{x}/{y}.jpg`,
    {
      opacity:0.4,
      attribution:'気象庁 ひまわり'
    }
  ).addTo(map);
});
</script>

</body>
</html>

これをアップロードしてアクセスしてみる。

  • 雲情報が表示されている

    雲情報が表示されている

  • 実際の気象庁の雲と比較してみた。おおよそあっている

    実際の気象庁の雲と比較してみた。おおよそあっている

  • 拡大すると雲と雪の区別が曖昧になり、極拡大では表示されない

    拡大すると雲と雪の区別が曖昧になり、極拡大では表示されない

あくまで試験用の雲把握でしかないが、表示されるとうれしいものだ。当然のことながら、気象庁はじめ各社のデータ満載のアプリをフル活用して急激な気象変更、地震をはじめとした災害に万全を期待したいと改めて思った。