Yahooリアルタイム震度(強震モニタ)から、リアルタイム震度を取得する。

# 概要
NIED(防災科学技術研究所)が提供している強震モニタは、GIF形式で配信されているので、
各観測地点のリアルタイム震度を取得するのが難しかった。
(最近は、利用規約が更新されて、使用できなくなったのもある。)
Yahooが提供している[リアルタイム震度](https://typhoon.yahoo.co.jp/weather/jp/earthquake/kyoshin/)は、JSONで配信し、それをクライアント側で描画している方式なので、NIEDよりもデータが手に入れやすい。
だから、Yahooリアルタイム震度を使い、各観測地点のリアルタイム震度を取得する。
# 取得方法
## 配信されるJSON
Yahooリアルタイム震度では、
https://weather-kyoshin.west.edge.storage-yahoo.jp/RealTimeData/{年}{月}{日}/{年}{月}{日}{時}{分}{秒}.json
という形式のJSONファイルで、震度を配信している。
配信されるJSONファイルは、以下のような形式になっている。
```json:https://weather-kyoshin.west.edge.storage-yahoo.jp/RealTimeData/20210213/20210213230833.json
{
  "realTimeData":
  {
    "dataTime":"2021-02-13T23:08:33+09:00",
    "siteConfigId":"20191010150000",
    "intensity":"qcoqpcpoqrcsprcdddddddddddddccdddgddcddcdddcddcddc...以下略"},
    "psWave":
    {
      "items": 
      [
        {
          "latitude":"N37.7",
          "longitude":"E141.8",
          "pRadius":"306.923",
          "sRadius":"164.467"
        }
      ]
    },
    "hypoInfo":
    {
      "items":
      [
        {
          "reportTime":"2021-02-13T23:08:22+09:00",
          "regionCode":"289",
          "regionName":"福島県沖",
          "longitude":"E141.8",
          "isCancel":"false",
          "depth":"50km",
          "calcintensity":"6-",
          "isFinal":"false",
          "isTraining":"false",
          "latitude":"N37.7",
          "originTime":"2021-02-13T23:07:50+09:00",
          "magnitude":"7.1",
          "reportNum":"18","reportId":"20210213230800"
        }
      ]
    },
    "estShindo":null,
    "copyright":
    [
      "National Research Institute for Earth Science and Disaster Resilience",
      "Yahoo Japan Corporation"
    ],
    "version":"2.0"
}
```
ここで、緊急地震速報などの情報を取得する場合は、psWaveやhypoInfoを見ていくのだが、
今回は、リアルタイム震度を取得したいので、intensityを見ていく。
## intensityの見方
intensityは、略さず書くと以下のようになる。(長い文字の羅列となる。)
```json:intensity
qcoqpcpoqrcsprcdddddddddddddccdddgddcddcdddcddcddcddddddccddcddddddjcddddcccdcdedddccmconrpcpnnonddddddddddddcdedcfdddddddcdddddddddddddddddddddddddddcddchccddkghchddccdddcdddddcdicddddddcfdfdcddddddcddddddddcdddddcddddddddddjdddmkdmjnmolmnonpcdddddddcccdddeddddedddddddddcddcccdcccdddcdddddddddddcdcccddcdvvtwutvssrpcdddddddddddhccdddddcddddddddddddddccdddddddddddieddeddcdddddddeddddddddcddddddddddcdddddddedffeddddpqqcopponommnnkkkhcihcrqmoiddcdcdddddddddddcddclmpoqpqsqpnccoscdcdddfddddddcdddddddddfcddcddddddddddcdccdmndgcjdlcccddedddddcddddddddddedddcddnvuvutcucuvrtsmnpccpndddddcddcddcddcdddddddddddcddddidddmhgdknlfdddddddddddddcdcdpcnnljjjcgdcdpcpolmddcddddddcfddddcdcdddddddddddcddcddcddcddgfdddddkudedddssptdfcddcccctomnfccdifddgddfffdfcddddcdehdehdedgdddddhdrddddeddhdddddkdodddddccccccdeddfddddcfcdeddddddgcddddnjmdjohhphnoeigdddkddeliddodduqdfddfddmgndiecefdddedoioddjndklopdpqddodddddcjnmgkjdkdjddudeeedlddddjgddddddgddkmddddukddddddfdhtmddddffdqcpdsdgddddfedqdqgededodddcddgdddeddrddddfddddddodmjnddcddddllddgdddodgdeuedneevlgdgdoddddddddcmndefenqnnoddddkgdddddeeeoddnejdmddldmddrnocdddgemjnnkkiqdcddcdidmlkdqtdlimppd
```
これは、1文字が、1観測点に結びついていて、合計で1133文字あるから、
1133観測点のリアルタイム震度を表している。
### intensityの各文字
震度を取得するには、まず、intensityの各文字を、Unicodeに変換する。
例として、上の文字の``q``をあげる。
``q``をUnicodeに変換すると、``\u0071``となる。
そして、変換したUnicodeのインデックスを10進数に変換し、100を引く。
``\u0071 = 113``で``113 - 100 = 13``となる。
つまり、``q``という文字は、``震度13``を表しているのである。

:::note warn
ただし、これで取得できる震度は、揺れの大きさを表すYahoo独自の震度であり、
気象庁などが使用している、一般的な震度とは異なるもので、
0 ~ 20の21段階の震度である。

追記:0 ~ 20の21段階の震度というのは、[NIEDの強震モニタ](http://www.kmoni.bosai.go.jp/)の目盛りにある
-3 ~ 7の震度を、さらに区間ごとに2分割する、つまり、
-3 -2.5 -2 -1.5 -1 -0.5 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 7
となるようになっていることがわかりました。
:::
## 観測地点の位置
[intensityの見方](#intensityの見方)で、intensityの各文字が、震度を表していると分かった。
しかし、その文字が表している震度が、どこの観測点のものなのかが分からなくては意味がない。
それを取得するために、Yahooリアルタイム震度が、描画する時に使用しているJSONデータを利用する。
### 観測位置のデータの見方
観測地点の位置をあらわすデータは、
https://weather-kyoshin.west.edge.storage-yahoo.jp/SiteList/sitelist.json
にある。
intensityの各文字は、このJSONデータの順番の通りに、震度を表しているので、
このJSONデータの通りに当てはめていけば、震度と観測点の位置を結びつけることができる。

:::note warn
ただし、このJSONは、Yahooリアルタイム震度で、描画する時に使用されているデータなため、
普通の位置座標ではなく、Yahooリアルタイム震度専用の座標を表している。
だから、Yahooリアルタイム震度と同じ形式のマップにしなくてはならない。
:::
## 震度別の色
[intensityの見方](#intensityの見方)で得られる震度は、注意書きの通り、
Yahoo独自の0 ~ 20の21段階の震度となっている。
それだと、利用する際に大きさがイメージしづらい。
だから、Yahooリアルタイム震度では、何色で描画しているかを取得する。
### 震度別の色をあらわすCSS
Yahooリアルタイム震度では、SVGの``<circle>``を使い、各観測地点の震度を描画している。
その際に、色をつけるために、``<circle>``に、``kyoshin_si-{震度}``というクラスを付与している。

:::note warn
例外として、震度が取得できなかった場合は、
``kyoshin_si-none``や、``kyoshin_si--1``となる。
:::
そして、そのクラスに紐づいているCSSを、
https://s.yimg.jp/images/weather/pc/v2/css/kyoshin-1.0.0.css
で見ることができる。
そのCSSでは、色を以下のように定義している。
```css:色をあらわすCSS
.kyoshin_si--1,.kyoshin_si-none{display:none}
.kyoshin_si-20{fill:#b600d7;stroke:#b600d7}
.kyoshin_si-19{fill:#c900ba;stroke:#c900ba}
.kyoshin_si-18{fill:#dc009c;stroke:#dc009c}
.kyoshin_si-17{fill:#e30071;stroke:#e30071}
.kyoshin_si-16{fill:#ed0047;stroke:#ed0047}
.kyoshin_si-15{fill:#f11520;stroke:#f11520}
.kyoshin_si-14{fill:#f53605;stroke:#f53605}
.kyoshin_si-13{fill:#fc4c02;stroke:#fc4c02}
.kyoshin_si-12{fill:#ff6200;stroke:#ff6200}
.kyoshin_si-11{fill:#ff7e00;stroke:#ff7e00}
.kyoshin_si-10{fill:#f90;stroke:#f90}
.kyoshin_si-9{fill:#ffaf00;stroke:#ffaf00}
.kyoshin_si-8{fill:#fbc300;stroke:#fbc300}
.kyoshin_si-7{fill:#f4e200;stroke:#f4e200}
.kyoshin_si-6{fill:#0fb02b;stroke:#0fb02b}
.kyoshin_si-5{fill:#38a477;stroke:#38a477}
.kyoshin_si-4{fill:#5ea7ac;stroke:#5ea7ac}
.kyoshin_si-3{fill:#71a2cb;stroke:#71a2cb}
.kyoshin_si-2{fill:#89afc8;stroke:#89afc8}
.kyoshin_si-1{fill:#90b3ca;stroke:#90b3ca}
.kyoshin_si-0{fill:#97b7cc;stroke:#97b7cc}
```
つまり、このCSSで定義されている色を見ることで、
Yahoo独自の震度は、どれぐらいの大きさなのかを見ることができる。

:::note info
[Yahooリアルタイム震度](https://typhoon.yahoo.co.jp/weather/jp/earthquake/kyoshin/)にある目盛りで、
``<circle>``の色と、一般的な震度の関係の目安を見ることができる。
:::

# まとめ
Yahooリアルタイム震度が使用している、JSONデータや、CSSなどを見ることで、
各観測地点のリアルタイム震度を取得することができた。
(もしも、規約違反などの問題があったら教えてくださいお願いします。)
(また、初記事なので、おかしいところがあるかもしれません。ごめんなさい。)

# 参考文献
https://qiita.com/Conripi/items/a22b11d4aece5106793b#comment-319d9413e3b1ea7ae8dd

(@wolf20482さんのコメントの部分を参考にしました)

---
:::note alert
Yahooに対して、許可をとっておらず、勝手に利用しているため、
使用する場合は、最低でも1秒間はアクセス間隔を取るようにし、
節度を守って利用してください。
トラブルや損害に関して、一切保証しません。
:::