気象庁HPのデータを使ってみよう（アメダス編）

# 目的
気象庁HPがリニューアルされたので、表示に使われてるデータを使ってみよう。
wgetしてもよいし、xhrで直接読んで来ても使えそう。
（内容は保証しません・・・。）

# 対象データ
アメダス

# 対象データの構成
```
[www.jma.go.jp/bosai/amedas/data/]
- latest_time.txt # 最新時刻
- map/
  - yyyymmddHHMM00.json # 全国の横断データ。10分毎。地図に表示しない要素は省かれる。
- point/
  - [point_code] # アメダス地点コード
    - yyyymmdd_HH # 3時間ごとに区切られたデータ（HH=00,03,06,...）
```

アメダス地点コードを調べるには、URLのamdnoを見ればよい。
http://www.jma.go.jp/bosai/amedas/#area_type=offices&area_code=130000&amdno=44132&format=table1h

地点データが３時間区切りなのは、入電都度１日分のデータを書き換えるとキャッシュの実効性が下がるから・・・かもしれない。訂正報での訂正範囲も最小化できますし。

# データ内容

| キー | 値 |備考|
|:-----|----|---:|
|prefNumber,observationNumber|組み合わせるとアメダス地点コード||
|pressure|現地気圧|hPa|
|normalPressure|海面更正気圧|hPa|
|temp|気温|℃|
|humidity|湿度|％|
|sun10m|１０分間日照時間||
|sun1h|１時間日照時間||
|precipitation10m|前１０分間降水量|mm|
|precipitation1h|前１時間降水量|mm|
|precipitation3h|前３時間降水量|mm|
|precipitation24h|前２４時間降水量|mm|
|windDirection|風向|0～15の16方位（北から時計回り）|
|wind|風速|m/s|
|maxTempTime|この時間までの日最高気温が出た時刻|{hour: HH, minute: MM}|
|maxTemp|この時間までの日最高気温|℃|
|minTempTime|この時間までの日最低気温が出た時刻|{hour: HH, minute: MM}|
|minTemp|この時間までの日最低気温|℃|
|gustTime|日最大風の時刻|{hour: HH, minute: MM}|
|gustDirection|日最大風速の風向|0～15の16方位（北から時計回り）|
|gust|日最大風速|m/s|
|snow|積雪深|cm|
|snow1h|１時間降雪量|cm|
|snow3h|３時間降雪量|cm|
|snow6h|６時間降雪量|cm|
|snow12h|１２時間降雪量|cm|
|snow24h|２４時間降雪量|cm|
値は配列になっており、[値, AQC]。AQCは品質情報で、0なら問題なく利用可能。

# 方針
 1. latest_time.txtから最新の時刻を読み取る
 1. 読み取った時刻から実データ(point)以下のファイル名を作成
 1. 作成したファイル名を取得
 1. 取得した各時刻のファイルを読み取って表示

# テーブルを書いてみる
``` html:index.html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>気象庁データを使ってみよう</title>
  </head>
  <body>
    <div id="target"></div>
    <script src="//code.jquery.com/jquery-3.5.1.min.js"></script>
    <script src="//www.jma.go.jp/bosai/common/js/jmaweb_utility.min.js"></script>
    <script src="app.js"></script>
  </body>
</html>
```
``` javascript:app.js
$(function () {

  var AMEDAS_POINT = '54841'; // アメダス地点コード
  var ELEM = 'temp'; // 表示要素

  // 最新時刻取得
  $.ajax({ url: '//www.jma.go.jp/bosai/amedas/data/latest_time.txt' })
    .done(function (txt) {
      // JSONのURL作成
      var baseTime = new Date(txt);
      var yesterday = new Date(baseTime);
      yesterday.setDate(yesterday.getDate() - 1);
      var baseStr = JMAWebUtility.date.strftime(baseTime, '%Y%m%d_');
      var yesterdayStr = JMAWebUtility.date.strftime(yesterday, '%Y%m%d_');
      var requests = {};
      ['00', '03', '06', '09', '12', '15', '18', '21'].forEach(function (th) {
        requests[yesterdayStr + th] = '//www.jma.go.jp/bosai/amedas/data/point/' + AMEDAS_POINT + '/' + yesterdayStr + th + '.json';
      });
      ['00', '03', '06', '09', '12', '15', '18', '21'].forEach(function (th) {
        if (Number(th) > baseTime.getUTCHours()) return;
        requests[baseStr + th] = '//www.jma.go.jp/bosai/amedas/data/point/' + AMEDAS_POINT + '/' + baseStr + th + '.json';
      });
      // データの取得
      JMAWebUtility.parallelRequest(requests, function (data) {
        // ３時間ごとでは使いにくいので、１つにまとめる。
        var merged = {};
        Object.keys(data).forEach(function (fkey) {
          Object.keys(data[fkey]).forEach(function (timeStr) {
            merged[timeStr] = data[fkey][timeStr];
          });
        });
        // テーブル作成
        var table = $('<table>').appendTo('#target');
        $('<tr>')
          .appendTo(table)
          .append($('<th>').text('時刻'))
          .append($('<th>').text('気温'));
        Object.keys(merged).sort().forEach(function (timeStr) {
          var time = JMAWebUtility.date.createFromString(timeStr);
          $('<tr>')
            .appendTo(table)
            .append($('<td>').text(JMAWebUtility.date.strftime(time, '%Y/%m/%d %H:%M')))
            .append($('<td>').text(merged[timeStr][ELEM][0]));
        });
      });
    });
});
```
ES3な書き方でごめんなさい。適当に書いたのでJSTとUTC間違えてるかもです。
時刻文字列作成や$.whenが微妙に面倒なので気象庁のライブラリ使ってしまいます。

# 結果
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1149177/118faa36-f240-4606-8c83-61ff0b24ea3e.png)