とある目的で気象庁のアメダス情報のJSONデータをゴニョゴニョしているのですが、まずアメダス情報のJSONはこういう感じになってる。
$ curl -s https://www.jma.go.jp/bosa20221101000000.json | jq | head -100 { "11001": { "temp": [ 6.9, 0 ], "humidity": [ 93, 0 ], "snow1h": [ 0, null ], "snow6h": [ 0, null ], "snow12h": [ 0, null ], "snow24h": [ 0, null ], "sun10m": [ 0, 0 ], "sun1h": [ 0, 0 ], "precipitation10m": [ 0, 0 ], "precipitation1h": [ 0, 0 ], "precipitation3h": [ 0, 0 ], "precipitation24h": [ 0, 0 ], "windDirection": [ 9, 0 ], "wind": [ 4.5, 0 ] }, "11016": { "pressure": [ 1024.3, 0 ], "normalPressure": [ 1025.8, 0 ], (snip)
数字のキーの下に天気予報や気温などのデータが入っている。このキーが観測所のキーになってる。
観測所は別のJSONで参照できる。こんな感じで。
$ curl -s https://www.jma.go.jp/bosai/amedas/const/amedastable.json | jq { "11001": { "type": "C", "elems": "11112010", "lat": [ 45, 31.2 ], "lon": [ 141, 56.1 ], "alt": 26, "kjName": "宗谷岬", "knName": "ソウヤミサキ", "enName": "Cape Soya" }, "11016": { "type": "A", "elems": "11111111", "lat": [ 45, 24.9 ], "lon": [ 141, 40.7 ], "alt": 3, "kjName": "稚内", (snip)
で、特定の観測所名のキーが取れれば、その地点のアメダス情報が取れるんだけど、この観測所のIDがキーになってるのが難しいところ。
例えばこうやってみる。
$ curl -s https://www.jma.go.jp/bosai/amedas/const/amedastable.json | jq 'select(.[].kjName == "札幌")' { "11001": { "type": "C", "elems": "11112010", "lat": [ 45, 31.2 ], "lon": [ 141, 56.1 ], "alt": 26, "kjName": "宗谷岬", "knName": "ソウヤミサキ", "enName": "Cape Soya" }, (snip) "14163": { "type": "A", "elems": "11111111", "lat": [ 43, 3.6 ], "lon": [ 141, 19.7 ], "alt": 17, "kjName": "札幌", "knName": "サッポロ", "enName": "Sapporo" }, (snip)
このJSONは一つの大きなオブジェクトになっているので、下位の階層でselectしても上位からたどったデータが全部表示されてしまう。
次にこれ。
$ curl -s https://www.jma.go.jp/bosai/amedas/const/amedastable.json | jq '.[] | select(.kjName == "札幌")' { "type": "A", "elems": "11111111", "lat": [ 43, 3.6 ], "lon": [ 141, 19.7 ], "alt": 17, "kjName": "札幌", "knName": "サッポロ", "enName": "Sapporo" }
配列の皮むきというか殻割りというみたいだけど、1階層展開してしまうと今度はキーが取れなくなってしまう。
そこでto_entries
を使う。
These functions convert between an object and an array of key-value pairs. If to_entries is passed an object, then for each k: v entry in the input, the output array includes {"key": k, "value": v}.
to_entriesを使うと、オブジェクトをキーと値の配列に変換してくれて、かつ、"key"と"value"というキー名を追加してくれる。
$ curl -s https://www.jma.go.jp/bosai/amedas/const/amedastable.json | jq '. | to_entries' [ { "key": "11001", "value": { "type": "C", "elems": "11112010", "lat": [ 45, 31.2 ], "lon": [ 141, 56.1 ], "alt": 26, "kjName": "宗谷岬", "knName": "ソウヤミサキ", "enName": "Cape Soya" } }, { "key": "11016", "value": { "type": "A", "elems": "11111111", "lat": [ 45, 24.9 ], (snip)
これで観測所名を元に観測所IDを取得することができる。
$ curl -s https://www.jma.go.jp/bosai/amedas/const/amedastable.json | jq '. | to_entries[] | select(.value.kjName == "札幌")' { "key": "14163", "value": { "type": "A", "elems": "11111111", "lat": [ 43, 3.6 ], "lon": [ 141, 19.7 ], "alt": 17, "kjName": "札幌", "knName": "サッポロ", "enName": "Sapporo" } }
めっちゃ便利。
ということで、観測所名を引数で風向き・風速を返してくれるサンプルをbashで書いてみた。
$ ./getWindInfo.sh 東京 東京 の風向きは北、風速 2.2 メートルです $ ./getWindInfo.sh 大阪 大阪 の風向きは北北東、風速 3.2 メートルです