├── .gitignore ├── .gitattributes ├── screenshot ├── forecast-diary.png ├── forecast-insert.png └── forecast-minibuffer.png ├── example-data ├── jma-amedas-latest-time.txt.el ├── jma-forecast-overview_week-仙台.json.el ├── jma-forecast-overview-福島.json.el ├── jma-forecast-福島-20220222-1117.json.el ├── jma-forecast-福島-20220222-0008.json.el ├── jma-forecast-長野-20220225-0846.json.el ├── jma-forecast-福島-20220223-0501.json.el ├── jma-forecast-week_area05.json.el ├── jma-amedas-4416-20220226_09.json.el ├── jma-forecast-福島-20220221-0753.json.el ├── jma-forecast-week_area_name.json.el ├── jma-forecast-東京-20220222-2212.json.el ├── jma-forecast-東京-20220222-0010.json.el ├── jma-forecast-東京-20220222-0827.json.el ├── jma-forecast-東京-20220221-0754.json.el ├── jma-forecast-week_area.json.el ├── jma-amedas-4416-20220226_06.json.el └── jma-forecast-area.json.el ├── jma-area.el ├── README.org ├── jma-amedas.el ├── jma-utils.el ├── docs ├── how-to-get-jma-area-info.org └── how-to-get-jma-forecast.org ├── jma-weather-code.el └── jma-forecast.el /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.elc 3 | README.html 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.el encoding=utf-8 2 | *.org encoding=utf-8 3 | -------------------------------------------------------------------------------- /screenshot/forecast-diary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/misohena/el-jma/main/screenshot/forecast-diary.png -------------------------------------------------------------------------------- /screenshot/forecast-insert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/misohena/el-jma/main/screenshot/forecast-insert.png -------------------------------------------------------------------------------- /screenshot/forecast-minibuffer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/misohena/el-jma/main/screenshot/forecast-minibuffer.png -------------------------------------------------------------------------------- /example-data/jma-amedas-latest-time.txt.el: -------------------------------------------------------------------------------- 1 | ;;(jma-http-body (jma-http-get "https://www.jma.go.jp/bosai/amedas/data/latest_time.txt")) 2 | "2022-02-26T10:30:00+09:00" 3 | -------------------------------------------------------------------------------- /example-data/jma-forecast-overview_week-仙台.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-json-get "https://www.jma.go.jp/bosai/forecast/data/overview_week/040000.json") 2 | ( 3 | (publishingOffice . "仙台管区気象台") 4 | (reportDatetime . "2022-02-21T16:36:00+09:00") 5 | (headTitle . "東北地方週間天気予報") 6 | (text . "予報期間 2月22日から2月28日まで 7 |  向こう一週間は、気圧の谷や寒気の影響により、日本海側は曇りで、雪または雨の降る日が多いでしょう。太平洋側は曇りや晴れで、期間のはじめと終わりは雪または雨の降る所がある見込みです。 8 |  最高気温と最低気温はともに、期間の前半は平年より低い日が多く、かなり低い日もありますが、後半は平年より高い日が多く、かなり高い所もあるでしょう。") 9 | ) 10 | -------------------------------------------------------------------------------- /example-data/jma-forecast-overview-福島.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-json-get "https://www.jma.go.jp/bosai/forecast/data/overview_forecast/070000.json") 2 | 3 | ((publishingOffice . "福島地方気象台") 4 | (reportDatetime . "2022-02-21T16:39:00+09:00") 5 | (targetArea . "福島県") 6 | (headlineText . "") 7 | (text . "日本付近は強い冬型の気圧配置となっています。 8 | 9 | 福島県は、雪の降っている所が多くなっています。 10 | 11 | 21日夜は、強い冬型の気圧配置のため、雪で、ふぶく所が多いでしょう。 12 | 13 | 22日は、冬型の気圧配置が続くため、中通りと会津では、雪や曇りで、ふぶく所がある見込みです。浜通りでは、曇りや晴れで、雪の降る所があるでしょう。 14 | 15 | <天気変化等の留意点> 16 | 22日は、中通りと会津では大雪による交通障害、電線や樹木への着雪、なだれに注意してください。中通りと浜通りでは、最低気温がかなり低くなる見込みです。路面の凍結や水道管の凍結に注意してください。")) 17 | -------------------------------------------------------------------------------- /example-data/jma-forecast-福島-20220222-1117.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-forecast-data "070000") 2 | 3 | [ 4 | ((publishingOffice . "福島地方気象台") 5 | (reportDatetime . "2022-02-22T11:00:00+09:00") 6 | (timeSeries 7 | . [ 8 | ((timeDefines . ["2022-02-22T11:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00"]) (areas . [((area (name . "中通り") (code . "070010")) (weatherCodes . ["200" "210" "101"]) (weathers . ["くもり 所により 雪" "くもり 昼過ぎ から 時々 晴れ 所により 朝 まで 雪" "晴れ 時々 くもり"]) (winds . ["西の風 やや強く" "西の風 日中 やや強く" "西の風"])) ((area (name . "浜通り") (code . "070020")) (weatherCodes . ["201" "101" "101"]) (weathers . ["くもり 時々 晴れ 所により 雪" "晴れ 時々 くもり 所により 未明 雪" "晴れ 時々 くもり"]) (winds . ["西の風 やや強く" "北西の風 日中 西の風 やや強く" "北西の風"]) (waves . ["2メートル 後 1.5メートル" "1.5メートル" "1.5メートル"])) ((area (name . "会津") (code . "070030")) (weatherCodes . ["402" "402" "205"]) (weathers . ["雪 時々 くもり" "雪 昼前 から 時々 くもり" "くもり 時々 雪"]) (winds . ["西の風" "西の風" "西の風"]))])) 9 | ((timeDefines . ["2022-02-22T12:00:00+09:00" "2022-02-22T18:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-23T06:00:00+09:00" "2022-02-23T12:00:00+09:00" "2022-02-23T18:00:00+09:00"]) (areas . [((area (name . "中通り") (code . "070010")) (pops . ["20" "30" "30" "20" "10" "10"])) ((area (name . "浜通り") (code . "070020")) (pops . ["20" "20" "20" "10" "0" "0"])) ((area (name . "会津") (code . "070030")) (pops . ["60" "70" "70" "60" "50" "50"]))])) 10 | ((timeDefines . ["2022-02-22T09:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-23T09:00:00+09:00"]) 11 | (areas 12 | . [((area (name . "福島") (code . "36127")) (temps . ["1" "1" "-3" "3"])) 13 | ((area (name . "小名浜") (code . "36846")) (temps . ["6" "6" "-3" "5"])) 14 | ((area (name . "若松") (code . "36361")) (temps . ["0" "0" "-3" "1"])) 15 | ((area (name . "白河") (code . "36667")) (temps . ["1" "1" "-5" "1"])) 16 | ((area (name . "郡山") (code . "36476")) (temps . ["1" "1" "-4" "1"])) 17 | ((area (name . "相馬") (code . "36151")) (temps . ["3" "3" "-4" "3"])) 18 | ((area (name . "田島") (code . "36641")) (temps . ["-3" "-3" "-7" "-3"]))]) 19 | )]) 20 | ) 21 | ((publishingOffice . "福島地方気象台") 22 | (reportDatetime . "2022-02-22T11:00:00+09:00") 23 | (timeSeries 24 | . [ 25 | ((timeDefines . ["2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00" "2022-03-01T00:00:00+09:00"]) 26 | (areas . [((area (name . "中通り・浜通り") (code . "070100")) (weatherCodes . ["210" "101" "101" "101" "201" "101" "201"]) (pops . ["" "20" "20" "20" "30" "20" "30"]) (reliabilities . ["" "" "A" "A" "A" "A" "A"])) ((area (name . "会津") (code . "070030")) (weatherCodes . ["402" "205" "200" "201" "260" "201" "260"]) (pops . ["" "60" "40" "30" "50" "30" "50"]) (reliabilities . ["" "" "B" "A" "C" "B" "C"]))]) 27 | ) 28 | ((timeDefines . ["2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00" "2022-03-01T00:00:00+09:00"]) 29 | (areas . [((area (name . "福島") (code . "36127")) (tempsMin . ["" "-1" "0" "0" "1" "2" "1"]) (tempsMinUpper . ["" "0" "2" "2" "4" "4" "3"]) (tempsMinLower . ["" "-4" "-1" "-2" "-4" "-3" "-3"]) (tempsMax . ["" "5" "8" "12" "10" "12" "11"]) (tempsMaxUpper . ["" "7" "10" "14" "13" "14" "15"]) (tempsMaxLower . ["" "3" "6" "10" "8" "10" "8"])) ((area (name . "若松") (code . "36361")) (tempsMin . ["" "-2" "-2" "-5" "-2" "-1" "-1"]) (tempsMinUpper . ["" "-1" "-1" "-2" "1" "1" "0"]) (tempsMinLower . ["" "-6" "-4" "-9" "-7" "-7" "-7"]) (tempsMax . ["" "3" "5" "8" "8" "8" "8"]) (tempsMaxUpper . ["" "4" "7" "11" "10" "10" "12"]) (tempsMaxLower . ["" "0" "1" "6" "5" "6" "6"]))]) 30 | ) 31 | ]) 32 | (tempAverage (areas . [((area (name . "福島") (code . "36127")) (min . "-0.5") (max . "8.3")) ((area (name . "若松") (code . "36361")) (min . "-2.6") (max . "5.5"))])) 33 | (precipAverage (areas . [((area (name . "福島") (code . "36127")) (min . "3.5") (max . "14.9")) ((area (name . "若松") (code . "36361")) (min . "9.3") (max . "20.6"))])) 34 | ) 35 | ] 36 | -------------------------------------------------------------------------------- /example-data/jma-forecast-福島-20220222-0008.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-forecast-data "070000") 2 | 3 | [ 4 | ((publishingOffice . "福島地方気象台") 5 | (reportDatetime . "2022-02-21T17:00:00+09:00") 6 | (timeSeries 7 | . [ 8 | ((timeDefines . ["2022-02-21T17:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00"]) 9 | (areas 10 | . [ 11 | ((area (name . "中通り") (code . "070010")) (weatherCodes . ["205" "204" "201"]) (weathers . ["くもり 夜のはじめ頃 雪 で ふぶく" "くもり 明け方 一時 雪 で ふぶく" "くもり 時々 晴れ"]) (winds . ["西の風 やや強く" "西の風 やや強く" "西の風"])) 12 | ((area (name . "浜通り") (code . "070020")) (weatherCodes . ["200" "201" "201"]) (weathers . ["くもり 所により 雪" "くもり 昼前 から 夕方 晴れ 所により 朝晩 雪" "くもり 時々 晴れ"]) (winds . ["西の風 やや強く 海上 では 西の風 強く" "西の風 やや強く 海上 では はじめ 西の風 強く" "北西の風"]) (waves . ["2.5メートル" "2メートル" "1.5メートル"])) 13 | ((area (name . "会津") (code . "070030")) (weatherCodes . ["400" "402" "205"]) (weathers . ["雪 で ふぶく" "雪 で ふぶく 時々 くもり" "くもり 時々 雪"]) (winds . ["西の風 やや強く" "西の風 やや強く" "西の風"])) 14 | ])) 15 | ((timeDefines . ["2022-02-21T18:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-22T06:00:00+09:00" "2022-02-22T12:00:00+09:00" "2022-02-22T18:00:00+09:00"]) 16 | (areas 17 | . [ 18 | ((area (name . "中通り") (code . "070010")) (pops . ["50" "50" "30" "20" "30"])) 19 | ((area (name . "浜通り") (code . "070020")) (pops . ["30" "20" "10" "10" "20"])) 20 | ((area (name . "会津") (code . "070030")) (pops . ["70" "60" "60" "60" "70"])) 21 | ])) 22 | ((timeDefines . ["2022-02-22T00:00:00+09:00" "2022-02-22T09:00:00+09:00"]) 23 | (areas 24 | . [ 25 | ((area (name . "福島") (code . "36127")) (temps . ["-3" "1"])) 26 | ((area (name . "小名浜") (code . "36846")) (temps . ["-3" "5"])) 27 | ((area (name . "若松") (code . "36361")) (temps . ["-3" "0"])) 28 | ((area (name . "白河") (code . "36667")) (temps . ["-6" "2"])) 29 | ((area (name . "郡山") (code . "36476")) (temps . ["-4" "1"])) 30 | ((area (name . "相馬") (code . "36151")) (temps . ["-4" "3"])) 31 | ((area (name . "田島") (code . "36641")) (temps . ["-7" "-3"]))])) 32 | ]) 33 | ) 34 | 35 | ((publishingOffice . "福島地方気象台") 36 | (reportDatetime . "2022-02-21T17:00:00+09:00") 37 | (timeSeries 38 | . [ 39 | ((timeDefines . ["2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00"]) (areas . [((area (name . "中通り・浜通り") (code . "070100")) (weatherCodes . ["204" "201" "101" "101" "101" "201" "101"]) (pops . ["" "20" "20" "20" "20" "30" "20"]) (reliabilities . ["" "" "A" "A" "A" "A" "A"])) ((area (name . "会津") (code . "070030")) (weatherCodes . ["402" "205" "204" "200" "200" "206" "200"]) (pops . ["" "80" "50" "40" "30" "50" "40"]) (reliabilities . ["" "" "C" "B" "A" "C" "C"]))])) 40 | ((timeDefines . ["2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00"]) (areas . [((area (name . "福島") (code . "36127")) (tempsMin . ["" "-2" "-2" "1" "1" "2" "2"]) (tempsMinUpper . ["" "-1" "0" "3" "2" "5" "3"]) (tempsMinLower . ["" "-4" "-4" "-1" "-2" "-3" "-1"]) (tempsMax . ["" "3" "5" "9" "12" "11" "12"]) (tempsMaxUpper . ["" "4" "7" "11" "14" "14" "15"]) (tempsMaxLower . ["" "1" "3" "7" "10" "9" "8"])) ((area (name . "若松") (code . "36361")) (tempsMin . ["" "-3" "-3" "-1" "-4" "-2" "0"]) (tempsMinUpper . ["" "-2" "-2" "0" "-2" "1" "1"]) (tempsMinLower . ["" "-6" "-6" "-6" "-9" "-7" "-6"]) (tempsMax . ["" "1" "1" "6" "8" "8" "8"]) (tempsMaxUpper . ["" "2" "3" "8" "10" "11" "11"]) (tempsMaxLower . ["" "-2" "-1" "4" "6" "6" "6"]))])) 41 | ]) 42 | (tempAverage (areas . [((area (name . "福島") (code . "36127")) (min . "-0.6") (max . "8.2")) ((area (name . "若松") (code . "36361")) (min . "-2.7") (max . "5.3"))])) 43 | (precipAverage (areas . [((area (name . "福島") (code . "36127")) (min . "3.5") (max . "14.4")) ((area (name . "若松") (code . "36361")) (min . "9.4") (max . "20.8"))])) 44 | ) 45 | ] 46 | -------------------------------------------------------------------------------- /example-data/jma-forecast-長野-20220225-0846.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-forecast-get "200000") 2 | 3 | [ 4 | ( 5 | (publishingOffice . "長野地方気象台") 6 | (reportDatetime . "2022-02-25T08:00:00+09:00") 7 | (timeSeries 8 | . [ 9 | ((timeDefines . ["2022-02-25T05:00:00+09:00" "2022-02-26T00:00:00+09:00"]) 10 | (areas 11 | . [ 12 | ((area (name . "北部") (code . "200010")) (weatherCodes . ["101" "100"]) (weathers . ["晴れ 時々 くもり" "晴れ 夜 くもり"]) (winds . ["南の風 後 北の風" "南の風"])) 13 | ((area (name . "中部") (code . "200020")) (weatherCodes . ["101" "100"]) (weathers . ["晴れ 時々 くもり" "晴れ 夜 くもり"]) (winds . ["南の風 後 北の風" "南の風"])) 14 | ((area (name . "南部") (code . "200030")) (weatherCodes . ["101" "100"]) (weathers . ["晴れ 時々 くもり" "晴れ 夜 くもり"]) (winds . ["北の風 日中 南の風" "北の風 後 南の風"])) 15 | ]) 16 | ) 17 | ((timeDefines . ["2022-02-25T06:00:00+09:00" "2022-02-25T12:00:00+09:00" "2022-02-25T18:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-26T06:00:00+09:00" "2022-02-26T12:00:00+09:00" "2022-02-26T18:00:00+09:00"]) 18 | (areas 19 | . [ 20 | ((area (name . "北部") (code . "200010")) (pops . ["20" "20" "10" "10" "0" "0" "10"])) 21 | ((area (name . "中部") (code . "200020")) (pops . ["10" "10" "0" "0" "0" "0" "10"])) 22 | ((area (name . "南部") (code . "200030")) (pops . ["0" "10" "0" "0" "0" "0" "10"])) 23 | ])) 24 | ((timeDefines . ["2022-02-25T09:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-26T09:00:00+09:00"]) 25 | (areas 26 | . [ 27 | ((area (name . "長野") (code . "48156")) (temps . ["5" "5" "-6" "9"])) 28 | ((area (name . "松本") (code . "48361")) (temps . ["6" "6" "-6" "10"])) 29 | ((area (name . "諏訪") (code . "48491")) (temps . ["5" "5" "-7" "8"])) 30 | ((area (name . "飯田") (code . "48767")) (temps . ["8" "8" "-5" "10"])) 31 | ((area (name . "軽井沢") (code . "48331")) (temps . ["3" "3" "-10" "6"])) 32 | ])) 33 | ]) 34 | ) 35 | 36 | ( 37 | (publishingOffice . "長野地方気象台") 38 | (reportDatetime . "2022-02-24T17:00:00+09:00") 39 | (timeSeries 40 | . [ 41 | ((timeDefines . ["2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00" "2022-03-01T00:00:00+09:00" "2022-03-02T00:00:00+09:00" "2022-03-03T00:00:00+09:00"]) 42 | (areas 43 | . [ 44 | ((area (name . "北部") (code . "200010")) (weatherCodes . ["101" "101" "260" "201" "260" "201" "201"]) (pops . ["" "10" "50" "20" "50" "30" "30"]) (reliabilities . ["" "" "C" "A" "C" "A" "B"])) 45 | ((area (name . "中部・南部") (code . "200100")) (weatherCodes . ["101" "101" "201" "101" "200" "201" "201"]) (pops . ["" "10" "30" "10" "40" "30" "30"]) (reliabilities . ["" "" "B" "A" "C" "A" "A"])) 46 | ]) 47 | ) 48 | ((timeDefines . ["2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00" "2022-03-01T00:00:00+09:00" "2022-03-02T00:00:00+09:00" "2022-03-03T00:00:00+09:00"]) 49 | (areas 50 | . [ 51 | ((area (name . "長野") (code . "48156")) (tempsMin . ["" "-8" "-2" "-3" "-2" "-2" "-2"]) (tempsMinUpper . ["" "-4" "0" "0" "-1" "0" "1"]) (tempsMinLower . ["" "-10" "-5" "-6" "-4" "-7" "-7"]) (tempsMax . ["" "9" "8" "10" "9" "7" "10"]) (tempsMaxUpper . ["" "11" "10" "12" "10" "10" "13"]) (tempsMaxLower . ["" "7" "5" "8" "6" "5" "7"])) 52 | ((area (name . "松本") (code . "48361")) (tempsMin . ["" "-7" "0" "-3" "0" "-2" "-1"]) (tempsMinUpper . ["" "-4" "2" "0" "2" "1" "1"]) (tempsMinLower . ["" "-8" "-2" "-6" "-1" "-6" "-5"]) (tempsMax . ["" "11" "9" "12" "9" "9" "12"]) (tempsMaxUpper . ["" "13" "11" "15" "12" "12" "15"]) (tempsMaxLower . ["" "9" "6" "11" "7" "7" "9"])) 53 | ])) 54 | ]) 55 | (tempAverage (areas . [((area (name . "長野") (code . "48156")) (min . "-2.2") (max . "7.4")) ((area (name . "松本") (code . "48361")) (min . "-2.8") (max . "8.6"))])) 56 | (precipAverage (areas . [((area (name . "長野") (code . "48156")) (min . "6.3") (max . "15.9")) ((area (name . "松本") (code . "48361")) (min . "3.9") (max . "17.4"))])) 57 | ) 58 | ] 59 | -------------------------------------------------------------------------------- /example-data/jma-forecast-福島-20220223-0501.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-forecast-data "070000") 2 | 3 | [ 4 | ((publishingOffice . "福島地方気象台") 5 | (reportDatetime . "2022-02-23T05:00:00+09:00") 6 | (timeSeries 7 | . [ 8 | ((timeDefines . ["2022-02-23T05:00:00+09:00" "2022-02-24T00:00:00+09:00"]) 9 | (areas 10 | . [ 11 | ((area (name . "中通り") (code . "070010")) (weatherCodes . ["210" "210"]) (weathers . ["くもり 昼過ぎ から 時々 晴れ 所により 昼前 まで 雪" "くもり 昼前 から 時々 晴れ 所により 朝晩 雪"]) (winds . ["西の風 日中 やや強く" "西の風 日中 やや強く"])) 12 | ((area (name . "浜通り") (code . "070020")) (weatherCodes . ["101" "101"]) (weathers . ["晴れ 時々 くもり" "晴れ 時々 くもり"]) (winds . ["北西の風 後 西の風 やや強く" "西の風 後 やや強く"]) (waves . ["2メートル 後 1.5メートル" "1.5メートル"])) 13 | ((area (name . "会津") (code . "070030")) (weatherCodes . ["402" "205"]) (weathers . ["雪 で ふぶく 昼過ぎ から 時々 くもり" "くもり 時々 雪"]) (winds . ["西の風 日中 やや強く" "西の風"])) 14 | ]) 15 | ) 16 | ((timeDefines . ["2022-02-23T06:00:00+09:00" "2022-02-23T12:00:00+09:00" "2022-02-23T18:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-24T06:00:00+09:00" "2022-02-24T12:00:00+09:00" "2022-02-24T18:00:00+09:00"]) 17 | (areas 18 | . [ 19 | ((area (name . "中通り") (code . "070010")) (pops . ["30" "10" "10" "20" "20" "10" "20"])) 20 | ((area (name . "浜通り") (code . "070020")) (pops . ["10" "10" "0" "10" "0" "0" "0"])) 21 | ((area (name . "会津") (code . "070030")) (pops . ["60" "50" "50" "50" "50" "40" "50"])) 22 | ]) 23 | ) 24 | ((timeDefines . ["2022-02-23T09:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-24T09:00:00+09:00"]) 25 | (areas 26 | . [ 27 | ((area (name . "福島") (code . "36127")) (temps . ["2" "2" "-3" "4"])) 28 | ((area (name . "小名浜") (code . "36846")) (temps . ["6" "6" "-3" "7"])) 29 | ((area (name . "若松") (code . "36361")) (temps . ["0" "0" "-5" "2"])) 30 | ((area (name . "白河") (code . "36667")) (temps . ["2" "2" "-5" "3"])) 31 | ((area (name . "郡山") (code . "36476")) (temps . ["1" "1" "-3" "3"])) 32 | ((area (name . "相馬") (code . "36151")) (temps . ["3" "3" "-4" "5"])) 33 | ((area (name . "田島") (code . "36641")) (temps . ["-3" "-3" "-7" "-1"]))]) 34 | ) 35 | ]) 36 | ) 37 | 38 | 39 | ((publishingOffice . "福島地方気象台") 40 | (reportDatetime . "2022-02-22T17:00:00+09:00") 41 | (timeSeries 42 | . [ 43 | ((timeDefines . ["2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00" "2022-03-01T00:00:00+09:00"]) 44 | (areas 45 | . [ 46 | ((area (name . "中通り・浜通り") (code . "070100")) 47 | (weatherCodes . ["201" "101" "101" "101" "201" "101" "201"]) 48 | (pops . ["" "20" "20" "20" "30" "20" "30"]) 49 | (reliabilities . ["" "" "A" "A" "A" "A" "A"])) 50 | ((area (name . "会津") (code . "070030")) 51 | (weatherCodes . ["402" "205" "200" "201" "260" "201" "260"]) 52 | (pops . ["" "60" "40" "30" "50" "30" "50"]) 53 | (reliabilities . ["" "" "B" "A" "C" "B" "C"])) 54 | ]) 55 | ) 56 | ((timeDefines . ["2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00" "2022-03-01T00:00:00+09:00"]) 57 | (areas 58 | . [ 59 | ((area (name . "福島") (code . "36127")) (tempsMin . ["" "-1" "0" "0" "1" "2" "1"]) (tempsMinUpper . ["" "0" "2" "2" "4" "4" "3"]) (tempsMinLower . ["" "-4" "-1" "-2" "-4" "-3" "-3"]) (tempsMax . ["" "5" "8" "12" "10" "12" "11"]) (tempsMaxUpper . ["" "7" "10" "14" "13" "14" "15"]) (tempsMaxLower . ["" "3" "6" "10" "8" "10" "8"])) 60 | ((area (name . "若松") (code . "36361")) (tempsMin . ["" "-2" "-2" "-5" "-2" "-1" "-1"]) (tempsMinUpper . ["" "-1" "-1" "-2" "1" "1" "0"]) (tempsMinLower . ["" "-6" "-4" "-9" "-7" "-7" "-7"]) (tempsMax . ["" "3" "5" "8" "8" "8" "8"]) (tempsMaxUpper . ["" "4" "7" "11" "10" "10" "12"]) (tempsMaxLower . ["" "0" "1" "6" "5" "6" "6"])) 61 | ]) 62 | ) 63 | ]) 64 | (tempAverage (areas . [((area (name . "福島") (code . "36127")) (min . "-0.5") (max . "8.3")) ((area (name . "若松") (code . "36361")) (min . "-2.6") (max . "5.5"))])) 65 | (precipAverage (areas . [((area (name . "福島") (code . "36127")) (min . "3.5") (max . "14.9")) ((area (name . "若松") (code . "36361")) (min . "9.3") (max . "20.6"))])) 66 | ) 67 | ] 68 | -------------------------------------------------------------------------------- /example-data/jma-forecast-week_area05.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-json-get "https://www.jma.go.jp/bosai/forecast/const/week_area05.json") 2 | 3 | ((\120010 . ["120000"]) 4 | (\120020 . ["120000"]) 5 | (\120030 . ["120000"]) 6 | (\220010 . ["220000"]) 7 | (\220020 . ["220000"]) 8 | (\220030 . ["220000"]) 9 | (\220040 . ["220000"]) 10 | (\210010 . ["210000" "210010"]) 11 | (\210020 . ["210000" "210020"]) 12 | (\230010 . ["230000"]) 13 | (\230020 . ["230000"]) 14 | (\240010 . ["240000"]) 15 | (\240020 . ["240000"]) 16 | (\150010 . ["150000"]) 17 | (\150020 . ["150000"]) 18 | (\150030 . ["150000"]) 19 | (\150040 . ["150000"]) 20 | (\160010 . ["160000"]) 21 | (\160020 . ["160000"]) 22 | (\170010 . ["170000"]) 23 | (\170020 . ["170000"]) 24 | (\180010 . ["180000"]) 25 | (\180020 . ["180000"]) 26 | (\250010 . ["250000" "250010"]) 27 | (\250020 . ["250000" "250020"]) 28 | (\260010 . ["260000" "260010"]) 29 | (\260020 . ["260000" "260020"]) 30 | (\290010 . ["290000"]) 31 | (\290020 . ["290000"]) 32 | (\270000 . ["270000"]) 33 | (\280010 . ["280000" "280010"]) 34 | (\280020 . ["280000" "280020"]) 35 | (\300010 . ["300000"]) 36 | (\300020 . ["300000"]) 37 | (\320010 . ["320000"]) 38 | (\320020 . ["320000"]) 39 | (\320030 . ["320000"]) 40 | (\310010 . ["310000"]) 41 | (\310020 . ["310000"]) 42 | (\330010 . ["330000" "330010"]) 43 | (\330020 . ["330000" "330020"]) 44 | (\340010 . ["340000" "340010"]) 45 | (\340020 . ["340000" "340020"]) 46 | (\370000 . ["370000"]) 47 | (\360010 . ["360000"]) 48 | (\360020 . ["360000"]) 49 | (\380010 . ["380000"]) 50 | (\380020 . ["380000"]) 51 | (\380030 . ["380000"]) 52 | (\390010 . ["390000"]) 53 | (\390020 . ["390000"]) 54 | (\390030 . ["390000"]) 55 | (\350010 . ["350000"]) 56 | (\350020 . ["350000"]) 57 | (\350030 . ["350000"]) 58 | (\350040 . ["350000"]) 59 | (\400010 . ["400000"]) 60 | (\400020 . ["400000"]) 61 | (\400030 . ["400000"]) 62 | (\400040 . ["400000"]) 63 | (\440010 . ["440000"]) 64 | (\440020 . ["440000"]) 65 | (\440030 . ["440000"]) 66 | (\440040 . ["440000"]) 67 | (\410010 . ["410000"]) 68 | (\410020 . ["410000"]) 69 | (\430010 . ["430000"]) 70 | (\430020 . ["430000"]) 71 | (\430030 . ["430000"]) 72 | (\430040 . ["430000"]) 73 | (\420010 . ["420000" "420100"]) 74 | (\420020 . ["420000" "420100"]) 75 | (\420030 . ["420000" "420030"]) 76 | (\420040 . ["420000" "420100"]) 77 | (\450010 . ["450000"]) 78 | (\450020 . ["450000"]) 79 | (\450030 . ["450000"]) 80 | (\450040 . ["450000"]) 81 | (\460010 . ["460100"]) 82 | (\460020 . ["460100"]) 83 | (\460030 . ["460100"]) 84 | (\460040 . ["460040"]) 85 | (\471010 . ["471000"]) 86 | (\471020 . ["471000"]) 87 | (\471030 . ["471000"]) 88 | (\472000 . ["472000"]) 89 | (\473000 . ["473000"]) 90 | (\474010 . ["474000"]) 91 | (\474020 . ["474000"]) 92 | (\011000 . ["011000"]) 93 | (\012010 . ["012000"]) 94 | (\012020 . ["012000"]) 95 | (\013010 . ["013000"]) 96 | (\013020 . ["013000"]) 97 | (\013030 . ["013000"]) 98 | (\014010 . ["014000" "014100"]) 99 | (\014020 . ["014000" "014100"]) 100 | (\014030 . ["014000" "014030"]) 101 | (\015010 . ["015000"]) 102 | (\015020 . ["015000"]) 103 | (\016010 . ["016000"]) 104 | (\016020 . ["016000"]) 105 | (\016030 . ["016000"]) 106 | (\017010 . ["017000"]) 107 | (\017020 . ["017000"]) 108 | (\020010 . ["020000" "020010" "020100"]) 109 | (\020020 . ["020000" "020200" "020100"]) 110 | (\020030 . ["020000" "020200" "020030"]) 111 | (\050010 . ["050000"]) 112 | (\050020 . ["050000"]) 113 | (\030010 . ["030000" "030010"]) 114 | (\030020 . ["030000" "030100"]) 115 | (\030030 . ["030000" "030100"]) 116 | (\060010 . ["060000"]) 117 | (\060020 . ["060000"]) 118 | (\060030 . ["060000"]) 119 | (\060040 . ["060000"]) 120 | (\040010 . ["040000" "040010"]) 121 | (\040020 . ["040000" "040020"]) 122 | (\070010 . ["070000" "070100"]) 123 | (\070020 . ["070000" "070100"]) 124 | (\070030 . ["070000" "070030"]) 125 | (\200010 . ["200000" "200010"]) 126 | (\200020 . ["200000" "200100"]) 127 | (\200030 . ["200000" "200100"]) 128 | (\190010 . ["190000"]) 129 | (\190020 . ["190000"]) 130 | (\100010 . ["100000" "100010"]) 131 | (\100020 . ["100000" "100020"]) 132 | (\090010 . ["090000"]) 133 | (\090020 . ["090000"]) 134 | (\080010 . ["080000"]) 135 | (\080020 . ["080000"]) 136 | (\110010 . ["110000"]) 137 | (\110020 . ["110000"]) 138 | (\110030 . ["110000"]) 139 | (\130010 . ["130010"]) 140 | (\130020 . ["130100" "130020"]) 141 | (\130030 . ["130100" "130030"]) 142 | (\130040 . ["130040"]) 143 | (\140010 . ["140000"]) 144 | (\140020 . ["140000"])) 145 | -------------------------------------------------------------------------------- /example-data/jma-amedas-4416-20220226_09.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-json-get "https://www.jma.go.jp/bosai/amedas/data/point/44116/20220226_09.json") 2 | 3 | ( 4 | (\20220226090000 5 | (prefNumber . 44) 6 | (observationNumber . 116) 7 | (temp . [7.1 0]) 8 | (snow1h . [0 :null]) 9 | (snow6h . [0 :null]) 10 | (snow12h . [0 :null]) 11 | (snow24h . [0 :null]) 12 | (sun10m . [10 0]) 13 | (sun1h . [1.0 0]) 14 | (precipitation10m . [0.0 0]) 15 | (precipitation1h . [0.0 0]) 16 | (precipitation3h . [0.0 0]) 17 | (precipitation24h . [0.0 0]) 18 | (windDirection . [12 0]) 19 | (wind . [1.5 0]) 20 | (maxTempTime (hour . 23) (minute . 58)) 21 | (maxTemp . [7.4 0]) 22 | (minTempTime (hour . 21) (minute . 32)) 23 | (minTemp . [0.0 0]) 24 | (gustTime (hour . 22) (minute . 38)) 25 | (gustDirection . [12 0]) 26 | (gust . [3.7 0])) 27 | 28 | (\20220226091000 (prefNumber . 44) (observationNumber . 116) (temp . [8.0 0]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [11 0]) (wind . [1.1 0]) (maxTempTime (hour . 0) (minute . 10)) (maxTemp . [8.3 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 29 | (\20220226092000 (prefNumber . 44) (observationNumber . 116) (temp . [9.0 0]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [10 0]) (wind . [1.2 0]) (maxTempTime (hour . 0) (minute . 17)) (maxTemp . [9.2 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 30 | (\20220226093000 (prefNumber . 44) (observationNumber . 116) (temp . [9.3 0]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [11 0]) (wind . [1.4 0]) (maxTempTime (hour . 0) (minute . 22)) (maxTemp . [9.5 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 31 | (\20220226094000 (prefNumber . 44) (observationNumber . 116) (temp . [10.2 0]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [13 0]) (wind . [1.1 0]) (maxTempTime (hour . 0) (minute . 40)) (maxTemp . [10.2 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 32 | (\20220226095000 (prefNumber . 44) (observationNumber . 116) (temp . [9.5 0]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [11 0]) (wind . [1.4 0]) (maxTempTime (hour . 0) (minute . 40)) (maxTemp . [10.2 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 33 | (\20220226100000 (prefNumber . 44) (observationNumber . 116) (temp . [9.8 0]) (snow1h . [0 :null]) (snow6h . [0 :null]) (snow12h . [0 :null]) (snow24h . [0 :null]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [6 0]) (wind . [0.9 0]) (maxTempTime (hour . 0) (minute . 57)) (maxTemp . [10.3 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 34 | (\20220226101000 (prefNumber . 44) (observationNumber . 116) (temp . [10.9 0]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [9 0]) (wind . [1.4 0]) (maxTempTime (hour . 1) (minute . 10)) (maxTemp . [10.9 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 35 | (\20220226102000 (prefNumber . 44) (observationNumber . 116) (temp . [10.1 0]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [10 0]) (wind . [1.5 0]) (maxTempTime (hour . 1) (minute . 10)) (maxTemp . [10.9 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 36 | ) 37 | -------------------------------------------------------------------------------- /example-data/jma-forecast-福島-20220221-0753.json.el: -------------------------------------------------------------------------------- 1 | ;;2022-02-21 07:53 2 | ;;(jma-forecast-data "070000") 3 | 4 | [ 5 | ((publishingOffice . "福島地方気象台") 6 | (reportDatetime . "2022-02-21T05:00:00+09:00") 7 | (timeSeries 8 | . [ 9 | ((timeDefines . ["2022-02-21T05:00:00+09:00" "2022-02-22T00:00:00+09:00"]) 10 | (areas 11 | . [ 12 | ;; class10s 13 | ((area (name . "中通り") (code . "070010")) (weatherCodes . ["205" "201"]) (weathers . ["くもり 昼過ぎ まで 時々 雪 で ふぶく" "くもり 時々 晴れ 所により 雪"]) (winds . ["西の風 やや強く" "西の風 日中 北西の風"])) 14 | ((area (name . "浜通り") (code . "070020")) (weatherCodes . ["101" "101"]) (weathers . ["晴れ 時々 くもり 所により 昼前 まで 雪" "晴れ 時々 くもり 所により 昼前 から 雪"]) (winds . ["西の風 やや強く 海上 では 西の風 強く" "北西の風 海上 では はじめ 西の風 強く"]) (waves . ["3メートル 後 2.5メートル" "2メートル"])) 15 | ((area (name . "会津") (code . "070030")) (weatherCodes . ["400" "400"]) (weathers . ["雪 で ふぶく" "雪"]) (winds . ["西の風 日中 やや強く" "西の風"]))]) 16 | ) 17 | ((timeDefines . ["2022-02-21T06:00:00+09:00" "2022-02-21T12:00:00+09:00" "2022-02-21T18:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-22T06:00:00+09:00" "2022-02-22T12:00:00+09:00" "2022-02-22T18:00:00+09:00"]) 18 | (areas 19 | . [ 20 | ;; class10s 21 | ((area (name . "中通り") (code . "070010")) (pops . ["30" "40" "20" "20" "20" "30" "30"])) 22 | ((area (name . "浜通り") (code . "070020")) (pops . ["20" "10" "10" "10" "20" "20" "20"])) 23 | ((area (name . "会津") (code . "070030")) (pops . ["80" "70" "70" "60" "50" "60" "70"])) 24 | ]) 25 | ) 26 | ((timeDefines . ["2022-02-21T09:00:00+09:00" "2022-02-21T00:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-22T09:00:00+09:00"]) 27 | (areas 28 | . [ 29 | ;; amedas 30 | ((area (name . "福島") (code . "36127")) (temps . ["1" "1" "-2" "2"])) 31 | ((area (name . "小名浜") (code . "36846")) (temps . ["4" "4" "-3" "6"])) 32 | ((area (name . "若松") (code . "36361")) (temps . ["1" "1" "-3" "1"])) 33 | ((area (name . "白河") (code . "36667")) (temps . ["1" "1" "-4" "3"])) 34 | ((area (name . "郡山") (code . "36476")) (temps . ["0" "0" "-4" "2"])) 35 | ((area (name . "相馬") (code . "36151")) (temps . ["2" "2" "-4" "3"])) 36 | ((area (name . "田島") (code . "36641")) (temps . ["-4" "-4" "-7" "-2"])) 37 | ]) 38 | ) 39 | ])) 40 | 41 | ((publishingOffice . "福島地方気象台") 42 | (reportDatetime . "2022-02-20T17:00:00+09:00") 43 | (timeSeries 44 | . [ 45 | ((timeDefines . ["2022-02-21T00:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00"]) 46 | (areas 47 | . [ 48 | ;; ???? 49 | ((area (name . "中通り・浜通り") (code . "070100")) (weatherCodes . ["201" "200" "201" "101" "101" "101" "201"]) (pops . ["" "40" "20" "20" "20" "20" "30"]) (reliabilities . ["" "" "A" "A" "A" "A" "A"])) 50 | ;; class10s 51 | ((area (name . "会津") (code . "070030")) (weatherCodes . ["400" "402" "205" "204" "200" "200" "206"]) (pops . ["" "80" "70" "50" "40" "30" "60"]) (reliabilities . ["" "" "A" "C" "B" "B" "C"])) 52 | ]) 53 | ) 54 | ((timeDefines . ["2022-02-21T00:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00"]) 55 | (areas 56 | . [ 57 | ;; amedas 58 | ((area (name . "福島") (code . "36127")) (tempsMin . ["" "-2" "-3" "-2" "2" "1" "2"]) (tempsMinUpper . ["" "-1" "-2" "0" "3" "3" "3"]) (tempsMinLower . ["" "-5" "-5" "-4" "0" "-4" "-3"]) (tempsMax . ["" "3" "2" "6" "9" "13" "11"]) (tempsMaxUpper . ["" "5" "4" "8" "12" "15" "15"]) (tempsMaxLower . ["" "1" "0" "3" "7" "10" "9"])) 59 | ((area (name . "若松") (code . "36361")) (tempsMin . ["" "-3" "-4" "-3" "-1" "-3" "-2"]) (tempsMinUpper . ["" "-2" "-3" "-2" "1" "-1" "1"]) (tempsMinLower . ["" "-9" "-6" "-5" "-6" "-9" "-7"]) (tempsMax . ["" "1" "0" "2" "6" "9" "8"]) (tempsMaxUpper . ["" "3" "2" "4" "8" "12" "11"]) (tempsMaxLower . ["" "-2" "-3" "-1" "4" "7" "6"])) 60 | ]) 61 | ) 62 | ]) 63 | (tempAverage (areas . [((area (name . "福島") (code . "36127")) (min . "-0.7") (max . "8.1")) ((area (name . "若松") (code . "36361")) (min . "-2.8") (max . "5.2"))])) 64 | (precipAverage (areas . [((area (name . "福島") (code . "36127")) (min . "3.4") (max . "14.0")) ((area (name . "若松") (code . "36361")) (min . "9.5") (max . "21.1"))])) 65 | ) 66 | ] 67 | 68 | -------------------------------------------------------------------------------- /example-data/jma-forecast-week_area_name.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-json-get "https://www.jma.go.jp/bosai/forecast/const/week_area_name.json") 2 | 3 | ((\011000 (jp . "宗谷地方") (en . "Soya")) 4 | (\012000 (jp . "上川・留萌地方") (en . "Kamikawa Rumoi")) 5 | (\013000 (jp . "網走・北見・紋別地方") (en . "Abashiri Kitami Mombetsu")) 6 | (\014000 (jp . "釧路・根室・十勝地方") (en . "Kushiro Nemuro Tokachi")) 7 | (\014030 (jp . "十勝地方") (en . "Tokachi")) 8 | (\014100 (jp . "釧路・根室地方") (en . "Kushiro Nemuro")) 9 | (\015000 (jp . "胆振・日高地方") (en . "Iburi Hidaka")) 10 | (\016000 (jp . "石狩・空知・後志地方") (en . "Ishikari Sorachi Shiribeshi")) 11 | (\017000 (jp . "渡島・檜山地方") (en . "Oshima Hiyama")) 12 | (\020000 (jp . "青森県") (en . "Aomori")) 13 | (\020010 (jp . "青森県津軽") (en . "Aomori Tsugaru")) 14 | (\020030 (jp . "青森県三八上北") (en . "Aomori Sanpachi Kamikita")) 15 | (\020100 (jp . "青森県津軽・下北") (en . "Aomori Tsugaru Shimokita")) 16 | (\020200 (jp . "青森県下北・三八上北") (en . "Aomori Shimokita Sanpachi Kamikita")) 17 | (\030000 (jp . "岩手県") (en . "Iwate")) 18 | (\030010 (jp . "岩手県内陸") (en . "Iwate Inland")) 19 | (\030100 (jp . "岩手県沿岸") (en . "Iwate Coast")) 20 | (\040000 (jp . "宮城県") (en . "Miyagi")) 21 | (\040010 (jp . "宮城県東部") (en . "Miyagi Eastern Region")) 22 | (\040020 (jp . "宮城県西部") (en . "Miyagi Western Region")) 23 | (\050000 (jp . "秋田県") (en . "Akita")) 24 | (\060000 (jp . "山形県") (en . "Yamagata")) 25 | (\070000 (jp . "福島県") (en . "Fukushima")) 26 | (\070030 (jp . "福島県会津") (en . "Fukushima Aizu")) 27 | (\070100 (jp . "福島県中通り・浜通り") (en . "Fukushima Nakadori Hamadori")) 28 | (\080000 (jp . "茨城県") (en . "Ibaraki")) 29 | (\090000 (jp . "栃木県") (en . "Tochigi")) 30 | (\100000 (jp . "群馬県") (en . "Gunma")) 31 | (\100010 (jp . "群馬県南部") (en . "Gunma Southern Region")) 32 | (\100020 (jp . "群馬県北部") (en . "Gunma Northern Region")) 33 | (\110000 (jp . "埼玉県") (en . "Saitama")) 34 | (\120000 (jp . "千葉県") (en . "Chiba")) 35 | (\130010 (jp . "東京地方") (en . "Tokyo Region")) 36 | (\130020 (jp . "伊豆諸島北部") (en . "Northern Izu Islands")) 37 | (\130030 (jp . "伊豆諸島南部") (en . "Southern Izu Islands")) 38 | (\130040 (jp . "小笠原諸島") (en . "Ogasawara Islands")) 39 | (\130100 (jp . "伊豆諸島") (en . "Izu Islands")) 40 | (\140000 (jp . "神奈川県") (en . "Kanagawa")) 41 | (\150000 (jp . "新潟県") (en . "Niigata")) 42 | (\160000 (jp . "富山県") (en . "Toyama")) 43 | (\170000 (jp . "石川県") (en . "Ishikawa")) 44 | (\180000 (jp . "福井県") (en . "Fukui")) 45 | (\190000 (jp . "山梨県") (en . "Yamanashi")) 46 | (\200000 (jp . "長野県") (en . "Nagano")) 47 | (\200010 (jp . "長野県北部") (en . "Nagano Northern Region")) 48 | (\200100 (jp . "長野県中部・南部") (en . "Nagano Central Region Southern Region")) 49 | (\210000 (jp . "岐阜県") (en . "Gifu")) 50 | (\210010 (jp . "岐阜県美濃地方") (en . "Gifu Mino Region")) 51 | (\210020 (jp . "岐阜県飛騨地方") (en . "Gifu Hida Region")) 52 | (\220000 (jp . "静岡県") (en . "Shizuoka")) 53 | (\230000 (jp . "愛知県") (en . "Aichi")) 54 | (\240000 (jp . "三重県") (en . "Mie")) 55 | (\250000 (jp . "滋賀県") (en . "Shiga")) 56 | (\250010 (jp . "滋賀県南部") (en . "Shiga Southern Region")) 57 | (\250020 (jp . "滋賀県北部") (en . "Shiga Northern Region")) 58 | (\260000 (jp . "京都府") (en . "Kyoto")) 59 | (\260010 (jp . "京都府南部") (en . "Kyoto Southern Region")) 60 | (\260020 (jp . "京都府北部") (en . "Kyoto Northern Region")) 61 | (\270000 (jp . "大阪府") (en . "Osaka")) 62 | (\280000 (jp . "兵庫県") (en . "Hyogo")) 63 | (\280010 (jp . "兵庫県南部") (en . "Hyogo Southern Region")) 64 | (\280020 (jp . "兵庫県北部") (en . "Hyogo Northern Region")) 65 | (\290000 (jp . "奈良県") (en . "Nara")) 66 | (\300000 (jp . "和歌山県") (en . "Wakayama")) 67 | (\310000 (jp . "鳥取県") (en . "Tottori")) 68 | (\320000 (jp . "島根県") (en . "Shimane")) 69 | (\330000 (jp . "岡山県") (en . "Okayama")) 70 | (\330010 (jp . "岡山県南部") (en . "Okayama Southern Region")) 71 | (\330020 (jp . "岡山県北部") (en . "Okayama Northern Region")) 72 | (\340000 (jp . "広島県") (en . "Hiroshima")) 73 | (\340010 (jp . "広島県南部") (en . "Hiroshima Southern Region")) 74 | (\340020 (jp . "広島県北部") (en . "Hiroshima Northern Region")) 75 | (\350000 (jp . "山口県") (en . "Yamaguchi")) 76 | (\360000 (jp . "徳島県") (en . "Tokushima")) 77 | (\370000 (jp . "香川県") (en . "Kagawa")) 78 | (\380000 (jp . "愛媛県") (en . "Ehime")) 79 | (\390000 (jp . "高知県") (en . "Kochi")) 80 | (\400000 (jp . "福岡県") (en . "Fukuoka")) 81 | (\410000 (jp . "佐賀県") (en . "Saga")) 82 | (\420000 (jp . "長崎県") (en . "Nagasaki")) 83 | (\420030 (jp . "長崎県壱岐・対馬") (en . "Nagasaki Iki Tsushima")) 84 | (\420100 (jp . "長崎県南部・北部・五島") (en . "Nagasaki Southern Region Northern Region Goto")) 85 | (\430000 (jp . "熊本県") (en . "Kumamoto")) 86 | (\440000 (jp . "大分県") (en . "Oita")) 87 | (\450000 (jp . "宮崎県") (en . "Miyazaki")) 88 | (\460040 (jp . "奄美地方") (en . "Amami")) 89 | (\460100 (jp . "鹿児島県(奄美地方除く)") (en . "Kagoshima (Excluding Amami)")) 90 | (\471000 (jp . "沖縄本島地方") (en . "Okinawa Main Island")) 91 | (\472000 (jp . "大東島地方") (en . "Daitojima")) 92 | (\473000 (jp . "宮古島地方") (en . "Miyakojima")) 93 | (\474000 (jp . "八重山地方") (en . "Yaeyama"))) 94 | -------------------------------------------------------------------------------- /jma-area.el: -------------------------------------------------------------------------------- 1 | ;;; jma-area.el --- JMA Area -*- lexical-binding: t; -*- 2 | 3 | ;; Copyright (C) 2022 AKIYAMA Kouhei 4 | 5 | ;; Author: AKIYAMA Kouhei 6 | ;; Keywords: comm 7 | 8 | ;; This program is free software; you can redistribute it and/or modify 9 | ;; it under the terms of the GNU General Public License as published by 10 | ;; the Free Software Foundation, either version 3 of the License, or 11 | ;; (at your option) any later version. 12 | 13 | ;; This program is distributed in the hope that it will be useful, 14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ;; GNU General Public License for more details. 17 | 18 | ;; You should have received a copy of the GNU General Public License 19 | ;; along with this program. If not, see . 20 | 21 | ;;; Commentary: 22 | 23 | ;; 24 | 25 | ;;; Code: 26 | 27 | (require 'jma-utils) 28 | 29 | ;;;; 発表区域 30 | 31 | (defvar jma-area-data-cache nil) 32 | 33 | (defun jma-area-data-get () 34 | (or jma-area-data-cache 35 | (setq jma-area-data-cache 36 | (jma-json-get 37 | "https://www.jma.go.jp/bosai/common/const/area.json")))) 38 | 39 | ;;;;; 一覧取得 40 | 41 | (defun jma-area-centers () 42 | (alist-get 'centers (jma-area-data-get))) 43 | 44 | (defun jma-area-offices () 45 | (alist-get 'offices (jma-area-data-get))) 46 | 47 | (defun jma-area-class10s () 48 | (alist-get 'class10s (jma-area-data-get))) 49 | 50 | (defun jma-area-class15s () 51 | (alist-get 'class15s (jma-area-data-get))) 52 | 53 | (defun jma-area-class20s () 54 | (alist-get 'class20s (jma-area-data-get))) 55 | 56 | ;;;;; 検索 57 | 58 | (defun jma-area-center (center-code) 59 | (assq 60 | (jma-ensure-symbol center-code) 61 | (jma-area-centers))) 62 | 63 | (defun jma-area-office (office-code) 64 | (assq 65 | (jma-ensure-symbol office-code) 66 | (jma-area-offices))) 67 | 68 | (defun jma-area-class10 (class10-code) 69 | (assq 70 | (jma-ensure-symbol class10-code) 71 | (jma-area-class10s))) 72 | 73 | (defun jma-area-class15 (class15-code) 74 | (assq 75 | (jma-ensure-symbol class15-code) 76 | (jma-area-class15s))) 77 | 78 | (defun jma-area-class20 (class20-code) 79 | (assq 80 | (jma-ensure-symbol class20-code) 81 | (jma-area-class20s))) 82 | 83 | ;;;;; 区域オブジェクトに対するアクセッサ 84 | 85 | (defun jma-area-code-symbol (area-obj) 86 | (car area-obj)) 87 | 88 | (defun jma-area-code (area-obj) 89 | (symbol-name (jma-area-code-symbol area-obj))) 90 | 91 | (defun jma-area-name (area-obj) 92 | (alist-get 'name (cdr area-obj))) 93 | 94 | (defun jma-area-office-name (area-obj) 95 | (alist-get 'officeName (cdr area-obj))) 96 | 97 | (defun jma-area-parent-code (area-obj) 98 | (alist-get 'parent (cdr area-obj))) 99 | 100 | (defun jma-area-child-codes (area-obj) 101 | (alist-get 'children (cdr area-obj))) 102 | 103 | ;;;;; 府県予報区-二次細分区域 対応関係 104 | 105 | (defun jma-area-class20-codes-in-office (office-code) 106 | "府県予報区OFFICE-CODEの中の全二次細分区域コードを返します。" 107 | (seq-mapcat 108 | (lambda (class15-code) 109 | (jma-area-child-codes (jma-area-class15 class15-code))) 110 | (seq-mapcat 111 | (lambda (class10-code) 112 | (jma-area-child-codes (jma-area-class10 class10-code))) 113 | (jma-area-child-codes (jma-area-office office-code))))) 114 | 115 | ;;;;; ユーザー入力 116 | 117 | (defun jma-area-read-center (&optional prompt) 118 | "ミニバッファから地方予報区を読み取ります。" 119 | (jma-choose-from-alist 120 | (or prompt "地方予報区: ") 121 | (mapcar (lambda (center) 122 | (cons 123 | (jma-area-name center) 124 | (jma-area-code center))) 125 | (jma-area-centers)))) 126 | ;;(jma-area-read-center) 127 | 128 | (defun jma-area-read-office (&optional prompt) 129 | "ミニバッファから府県予報区(概ね都道府県)を読み取ります。" 130 | (jma-choose-from-alist 131 | (or prompt "府県予報区: ") 132 | (mapcar (lambda (office) 133 | (cons 134 | (jma-area-name office) 135 | (jma-area-code office))) 136 | (jma-area-offices)))) 137 | ;;(jma-area-read-office) 138 | 139 | (defun jma-area-read-class10 (office-code &optional prompt) 140 | "ミニバッファから一次細分区域を読み取ります。" 141 | (jma-choose-from-alist 142 | (or prompt "一次細分区域: ") 143 | (mapcar (lambda (class10-code) 144 | (cons 145 | (jma-area-name (jma-area-class10 class10-code)) 146 | class10-code)) 147 | (jma-area-child-codes (jma-area-office office-code))))) 148 | ;;(jma-area-read-class10 "130000") 149 | 150 | (defun jma-area-read-class20-in-office (office-code &optional prompt) 151 | "ミニバッファから二次細分区域(概ね市区町村)を読み取ります。" 152 | (jma-choose-from-alist 153 | (or prompt "二次細分区域: ") 154 | (mapcar (lambda (class20-code) 155 | (cons 156 | (jma-area-name (jma-area-class20 class20-code)) 157 | class20-code)) 158 | (jma-area-class20-codes-in-office office-code)))) 159 | ;;(jma-area-read-class20-in-office "130000") 160 | 161 | 162 | (provide 'jma-area) 163 | ;;; jma-area.el ends here 164 | -------------------------------------------------------------------------------- /example-data/jma-forecast-東京-20220222-2212.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-forecast-data "130000") 2 | 3 | [ 4 | ((publishingOffice . "気象庁") 5 | (reportDatetime . "2022-02-22T17:00:00+09:00") 6 | (timeSeries 7 | . [ 8 | ((timeDefines . ["2022-02-22T17:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00"]) 9 | (areas 10 | . [ 11 | ((area (name . "東京地方") (code . "130010")) (weatherCodes . ["101" "111" "101"]) (weathers . ["晴れ 夜のはじめ頃 くもり" "晴れ 夕方 から くもり" "晴れ 時々 くもり"]) (winds . ["北の風 やや強く" "北の風 23区西部 では 後 北の風 やや強く" "北の風"]) (waves . ["1メートル" "0.5メートル 後 1メートル" "0.5メートル"])) 12 | ((area (name . "伊豆諸島北部") (code . "130020")) (weatherCodes . ["101" "101" "201"]) (weathers . ["晴れ 夜のはじめ頃 くもり" "晴れ 時々 くもり 所により 夜 雨か雪" "くもり 時々 晴れ"]) (winds . ["西の風 強く" "西の風 強く" "西の風 やや強く 後 北東の風"]) (waves . ["3メートル ただし 新島 では 4メートル" "3メートル 後 2.5メートル ただし 新島 では 4メートル 後 3メートル" "2メートル 後 1.5メートル ただし 新島 では 3メートル 後 2メートル"])) 13 | ((area (name . "伊豆諸島南部") (code . "130030")) (weatherCodes . ["200" "200" "201"]) (weathers . ["くもり 所により 雨か雪" "くもり 所により 雨か雪" "くもり 時々 晴れ"]) (winds . ["西の風 強く" "西の風 強く" "西の風 強く 後 やや強く"]) (waves . ["4メートル" "4メートル" "3メートル 後 2.5メートル"])) 14 | ((area (name . "小笠原諸島") (code . "130040")) (weatherCodes . ["101" "201" "201"]) (weathers . ["晴れ 夜のはじめ頃 くもり" "くもり 昼過ぎ まで 時々 晴れ" "くもり 時々 晴れ"]) (winds . ["北西の風" "北西の風 後 北の風" "北の風"]) (waves . ["3メートル うねり を伴う" "3メートル うねり を伴う" "2.5メートル 後 2メートル うねり を伴う"])) 15 | ])) 16 | ((timeDefines . ["2022-02-22T18:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-23T06:00:00+09:00" "2022-02-23T12:00:00+09:00" "2022-02-23T18:00:00+09:00"]) 17 | (areas 18 | . [ 19 | ((area (name . "東京地方") (code . "130010")) (pops . ["10" "0" "0" "10" "10"])) 20 | ((area (name . "伊豆諸島北部") (code . "130020")) (pops . ["10" "10" "10" "10" "20"])) 21 | ((area (name . "伊豆諸島南部") (code . "130030")) (pops . ["20" "20" "20" "10" "20"])) 22 | ((area (name . "小笠原諸島") (code . "130040")) (pops . ["10" "10" "10" "10" "10"])) 23 | ])) 24 | ((timeDefines . ["2022-02-23T00:00:00+09:00" "2022-02-23T09:00:00+09:00"]) (areas . [((area (name . "東京") (code . "44132")) (temps . ["-1" "9"])) ((area (name . "大島") (code . "44172")) (temps . ["3" "10"])) ((area (name . "八丈島") (code . "44263")) (temps . ["5" "9"])) ((area (name . "父島") (code . "44301")) (temps . ["14" "19"]))])) 25 | ]) 26 | ) 27 | 28 | ((publishingOffice . "気象庁") 29 | (reportDatetime . "2022-02-22T17:00:00+09:00") 30 | (timeSeries . [((timeDefines . ["2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00" "2022-03-01T00:00:00+09:00"]) (areas . [((area (name . "東京地方") (code . "130010")) (weatherCodes . ["111" "101" "101" "101" "201" "101" "201"]) (pops . ["" "10" "10" "10" "30" "10" "30"]) (reliabilities . ["" "" "A" "A" "A" "A" "A"])) ((area (name . "伊豆諸島北部") (code . "130020")) (weatherCodes . ["101" "201" "101" "101" "201" "101" "201"]) (pops . ["" "20" "20" "20" "30" "20" "30"]) (reliabilities . ["" "" "A" "A" "B" "A" "B"])) ((area (name . "伊豆諸島南部") (code . "130030")) (weatherCodes . ["200" "201" "101" "101" "202" "101" "201"]) (pops . ["" "30" "20" "20" "50" "20" "30"]) (reliabilities . ["" "" "A" "A" "C" "A" "B"])) ((area (name . "小笠原諸島") (code . "130040")) (weatherCodes . ["201" "201" "200" "201" "201" "101" "101"]) (pops . ["" "30" "40" "30" "30" "20" "20"]) (reliabilities . ["" "" "B" "B" "A" "A" "A"]))])) ((timeDefines . ["2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00" "2022-03-01T00:00:00+09:00"]) (areas . [((area (name . "東京") (code . "44132")) (tempsMin . ["" "0" "0" "1" "4" "2" "5"]) (tempsMinUpper . ["" "2" "2" "2" "5" "4" "7"]) (tempsMinLower . ["" "-1" "-1" "-1" "2" "0" "3"]) (tempsMax . ["" "9" "12" "15" "15" "16" "15"]) (tempsMaxUpper . ["" "11" "14" "17" "17" "18" "19"]) (tempsMaxLower . ["" "8" "10" "12" "13" "14" "13"])) ((area (name . "大島") (code . "44172")) (tempsMin . ["" "2" "4" "5" "8" "7" "8"]) (tempsMinUpper . ["" "5" "6" "7" "10" "9" "10"]) (tempsMinLower . ["" "1" "2" "3" "5" "4" "6"]) (tempsMax . ["" "9" "13" "14" "15" "16" "15"]) (tempsMaxUpper . ["" "12" "14" "16" "16" "18" "18"]) (tempsMaxLower . ["" "8" "11" "13" "13" "14" "14"])) ((area (name . "八丈島") (code . "44263")) (tempsMin . ["" "5" "7" "8" "10" "10" "11"]) (tempsMinUpper . ["" "7" "8" "10" "12" "11" "14"]) (tempsMinLower . ["" "4" "5" "6" "8" "8" "9"]) (tempsMax . ["" "9" "12" "15" "14" "16" "17"]) (tempsMaxUpper . ["" "11" "13" "16" "16" "18" "19"]) (tempsMaxLower . ["" "8" "10" "13" "13" "14" "15"])) ((area (name . "父島") (code . "44301")) (tempsMin . ["" "14" "16" "16" "17" "16" "17"]) (tempsMinUpper . ["" "16" "17" "17" "19" "18" "18"]) (tempsMinLower . ["" "13" "14" "14" "15" "15" "15"]) (tempsMax . ["" "19" "19" "20" "22" "21" "21"]) (tempsMaxUpper . ["" "20" "20" "21" "23" "22" "23"]) (tempsMaxLower . ["" "18" "18" "19" "20" "20" "20"]))]))]) 31 | (tempAverage (areas . [((area (name . "東京") (code . "44132")) (min . "3.0") (max . "11.8")) ((area (name . "大島") (code . "44172")) (min . "4.9") (max . "12.4")) ((area (name . "八丈島") (code . "44263")) (min . "8.2") (max . "14.4")) ((area (name . "父島") (code . "44301")) (min . "15.9") (max . "20.9"))])) 32 | (precipAverage (areas . [((area (name . "東京") (code . "44132")) (min . "6.3") (max . "28.2")) ((area (name . "大島") (code . "44172")) (min . "18.6") (max . "60.2")) ((area (name . "八丈島") (code . "44263")) (min . "33.8") (max . "69.5")) ((area (name . "父島") (code . "44301")) (min . "2.8") (max . "15.0"))])) 33 | ) 34 | ] 35 | -------------------------------------------------------------------------------- /example-data/jma-forecast-東京-20220222-0010.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-forecast-data "130000") 2 | [ 3 | ((publishingOffice . "気象庁") 4 | (reportDatetime . "2022-02-21T20:00:00+09:00") 5 | (timeSeries 6 | . [ 7 | ((timeDefines . ["2022-02-21T17:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00"]) 8 | (areas 9 | . [ 10 | ((area (name . "東京地方") (code . "130010")) (weatherCodes . ["100" "110" "101"]) (weathers . ["晴れ" "晴れ 昼前 から 時々 くもり" "晴れ 時々 くもり"]) (winds . ["北西の風 23区西部 では 北西の風 やや強く" "北の風 23区西部 では 後 北の風 やや強く" "北の風"]) (waves . ["1メートル" "0.5メートル 後 1メートル" "0.5メートル"])) 11 | ((area (name . "伊豆諸島北部") (code . "130020")) (weatherCodes . ["100" "101" "101"]) (weathers . ["晴れ" "晴れ 時々 くもり" "晴れ 時々 くもり"]) (winds . ["西の風 強く" "西の風 強く" "西の風 強く"]) (waves . ["3メートル ただし 新島 では 4メートル" "3メートル ただし 新島 では 4メートル" "3メートル 後 2.5メートル ただし 新島 では 4メートル 後 3メートル"])) 12 | ((area (name . "伊豆諸島南部") (code . "130030")) (weatherCodes . ["200" "200" "201"]) (weathers . ["くもり 八丈島 では 雨か雪" "くもり 所により 雨か雪" "くもり 時々 晴れ"]) (winds . ["西の風 強く" "西の風 強く" "西の風 強く"]) (waves . ["4メートル" "4メートル" "4メートル 後 3メートル"])) 13 | ((area (name . "小笠原諸島") (code . "130040")) (weatherCodes . ["200" "210" "101"]) (weathers . ["くもり" "くもり 昼前 から 時々 晴れ" "晴れ 時々 くもり"]) (winds . ["北の風" "北の風" "北の風"]) (waves . ["4メートル うねり を伴う" "4メートル 後 2.5メートル うねり を伴う" "2.5メートル うねり を伴う"])) 14 | ])) 15 | ((timeDefines . ["2022-02-21T18:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-22T06:00:00+09:00" "2022-02-22T12:00:00+09:00" "2022-02-22T18:00:00+09:00"]) 16 | (areas 17 | . [ 18 | ((area (name . "東京地方") (code . "130010")) (pops . ["0" "0" "10" "10" "0"])) 19 | ((area (name . "伊豆諸島北部") (code . "130020")) (pops . ["10" "10" "10" "10" "10"])) 20 | ((area (name . "伊豆諸島南部") (code . "130030")) (pops . ["20" "20" "20" "20" "20"])) 21 | ((area (name . "小笠原諸島") (code . "130040")) (pops . ["10" "10" "10" "10" "10"]))]) 22 | ) 23 | ((timeDefines . ["2022-02-22T00:00:00+09:00" "2022-02-22T09:00:00+09:00"]) 24 | (areas 25 | . [ 26 | ((area (name . "東京") (code . "44132")) (temps . ["-1" "9"])) 27 | ((area (name . "大島") (code . "44172")) (temps . ["3" "10"])) 28 | ((area (name . "八丈島") (code . "44263")) (temps . ["5" "11"])) 29 | ((area (name . "父島") (code . "44301")) (temps . ["14" "18"]))])) 30 | ]) 31 | ) 32 | 33 | ((publishingOffice . "気象庁") 34 | (reportDatetime . "2022-02-21T17:00:00+09:00") 35 | (timeSeries 36 | . [ 37 | ((timeDefines . ["2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00"]) (areas . [((area (name . "東京地方") (code . "130010")) (weatherCodes . ["110" "101" "101" "101" "101" "201" "101"]) (pops . ["" "10" "10" "10" "20" "30" "10"]) (reliabilities . ["" "" "A" "A" "A" "A" "A"])) ((area (name . "伊豆諸島北部") (code . "130020")) (weatherCodes . ["101" "101" "101" "101" "101" "200" "101"]) (pops . ["" "20" "20" "20" "20" "40" "20"]) (reliabilities . ["" "" "A" "A" "A" "B" "A"])) ((area (name . "伊豆諸島南部") (code . "130030")) (weatherCodes . ["200" "201" "101" "101" "101" "202" "101"]) (pops . ["" "30" "20" "20" "20" "50" "20"]) (reliabilities . ["" "" "A" "A" "A" "C" "A"])) ((area (name . "小笠原諸島") (code . "130040")) (weatherCodes . ["210" "101" "201" "200" "201" "201" "101"]) (pops . ["" "10" "30" "40" "30" "30" "20"]) (reliabilities . ["" "" "A" "B" "A" "A" "A"]))])) 38 | ((timeDefines . ["2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00"]) (areas . [((area (name . "東京") (code . "44132")) (tempsMin . ["" "0" "1" "0" "1" "3" "2"]) (tempsMinUpper . ["" "2" "2" "2" "2" "5" "4"]) (tempsMinLower . ["" "-1" "-1" "-1" "0" "2" "1"]) (tempsMax . ["" "9" "9" "12" "15" "16" "16"]) (tempsMaxUpper . ["" "10" "11" "15" "17" "18" "19"]) (tempsMaxLower . ["" "7" "7" "10" "13" "14" "13"])) ((area (name . "大島") (code . "44172")) (tempsMin . ["" "2" "3" "4" "6" "8" "7"]) (tempsMinUpper . ["" "4" "5" "6" "7" "10" "9"]) (tempsMinLower . ["" "1" "1" "2" "4" "5" "4"]) (tempsMax . ["" "10" "11" "13" "15" "15" "16"]) (tempsMaxUpper . ["" "11" "13" "15" "16" "17" "18"]) (tempsMaxLower . ["" "8" "9" "11" "13" "14" "14"])) ((area (name . "八丈島") (code . "44263")) (tempsMin . ["" "5" "6" "7" "9" "11" "10"]) (tempsMinUpper . ["" "7" "8" "9" "11" "13" "12"]) (tempsMinLower . ["" "4" "5" "6" "7" "9" "7"]) (tempsMax . ["" "9" "11" "13" "15" "16" "16"]) (tempsMaxUpper . ["" "11" "12" "14" "16" "17" "18"]) (tempsMaxLower . ["" "8" "9" "11" "13" "14" "14"])) ((area (name . "父島") (code . "44301")) (tempsMin . ["" "14" "15" "16" "16" "17" "17"]) (tempsMinUpper . ["" "16" "16" "17" "17" "18" "19"]) (tempsMinLower . ["" "13" "13" "14" "15" "15" "15"]) (tempsMax . ["" "19" "19" "20" "21" "21" "21"]) (tempsMaxUpper . ["" "20" "20" "22" "22" "23" "22"]) (tempsMaxLower . ["" "18" "18" "19" "19" "20" "20"]))])) 39 | ]) 40 | (tempAverage (areas . [((area (name . "東京") (code . "44132")) (min . "2.9") (max . "11.7")) ((area (name . "大島") (code . "44172")) (min . "4.8") (max . "12.3")) ((area (name . "八丈島") (code . "44263")) (min . "8.1") (max . "14.3")) ((area (name . "父島") (code . "44301")) (min . "15.9") (max . "20.8"))])) 41 | (precipAverage (areas . [((area (name . "東京") (code . "44132")) (min . "5.6") (max . "26.5")) ((area (name . "大島") (code . "44172")) (min . "17.6") (max . "58.5")) ((area (name . "八丈島") (code . "44263")) (min . "33.0") (max . "67.7")) ((area (name . "父島") (code . "44301")) (min . "2.7") (max . "15.3"))])) 42 | ) 43 | ] 44 | -------------------------------------------------------------------------------- /example-data/jma-forecast-東京-20220222-0827.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-forecast-data "130000") 2 | [ 3 | ((publishingOffice . "気象庁") 4 | (reportDatetime . "2022-02-22T05:00:00+09:00") 5 | (timeSeries 6 | . [ 7 | ((timeDefines . ["2022-02-22T05:00:00+09:00" "2022-02-23T00:00:00+09:00"]) 8 | (areas 9 | . [ 10 | ((area (name . "東京地方") (code . "130010")) (weatherCodes . ["101" "110"]) (weathers . ["晴れ 昼過ぎ から 夕方 くもり" "晴れ 昼過ぎ から 時々 くもり"]) (winds . ["北の風 後 やや強く" "北の風 23区西部 では 後 北の風 やや強く"]) (waves . ["0.5メートル 後 1メートル" "0.5メートル 後 1メートル"])) 11 | ((area (name . "伊豆諸島北部") (code . "130020")) (weatherCodes . ["101" "101"]) (weathers . ["晴れ 時々 くもり" "晴れ 時々 くもり"]) (winds . ["西の風 強く 新島 では 西の風 非常に強く" "西の風 強く"]) (waves . ["3メートル ただし 新島 では 3メートル 後 4メートル" "3メートル 後 2.5メートル ただし 新島 では 4メートル 後 3メートル"])) 12 | ((area (name . "伊豆諸島南部") (code . "130030")) (weatherCodes . ["200" "200"]) (weathers . ["くもり 所により 雨か雪" "くもり 所により 雨か雪"]) (winds . ["西の風 強く 三宅島 では 西の風 非常に強く" "西の風 強く"]) (waves . ["4メートル" "4メートル"])) 13 | ((area (name . "小笠原諸島") (code . "130040")) (weatherCodes . ["101" "201"]) (weathers . ["晴れ 時々 くもり" "くもり 昼過ぎ まで 時々 晴れ"]) (winds . ["北の風 後 北西の風" "北西の風 後 北の風"]) (waves . ["3メートル うねり を伴う" "3メートル 後 2.5メートル うねり を伴う"])) 14 | ]) 15 | ) 16 | ((timeDefines . ["2022-02-22T06:00:00+09:00" "2022-02-22T12:00:00+09:00" "2022-02-22T18:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-23T06:00:00+09:00" "2022-02-23T12:00:00+09:00" "2022-02-23T18:00:00+09:00"]) 17 | (areas 18 | . [ 19 | ((area (name . "東京地方") (code . "130010")) (pops . ["10" "20" "0" "0" "0" "10" "10"])) 20 | ((area (name . "伊豆諸島北部") (code . "130020")) (pops . ["10" "10" "10" "10" "10" "10" "10"])) 21 | ((area (name . "伊豆諸島南部") (code . "130030")) (pops . ["20" "20" "20" "20" "20" "20" "20"])) 22 | ((area (name . "小笠原諸島") (code . "130040")) (pops . ["10" "10" "10" "10" "10" "10" "10"])) 23 | ]) 24 | ) 25 | ((timeDefines . ["2022-02-22T09:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-23T09:00:00+09:00"]) 26 | (areas 27 | . [ 28 | ((area (name . "東京") (code . "44132")) (temps . ["10" "10" "0" "9"])) 29 | ((area (name . "大島") (code . "44172")) (temps . ["10" "10" "3" "10"])) 30 | ((area (name . "八丈島") (code . "44263")) (temps . ["10" "10" "6" "9"])) 31 | ((area (name . "父島") (code . "44301")) (temps . ["18" "18" "14" "19"]))]) 32 | )]) 33 | ) 34 | 35 | ((publishingOffice . "気象庁") 36 | (reportDatetime . "2022-02-21T17:00:00+09:00") 37 | (timeSeries . [((timeDefines . ["2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00"]) (areas . [((area (name . "東京地方") (code . "130010")) (weatherCodes . ["110" "101" "101" "101" "101" "201" "101"]) (pops . ["" "10" "10" "10" "20" "30" "10"]) (reliabilities . ["" "" "A" "A" "A" "A" "A"])) ((area (name . "伊豆諸島北部") (code . "130020")) (weatherCodes . ["101" "101" "101" "101" "101" "200" "101"]) (pops . ["" "20" "20" "20" "20" "40" "20"]) (reliabilities . ["" "" "A" "A" "A" "B" "A"])) ((area (name . "伊豆諸島南部") (code . "130030")) (weatherCodes . ["200" "201" "101" "101" "101" "202" "101"]) (pops . ["" "30" "20" "20" "20" "50" "20"]) (reliabilities . ["" "" "A" "A" "A" "C" "A"])) ((area (name . "小笠原諸島") (code . "130040")) (weatherCodes . ["210" "101" "201" "200" "201" "201" "101"]) (pops . ["" "10" "30" "40" "30" "30" "20"]) (reliabilities . ["" "" "A" "B" "A" "A" "A"]))])) ((timeDefines . ["2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00"]) (areas . [((area (name . "東京") (code . "44132")) (tempsMin . ["" "0" "1" "0" "1" "3" "2"]) (tempsMinUpper . ["" "2" "2" "2" "2" "5" "4"]) (tempsMinLower . ["" "-1" "-1" "-1" "0" "2" "1"]) (tempsMax . ["" "9" "9" "12" "15" "16" "16"]) (tempsMaxUpper . ["" "10" "11" "15" "17" "18" "19"]) (tempsMaxLower . ["" "7" "7" "10" "13" "14" "13"])) ((area (name . "大島") (code . "44172")) (tempsMin . ["" "2" "3" "4" "6" "8" "7"]) (tempsMinUpper . ["" "4" "5" "6" "7" "10" "9"]) (tempsMinLower . ["" "1" "1" "2" "4" "5" "4"]) (tempsMax . ["" "10" "11" "13" "15" "15" "16"]) (tempsMaxUpper . ["" "11" "13" "15" "16" "17" "18"]) (tempsMaxLower . ["" "8" "9" "11" "13" "14" "14"])) ((area (name . "八丈島") (code . "44263")) (tempsMin . ["" "5" "6" "7" "9" "11" "10"]) (tempsMinUpper . ["" "7" "8" "9" "11" "13" "12"]) (tempsMinLower . ["" "4" "5" "6" "7" "9" "7"]) (tempsMax . ["" "9" "11" "13" "15" "16" "16"]) (tempsMaxUpper . ["" "11" "12" "14" "16" "17" "18"]) (tempsMaxLower . ["" "8" "9" "11" "13" "14" "14"])) ((area (name . "父島") (code . "44301")) (tempsMin . ["" "14" "15" "16" "16" "17" "17"]) (tempsMinUpper . ["" "16" "16" "17" "17" "18" "19"]) (tempsMinLower . ["" "13" "13" "14" "15" "15" "15"]) (tempsMax . ["" "19" "19" "20" "21" "21" "21"]) (tempsMaxUpper . ["" "20" "20" "22" "22" "23" "22"]) (tempsMaxLower . ["" "18" "18" "19" "19" "20" "20"]))]))]) 38 | (tempAverage (areas . [((area (name . "東京") (code . "44132")) (min . "2.9") (max . "11.7")) ((area (name . "大島") (code . "44172")) (min . "4.8") (max . "12.3")) ((area (name . "八丈島") (code . "44263")) (min . "8.1") (max . "14.3")) ((area (name . "父島") (code . "44301")) (min . "15.9") (max . "20.8"))])) 39 | (precipAverage (areas . [((area (name . "東京") (code . "44132")) (min . "5.6") (max . "26.5")) ((area (name . "大島") (code . "44172")) (min . "17.6") (max . "58.5")) ((area (name . "八丈島") (code . "44263")) (min . "33.0") (max . "67.7")) ((area (name . "父島") (code . "44301")) (min . "2.7") (max . "15.3"))])) 40 | ) 41 | ] 42 | -------------------------------------------------------------------------------- /example-data/jma-forecast-東京-20220221-0754.json.el: -------------------------------------------------------------------------------- 1 | 2 | ;;2022-02-21 07:54 3 | ;;(jma-forecast-data "130000") 4 | 5 | [ 6 | ((publishingOffice . "気象庁") 7 | (reportDatetime . "2022-02-21T05:00:00+09:00") 8 | (timeSeries 9 | . [ 10 | ((timeDefines . ["2022-02-21T05:00:00+09:00" "2022-02-22T00:00:00+09:00"]) 11 | (areas 12 | . [ 13 | ((area (name . "東京地方") (code . "130010")) (weatherCodes . ["100" "100"]) (weathers . ["晴れ" "晴れ"]) (winds . ["北西の風 23区西部 では はじめ 北の風 強く" "北西の風 後 北の風"]) (waves . ["1.5メートル" "0.5メートル"])) 14 | ((area (name . "伊豆諸島北部") (code . "130020")) (weatherCodes . ["210" "101"]) (weathers . ["くもり 昼過ぎ から 時々 晴れ 所により 昼前 まで 雪か雨" "晴れ 時々 くもり"]) (winds . ["西の風 強く 新島 では はじめ 西の風 非常に強く" "西の風 強く"]) (waves . ["3メートル ただし 新島 では 4メートル 後 3メートル" "3メートル"])) 15 | ((area (name . "伊豆諸島南部") (code . "130030")) (weatherCodes . ["200" "201"]) (weathers . ["くもり 所により 雨か雪" "くもり 時々 晴れ"]) (winds . ["西の風 非常に強く 後 強く" "西の風 強く"]) (waves . ["6メートル 後 4メートル ただし 三宅島 では 5メートル 後 4メートル" "4メートル"])) 16 | ((area (name . "小笠原諸島") (code . "130040")) (weatherCodes . ["201" "210"]) (weathers . ["くもり 時々 晴れ" "くもり 昼前 から 時々 晴れ"]) (winds . ["北の風 やや強く" "北の風"]) (waves . ["4メートル うねり を伴う" "4メートル 後 2.5メートル うねり を伴う"]))]) 17 | ) 18 | ((timeDefines . ["2022-02-21T06:00:00+09:00" "2022-02-21T12:00:00+09:00" "2022-02-21T18:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-22T06:00:00+09:00" "2022-02-22T12:00:00+09:00" "2022-02-22T18:00:00+09:00"]) 19 | (areas 20 | . [ 21 | ((area (name . "東京地方") (code . "130010")) (pops . ["0" "0" "0" "0" "0" "10" "0"])) 22 | ((area (name . "伊豆諸島北部") (code . "130020")) (pops . ["20" "10" "10" "10" "10" "10" "10"])) 23 | ((area (name . "伊豆諸島南部") (code . "130030")) (pops . ["20" "20" "20" "10" "20" "20" "10"])) 24 | ((area (name . "小笠原諸島") (code . "130040")) (pops . ["10" "10" "10" "10" "10" "10" "10"])) 25 | ])) 26 | ((timeDefines . ["2022-02-21T09:00:00+09:00" "2022-02-21T00:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-22T09:00:00+09:00"]) 27 | (areas 28 | . [ 29 | ((area (name . "東京") (code . "44132")) (temps . ["10" "10" "0" "9"])) 30 | ((area (name . "大島") (code . "44172")) (temps . ["10" "10" "3" "10"])) 31 | ((area (name . "八丈島") (code . "44263")) (temps . ["9" "9" "5" "11"])) 32 | ((area (name . "父島") (code . "44301")) (temps . ["18" "18" "13" "18"])) 33 | ])) 34 | ]) 35 | ) 36 | 37 | ;;週間予報 38 | ((publishingOffice . "気象庁") 39 | (reportDatetime . "2022-02-20T17:00:00+09:00") 40 | (timeSeries 41 | . [ 42 | ((timeDefines . ["2022-02-21T00:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00"]) 43 | (areas 44 | . [ 45 | ((area (name . "東京地方") (code . "130010")) (weatherCodes . ["100" "101" "101" "101" "101" "101" "201"]) (pops . ["" "10" "10" "10" "10" "20" "30"]) (reliabilities . ["" "" "A" "A" "A" "A" "A"])) 46 | ((area (name . "伊豆諸島北部") (code . "130020")) (weatherCodes . ["210" "101" "101" "101" "101" "101" "200"]) (pops . ["" "20" "20" "20" "20" "20" "40"]) (reliabilities . ["" "" "A" "A" "A" "A" "B"])) 47 | ((area (name . "伊豆諸島南部") (code . "130030")) (weatherCodes . ["200" "201" "201" "101" "201" "201" "202"]) (pops . ["" "30" "30" "20" "30" "30" "50"]) (reliabilities . ["" "" "A" "A" "A" "B" "C"])) 48 | ((area (name . "小笠原諸島") (code . "130040")) (weatherCodes . ["210" "101" "101" "201" "201" "201" "201"]) (pops . ["" "20" "20" "30" "30" "30" "30"]) (reliabilities . ["" "" "A" "A" "A" "A" "A"])) 49 | ]) 50 | ) 51 | 52 | ((timeDefines . ["2022-02-21T00:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00"]) 53 | (areas 54 | . [ 55 | ((area (name . "東京") (code . "44132")) (tempsMin . ["" "0" "0" "0" "0" "1" "4"]) (tempsMinUpper . ["" "2" "2" "2" "2" "2" "6"]) (tempsMinLower . ["" "-1" "-1" "-1" "-1" "-1" "1"]) (tempsMax . ["" "11" "9" "10" "13" "15" "17"]) (tempsMaxUpper . ["" "12" "11" "12" "15" "18" "19"]) (tempsMaxLower . ["" "9" "8" "8" "11" "13" "14"])) 56 | ((area (name . "大島") (code . "44172")) (tempsMin . ["" "3" "3" "3" "4" "5" "9"]) (tempsMinUpper . ["" "5" "4" "5" "6" "8" "11"]) (tempsMinLower . ["" "1" "1" "1" "2" "3" "6"]) (tempsMax . ["" "11" "10" "12" "14" "15" "15"]) (tempsMaxUpper . ["" "12" "11" "13" "15" "17" "17"]) (tempsMaxLower . ["" "9" "9" "10" "12" "13" "13"])) 57 | ((area (name . "八丈島") (code . "44263")) (tempsMin . ["" "5" "6" "6" "8" "9" "11"]) (tempsMinUpper . ["" "7" "7" "8" "9" "11" "13"]) (tempsMinLower . ["" "4" "4" "4" "6" "8" "8"]) (tempsMax . ["" "11" "10" "12" "14" "16" "16"]) (tempsMaxUpper . ["" "13" "11" "13" "15" "17" "18"]) (tempsMaxLower . ["" "10" "8" "10" "12" "14" "15"])) 58 | ((area (name . "父島") (code . "44301")) (tempsMin . ["" "13" "14" "15" "15" "17" "18"]) (tempsMinUpper . ["" "15" "16" "16" "17" "18" "20"]) (tempsMinLower . ["" "12" "13" "13" "14" "15" "16"]) (tempsMax . ["" "18" "19" "19" "20" "22" "22"]) (tempsMaxUpper . ["" "20" "20" "20" "22" "23" "23"]) (tempsMaxLower . ["" "17" "18" "18" "19" "20" "21"])) 59 | ]) 60 | ) 61 | ]) 62 | (tempAverage (areas . [((area (name . "東京") (code . "44132")) (min . "2.8") (max . "11.6")) ((area (name . "大島") (code . "44172")) (min . "4.7") (max . "12.2")) ((area (name . "八丈島") (code . "44263")) (min . "8.1") (max . "14.2")) ((area (name . "父島") (code . "44301")) (min . "15.8") (max . "20.8"))])) 63 | (precipAverage (areas . [((area (name . "東京") (code . "44132")) (min . "5.0") (max . "24.7")) ((area (name . "大島") (code . "44172")) (min . "16.6") (max . "56.8")) ((area (name . "八丈島") (code . "44263")) (min . "32.1") (max . "66.0")) ((area (name . "父島") (code . "44301")) (min . "2.6") (max . "15.5"))])) 64 | ) 65 | ] 66 | -------------------------------------------------------------------------------- /example-data/jma-forecast-week_area.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-json-get "https://www.jma.go.jp/bosai/forecast/const/week_area.json") 2 | 3 | ( 4 | (\120000 . [((srf . "120020") (week . "120000") (amedas . "45147"))]) 5 | (\220000 . [((srf . "220010") (week . "220000") (amedas . "50331"))]) 6 | (\210000 . [((srf . "210010") (week . "210000") (amedas . "52586")) ((srf . "210010") (week . "210010") (amedas . "52586")) ((srf . "210020") (week . "210020") (amedas . "52146"))]) 7 | (\230000 . [((srf . "230010") (week . "230000") (amedas . "51106"))]) 8 | (\240000 . [((srf . "240010") (week . "240000") (amedas . "53133"))]) 9 | (\150000 . [((srf . "150010") (week . "150000") (amedas . "54232"))]) 10 | (\160000 . [((srf . "160010") (week . "160000") (amedas . "55102"))]) 11 | (\170000 . [((srf . "170010") (week . "170000") (amedas . "56227"))]) 12 | (\180000 . [((srf . "180010") (week . "180000") (amedas . "57066"))]) 13 | (\250000 . [((srf . "250020") (week . "250000") (amedas . "60131")) ((srf . "250020") (week . "250020") (amedas . "60131")) ((srf . "250010") (week . "250010") (amedas . "60216"))]) 14 | (\260000 . [((srf . "260010") (week . "260000") (amedas . "61286")) ((srf . "260020") (week . "260020") (amedas . "61111")) ((srf . "260010") (week . "260010") (amedas . "61286"))]) 15 | (\290000 . [((srf . "290010") (week . "290000") (amedas . "64036"))]) 16 | (\270000 . [((srf . "270000") (week . "270000") (amedas . "62078"))]) 17 | (\280000 . [((srf . "280010") (week . "280000") (amedas . "63518")) ((srf . "280020") (week . "280020") (amedas . "63051")) ((srf . "280010") (week . "280010") (amedas . "63518"))]) 18 | (\300000 . [((srf . "300010") (week . "300000") (amedas . "65042"))]) 19 | (\320000 . [((srf . "320010") (week . "320000") (amedas . "68132"))]) 20 | (\310000 . [((srf . "310010") (week . "310000") (amedas . "69122"))]) 21 | (\330000 . [((srf . "330010") (week . "330000") (amedas . "66408")) ((srf . "330020") (week . "330020") (amedas . "66186")) ((srf . "330010") (week . "330010") (amedas . "66408"))]) 22 | (\340000 . [((srf . "340010") (week . "340000") (amedas . "67437")) ((srf . "340020") (week . "340020") (amedas . "67116")) ((srf . "340010") (week . "340010") (amedas . "67437"))]) 23 | (\370000 . [((srf . "370000") (week . "370000") (amedas . "72086"))]) 24 | (\360000 . [((srf . "360010") (week . "360000") (amedas . "71106"))]) 25 | (\380000 . [((srf . "380010") (week . "380000") (amedas . "73166"))]) 26 | (\390000 . [((srf . "390010") (week . "390000") (amedas . "74181"))]) 27 | (\350000 . [((srf . "350010") (week . "350000") (amedas . "81428"))]) 28 | (\400000 . [((srf . "400010") (week . "400000") (amedas . "82182"))]) 29 | (\440000 . [((srf . "440010") (week . "440000") (amedas . "83216"))]) 30 | (\410000 . [((srf . "410010") (week . "410000") (amedas . "85142"))]) 31 | (\430000 . [((srf . "430010") (week . "430000") (amedas . "86141"))]) 32 | (\420000 . [((srf . "420010") (week . "420000") (amedas . "84496")) ((srf . "420030") (week . "420030") (amedas . "84072")) ((srf . "420010") (week . "420100") (amedas . "84496"))]) 33 | (\450000 . [((srf . "450010") (week . "450000") (amedas . "87376"))]) 34 | (\460100 . [((srf . "460010") (week . "460100") (amedas . "88317"))]) 35 | (\460040 . [((srf . "460040") (week . "460040") (amedas . "88836"))]) 36 | (\471000 . [((srf . "471010") (week . "471000") (amedas . "91197"))]) 37 | (\472000 . [((srf . "472000") (week . "472000") (amedas . "92011"))]) 38 | (\473000 . [((srf . "473000") (week . "473000") (amedas . "93041"))]) 39 | (\474000 . [((srf . "474010") (week . "474000") (amedas . "94081"))]) 40 | (\011000 . [((srf . "011000") (week . "011000") (amedas . "11016"))]) 41 | (\012000 . [((srf . "012010") (week . "012000") (amedas . "12442"))]) 42 | (\013000 . [((srf . "013010") (week . "013000") (amedas . "17341"))]) 43 | (\014100 . [((srf . "014020") (week . "014000") (amedas . "19432")) ((srf . "014020") (week . "014100") (amedas . "19432"))]) 44 | (\014030 . [((srf . "014030") (week . "014000") (amedas . "19432")) ((srf . "014030") (week . "014030") (amedas . "20432"))]) 45 | (\015000 . [((srf . "015010") (week . "015000") (amedas . "21323"))]) 46 | (\016000 . [((srf . "016010") (week . "016000") (amedas . "14163"))]) 47 | (\017000 . [((srf . "017010") (week . "017000") (amedas . "23232"))]) 48 | (\020000 . [((srf . "020010") (week . "020010") (amedas . "31312")) ((srf . "020030") (week . "020200") (amedas . "31602")) ((srf . "020010") (week . "020100") (amedas . "31312")) ((srf . "020030") (week . "020030") (amedas . "31602"))]) 49 | (\050000 . [((srf . "050010") (week . "050000") (amedas . "32402"))]) 50 | (\030000 . [((srf . "030010") (week . "030000") (amedas . "33431")) ((srf . "030010") (week . "030010") (amedas . "33431")) ((srf . "030020") (week . "030100") (amedas . "33472"))]) 51 | (\060000 . [((srf . "060010") (week . "060000") (amedas . "35426"))]) 52 | (\040000 . [((srf . "040010") (week . "040000") (amedas . "34392")) ((srf . "040010") (week . "040010") (amedas . "34392")) ((srf . "040020") (week . "040020") (amedas . "34461"))]) 53 | (\070000 . [((srf . "070010") (week . "070100") (amedas . "36127")) ((srf . "070030") (week . "070030") (amedas . "36361"))]) 54 | (\200000 . [((srf . "200010") (week . "200000") (amedas . "48156")) ((srf . "200010") (week . "200010") (amedas . "48156")) ((srf . "200020") (week . "200100") (amedas . "48361"))]) 55 | (\190000 . [((srf . "190010") (week . "190000") (amedas . "49142"))]) 56 | (\100000 . [((srf . "100010") (week . "100000") (amedas . "42251")) ((srf . "100020") (week . "100020") (amedas . "42091")) ((srf . "100010") (week . "100010") (amedas . "42251"))]) 57 | (\090000 . [((srf . "090010") (week . "090000") (amedas . "41277"))]) 58 | (\080000 . [((srf . "080010") (week . "080000") (amedas . "40201"))]) 59 | (\110000 . [((srf . "110020") (week . "110000") (amedas . "43056"))]) 60 | (\130000 . [((srf . "130010") (week . "130010") (amedas . "44132")) ((srf . "130030") (week . "130100") (amedas . "44263")) ((srf . "130020") (week . "130020") (amedas . "44172")) ((srf . "130030") (week . "130030") (amedas . "44263")) ((srf . "130040") (week . "130040") (amedas . "44301"))]) 61 | (\140000 . [((srf . "140010") (week . "140000") (amedas . "46106"))])) 62 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Emacsから気象庁のデータにアクセスする 2 | 3 | * jma-forecast.el 4 | 5 | このEmacs Lispは気象庁の天気予報データにアクセスする。 6 | 7 | ** 天気予報のミニバッファ表示 8 | 9 | =M-x jma-forecast-show= を実行するとミニバッファに天気予報を表示する。 10 | 11 | [[file:screenshot/forecast-minibuffer.png]] 12 | 13 | 事前に次の変数で予報する場所を設定しておく必要がある。 14 | - ~jma-forecast-location-office~ 15 | - ~jma-forecast-location-class10~ 16 | - ~jma-forecast-location-amedas~ 17 | - ~jma-forecast-location-week-area~ 18 | - ~jma-forecast-location-week-amedas~ 19 | 20 | =M-x jma-forecast-location-setup= を実行すると入力補完付きでこれらの変数を設定できる。 21 | 22 | 場所を指定するコードについては[[*エリアコード][エリアコード]]を参照すること。 23 | 24 | ** Diary連携 25 | 26 | [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Sexp-Diary-Entries.html][ダイアリーエントリー]]や[[https://orgmode.org/manual/Weekly_002fdaily-agenda.html#index-diary-integration][org-modeのagendaファイル]]に次の文を追加すると、現在の日付から向こう8日間に天気予報のエントリーが追加される。 27 | 28 | #+begin_src org 29 | %%(jma-diary-weathers "130000" "130010" "44132" "130010" "44132") 30 | #+end_src 31 | 32 | #+DOWNLOADED: screenshot @ 2022-02-23 19:31:18 33 | [[file:screenshot/forecast-diary.png]] 34 | 35 | 引数の数字は予報する場所を指定するコードであり、上の例では次の意味を持つ。 36 | 37 | - 府県予報区: 東京都(130000) 38 | - 一次細分区域: 東京地方(130010) 39 | - アメダス観測所: 東京(44132) 40 | - 週間予報区域: 東京地方(130010) 41 | - アメダス観測所(週間): 東京(44132) 42 | 43 | 場所を指定するコードについては[[*エリアコード][エリアコード]]を参照すること。 44 | 45 | また、これらのコードは =M-x jma-forecast-area-read= で調べることもできる。 46 | 47 | ** Emacs Lispから使う 48 | *** 今日の東京の天気予報を取得する 49 | 50 | #+name: example-get-tokyo-forecast 51 | #+begin_src elisp :results pp :exports both :cache yes 52 | (require 'jma-forecast) 53 | 54 | (jma-forecast-weather-for-date 55 | (jma-forecast-get "130000") ;;130000はoffice-code(府県予報区) 56 | "130010" ;;class10-code (一次細分区域) 57 | "44132" ;;amedas-code (アメダス観測所番号) 58 | "130010" ;;week-area-code (週間予報区域。府県予報区を少し細分化したもの) 59 | "44132" ;;week-amedas-code (週間予報でのアメダス観測所番号) 60 | (jma-date-today)) ;; 日付はcalendarパッケージと同じ形式 (MM DD YYYY) 61 | #+end_src 62 | 63 | 結果は次の通り。 64 | 65 | #+RESULTS[9e9214b59edeac33ead47fec4c242c26adc3cac4]: example-get-tokyo-forecast 66 | #+begin_example 67 | ((report-type . "detailed") 68 | (class10-area 69 | (name . "東京地方") 70 | (code . "130010")) 71 | (weather . "くもり 夜のはじめ頃 晴れ") 72 | (weather-code . "201") 73 | (wind . "北の風 23区西部 では 北の風 やや強く") 74 | (wave . "0.5メートル 後 1メートル") 75 | (pops "10") 76 | (pop . "10")) 77 | #+end_example 78 | 79 | *** 東京都の週間天気予報の一つ目の時系列データを取得する 80 | 81 | #+name: example-get-tokyo-forecast-week-ts0 82 | #+begin_src elisp :results pp :exports both :cache yes 83 | (jma-forecast-report-time-series-at 84 | (jma-forecast-week-report (jma-forecast-get "130000")) 85 | 0) 86 | #+end_src 87 | 88 | 結果は次の通り。 89 | 90 | #+RESULTS[6bad4b2b91a72fed4bedc01e49951f7ce07db047]: example-get-tokyo-forecast-week-ts0 91 | #+begin_example 92 | ((timeDefines . 93 | ["2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00" "2022-02-28T00:00:00+09:00" "2022-03-01T00:00:00+09:00" "2022-03-02T00:00:00+09:00"]) 94 | (areas . 95 | [((area 96 | (name . "東京地方") 97 | (code . "130010")) 98 | (weatherCodes . 99 | ["101" "101" "101" "201" "101" "201" "201"]) 100 | (pops . 101 | ["" "10" "10" "30" "10" "30" "30"]) 102 | (reliabilities . 103 | ["" "" "A" "B" "A" "A" "A"])) 104 | ((area 105 | (name . "伊豆諸島北部") 106 | (code . "130020")) 107 | (weatherCodes . 108 | ["201" "101" "101" "200" "101" "200" "201"]) 109 | (pops . 110 | ["" "20" "20" "40" "10" "40" "30"]) 111 | (reliabilities . 112 | ["" "" "A" "C" "A" "C" "A"])) 113 | ((area 114 | (name . "伊豆諸島南部") 115 | (code . "130030")) 116 | (weatherCodes . 117 | ["200" "101" "101" "202" "101" "200" "201"]) 118 | (pops . 119 | ["" "20" "20" "50" "10" "40" "30"]) 120 | (reliabilities . 121 | ["" "" "A" "C" "A" "C" "B"])) 122 | ((area 123 | (name . "小笠原諸島") 124 | (code . "130040")) 125 | (weatherCodes . 126 | ["200" "200" "101" "201" "101" "101" "101"]) 127 | (pops . 128 | ["" "40" "20" "30" "20" "20" "20"]) 129 | (reliabilities . 130 | ["" "" "B" "A" "A" "A" "A"]))])) 131 | #+end_example 132 | 133 | *** 長野県の特定の日の天気予報を取得し、文字列化し、バッファに挿入する 134 | 135 | #+name: example-get-nagano-forecast-insert 136 | #+begin_src elisp :results pp 137 | (let* ((forecast (jma-forecast-get "200000")) 138 | (weather (jma-forecast-weather-for-date 139 | forecast 140 | "200020" ;;中部 141 | "48491" ;;諏訪 142 | '("200100" "200000") ;;中部・南部 または 長野県全域 143 | '("48361" "48156") ;;松本 または 長野 144 | (jma-date 2022 2 23))) ;;2022年2月23日 145 | (weather-str (jma-weather-to-string weather))) 146 | (when weather-str 147 | (insert weather-str))) 148 | #+end_src 149 | 150 | 151 | #+DOWNLOADED: screenshot @ 2022-02-23 19:33:50 152 | [[file:screenshot/forecast-insert.png]] 153 | 154 | 文字列のフォーマットは、 ~jma-weather-default-template~ 変数か ~jma-weather-to-string~ の引数で指定できる。 155 | 156 | ** エリアコード 157 | 158 | 天気予報を取得するには、予報する場所を番号(コード)で指定する必要がある。 159 | 160 | 気象庁では様々な場所表すをコードが使用されているが、天気予報で使用するものは以下の通り。 161 | 162 | - office-code : 府県予報区コード (概ね都道府県) 163 | - class10-code : 一次細分区域コード (府県の中を大ざっぱに分割したもの) 164 | - amedas-code : アメダス観測所コード 165 | - week-area-code : 週間予報区域コード(府県予報区を少し細分化したもの)(※独自呼称) 166 | 167 | 天気予報データは府県予報区(office)単位でダウンロードできる。 168 | 169 | 天気予報(明後日までの詳細)は一次細分区域(class10)毎に行われている。 170 | (参考: https://www.jma.go.jp/jma/kishou/know/saibun/) 171 | 172 | 気温や降水量に関する情報はアメダス観測所(amedas)毎に発表されている。 173 | (参考: https://www.jma.go.jp/jma/kishou/know/amedas/kaisetsu.html) 174 | 175 | 週間天気予報は原則として府県予報区毎に行われているが、地形や季節等の都合で多少の細分化が行われている(参考: https://www.jma.go.jp/jma/kishou/know/kurashi/shukan.html)。ここでは細分化後の区域を週間予報区域(week-area)と呼ぶことにする。 176 | 177 | 例(2022-02-23現在): 178 | 179 | - 長野県(office=200000) 180 | - 詳細予報 181 | - 一次細分区域(class10) 182 | - 200010 北部 183 | - 200020 中部 184 | - 200030 南部 185 | - アメダス観測所(amedas) 186 | - 48156 長野 (北部) 187 | - 48361 松本 (中部) 188 | - 48491 諏訪 (中部) 189 | - 48767 飯田 (南部) 190 | - 48331 軽井沢 (中部) 191 | - 週間予報 192 | - 週間予報区域(week-area) (※季節によっては分割されないことに注意) 193 | - 200010 北部 194 | - 200100 中部・南部 195 | - アメダス観測所(amedas) 196 | - 48156 長野 (北部) 197 | - 48361 松本 (中部・南部) 198 | 199 | 実際に長野県の予報がどのように構成されているかは次のURLから確認できる。 200 | 201 | - 人間閲覧用URL: https://www.jma.go.jp/bosai/forecast/#area_type=offices&area_code=200000 202 | - JSON URL: https://www.jma.go.jp/bosai/forecast/data/forecast/200000.json 203 | 204 | 各エリア間の対応関係は次のURLから得られる。 205 | - https://www.jma.go.jp/bosai/forecast/const/forecast_area.json (class10とamedasの対応関係) 206 | - https://www.jma.go.jp/bosai/forecast/const/week_area.json (week-areaとamedasの対応関係) 207 | - https://www.jma.go.jp/bosai/common/const/area.json (officeとclass10の対応関係) 208 | 209 | コードは =M-x jma-forecast-area-read= で調べることもできる。 210 | 211 | * jma-weather-code.el 212 | 213 | このEmacs Lispは天気コードに関する処理を提供する。 214 | 215 | ** 天気コードの情報を取得する 216 | 217 | #+begin_src elisp :results pp :exports both :cache yes 218 | (list 219 | (jma-weather-code-image-daytime 101) 220 | (jma-weather-code-image-night 101) 221 | (jma-weather-code-image 101 nil) 222 | (jma-weather-code-text-ja 101) 223 | (jma-weather-code-text-en 101)) 224 | #+end_src 225 | 226 | #+RESULTS[928c82e78e9a1549177f163796049d380ddd8df3]: 227 | : ("101.svg" "501.svg" "101.svg" "晴時々曇" "PARTLY CLOUDY") 228 | 229 | ** 天気コードの画像を取得する 230 | 231 | 次のコードは天気コード101に対応する画像を表示するテキストプロパティが付加された文字列を返す。 232 | 233 | #+begin_src elisp :results pp :exports both :eval no-export 234 | (jma-weather-code-image-string 101) 235 | #+end_src 236 | 237 | #+RESULTS: 238 | : #("_" 0 1 239 | : (display 240 | : (image :type svg :file "~/.emacs.d/.jma-weather-cache/101.svg" :scale 1 :height 17 :ascent center))) 241 | 242 | テキスト端末の場合やSVGをサポートしていない場合はnilを返す。 243 | 244 | ** 画像のダウンロードについて 245 | 246 | 天気マークの画像は ~jma-weather-code-image-dir~ 変数で指定するディレクトリ(デフォルトは =~/.emacs.d/.jma-weather-cache=)に格納される。 247 | 248 | =M-x jma-weather-code-image-download-all= で全ての画像を一括でダウンロードできる。 249 | -------------------------------------------------------------------------------- /jma-amedas.el: -------------------------------------------------------------------------------- 1 | ;;; jma-amedas.el --- 気象庁アメダス関連処理 -*- lexical-binding: t; -*- 2 | 3 | ;; Copyright (C) 2022 AKIYAMA Kouhei 4 | 5 | ;; Author: AKIYAMA Kouhei 6 | ;; Keywords: comm 7 | 8 | ;; This program is free software; you can redistribute it and/or modify 9 | ;; it under the terms of the GNU General Public License as published by 10 | ;; the Free Software Foundation, either version 3 of the License, or 11 | ;; (at your option) any later version. 12 | 13 | ;; This program is distributed in the hope that it will be useful, 14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ;; GNU General Public License for more details. 17 | 18 | ;; You should have received a copy of the GNU General Public License 19 | ;; along with this program. If not, see . 20 | 21 | ;;; Commentary: 22 | 23 | ;; 気象庁からアメダスに関する情報を取得するためのコードです。 24 | 25 | ;; * 使用例 26 | ;; ** 選択したアメダス観測所の最新の気温を取得する 27 | ;; (jma-amedas-sample-temp ;;気温を取得 28 | ;; (jma-amedas-point-latest ;;最新のデータを取得 29 | ;; (jma-amedas-read-amedas-code))) ;;観測所を選んでもらう 30 | ;; 31 | ;; ** 最新のデータから過去1日分のデータを取得する 32 | ;; (let ((latest-time (jma-amedas-latest-time))) 33 | ;; (jma-amedas-point-samples-between "44116" (time-add latest-time (* -24 60 60)) latest-time)) 34 | 35 | 36 | ;;; Code: 37 | 38 | (require 'jma-utils) 39 | (require 'jma-area) 40 | 41 | 42 | 43 | ;;;; 観測所情報 44 | ;; jma-area.elに書くべきか迷う。jma-forecast.el等他でも使用するので。 45 | 46 | ;;;;; 観測所情報取得 47 | 48 | (defvar jma-amedas-points nil) 49 | 50 | (defun jma-amedas-points () 51 | (or jma-amedas-points 52 | (setq jma-amedas-points 53 | (jma-json-get 54 | "https://www.jma.go.jp/bosai/amedas/const/amedastable.json")))) 55 | 56 | (defun jma-amedas-point (amedas-code) 57 | "AMEDAS-CODEで指定されたコードを持つ観測所の情報を返します。" 58 | (assq (jma-ensure-symbol amedas-code) (jma-amedas-points))) 59 | 60 | (defun jma-amedas-point-code (amedas-point) 61 | (symbol-name (car amedas-point))) 62 | 63 | (defun jma-amedas-point-name (amedas-point) 64 | (alist-get 'kjName (cdr amedas-point))) 65 | 66 | ;;;;; 観測所検索 67 | ;; jma-area.elに書くべきか迷う。jma-forecast.el等他でも使用するので。 68 | 69 | (defvar jma-amedas-class20-list nil) 70 | 71 | (defun jma-amedas-class20-list () 72 | "二次細分区域から近いアメダス観測所のリストを返します。" 73 | (or jma-amedas-class20-list 74 | (setq 75 | jma-amedas-class20-list 76 | (jma-json-get 77 | "https://www.jma.go.jp/bosai/amedas/const/amedas_class20_list.json")))) 78 | 79 | (defun jma-amedas-near-class20 (class20-code) 80 | "二次細分区域CLASS20から近いアメダス観測所番号をいくつか返します。" 81 | (alist-get (jma-ensure-symbol class20-code) (jma-amedas-class20-list))) 82 | ;;Example (jma-amedas-near-class20 "0120200") 83 | 84 | (defun jma-amedas-read-amedas-code (&optional amedas-codes prompt) 85 | "複数のアメダス観測所コードから一つを選びます。" 86 | (jma-choose-from-alist 87 | (or prompt "アメダス観測所: ") 88 | (mapcar 89 | (lambda (amedas-code) 90 | (cons 91 | (jma-amedas-point-name (jma-amedas-point amedas-code)) 92 | amedas-code)) 93 | (or amedas-codes 94 | ;; 省略時は府県予報区、二次細分区域を選んでもらう。 95 | (jma-amedas-near-class20 96 | (jma-area-read-class20-in-office (jma-area-read-office))))))) 97 | ;;(jma-amedas-read-amedas-code) 98 | 99 | 100 | 101 | ;;;; 計測データサンプル処理 102 | 103 | (defun jma-amedas-sample-proc-aqc (value-vec) 104 | "シーケンスの第2要素が0のときだけ第1要素の値を返し、それ以外の時nilを返します。" 105 | ;; 参考: 106 | ;; https://qiita.com/e_toyoda/items/7a293313a725c4d306c0#:~:text=%E5%90%84%E8%A6%81%E7%B4%A0%E3%81%8C2%E3%81%A4%E3%81%AE%E6%95%B0%E5%80%A4%E3%81%AE%E9%85%8D%E5%88%97%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%81%8C%E3%80%81%E5%85%88%E3%81%AEfloat%E3%81%8C%E5%80%A4%E3%81%9D%E3%81%AE%E3%82%82%E3%81%AE%E3%80%81%E5%BE%8C%E3%81%AE0%E3%81%B0%E3%81%8B%E3%82%8A%E3%81%AA%E3%81%AE%E3%81%8CAQC%E3%83%95%E3%83%A9%E3%82%B0%E3%81%A7%E3%81%99%E3%80%82 107 | ;; > 各要素が2つの数値の配列になっていますが、先のfloatが値そのもの、後の0ばかりなのがAQCフラグです。 108 | 109 | ;; 参考: 110 | ;; https://www.wxbc.jp/wp-content/uploads/2018/07/seminar_180706_03.pdf 111 | ;; > 0 正常 112 | ;; > 1 準正常(やや疑わしい) 113 | ;; > 2 非常に疑わしい 114 | ;; > 3 利用に適さない 115 | ;; > 4 観測値は期間内で資料数が不足している 116 | ;; > 5 点検又は計画休止のため欠測 117 | ;; > 6 障害のため欠測 118 | ;; > 7 この要素の観測はしていない 119 | (when (eq (elt value-vec 1) 0) 120 | (elt value-vec 0))) 121 | 122 | (defun jma-amedas-sample-time (sample) 123 | "サンプルの取得時刻を返します。" 124 | (let* ((date-str (symbol-name (car sample))) 125 | (year (string-to-number (substring date-str 0 4))) 126 | (month (string-to-number (substring date-str 4 6))) 127 | (day (string-to-number (substring date-str 6 8))) 128 | (hour (string-to-number (substring date-str 8 10))) 129 | ;; 必ず10分毎か分からないので 130 | (minute (string-to-number (substring date-str 10 12))) 131 | ;; 必ず00秒か分からないので 132 | (second (string-to-number (substring date-str 12 14)))) 133 | (encode-time (list second minute hour day month year nil nil 32400)))) 134 | 135 | (defun jma-amedas-sample-value (sample key) 136 | (jma-amedas-sample-proc-aqc 137 | (alist-get key (cdr sample)))) 138 | 139 | (defun jma-amedas-sample-temp (sample) 140 | "気温(℃)" 141 | (jma-amedas-sample-value sample 'temp)) 142 | 143 | (defun jma-amedas-sample-wind-direction (sample) 144 | "風向" 145 | (jma-amedas-sample-value sample 'windDirection)) 146 | 147 | (defun jma-amedas-sample-wind (sample) 148 | "風速(m/s)" 149 | (jma-amedas-sample-value sample 'wind)) 150 | 151 | (defun jma-amedas-sample-precipitation1h (sample) 152 | "(前1h)降水量(mm)" 153 | (jma-amedas-sample-value sample 'precipitation1h)) 154 | 155 | 156 | 157 | ;;;; 計測データ時間軸処理 158 | 159 | (defun jma-amedas-trim-sorted-samples-between (samples min-time max-time) 160 | "時刻でソート済みの計測データリストSAMPLESから、MIN-TIMEからMAX-TIME以外のデータを削除します。 161 | 162 | 新しいリストの先頭を返します。リストSAMPLESは変更されます。" 163 | (while (and samples 164 | (time-less-p (jma-amedas-sample-time (car samples)) min-time)) 165 | (setq samples (cdr samples))) 166 | (let ((first samples) 167 | last) 168 | (while (and samples 169 | (not (time-less-p max-time (jma-amedas-sample-time (car samples))))) 170 | (setq last samples) 171 | (setq samples (cdr samples))) 172 | (when last 173 | (setcdr last nil) 174 | first))) 175 | 176 | 177 | 178 | ;;;; 最新時刻 179 | 180 | (defun jma-amedas-latest-time () 181 | (let* ((res (jma-http-get "https://www.jma.go.jp/bosai/amedas/data/latest_time.txt")) 182 | (status (jma-http-status res))) 183 | (unless (= status 200) 184 | (error "HTTP status is not OK : %s" status)) 185 | (parse-iso8601-time-string (jma-http-body res)))) 186 | ;;Example: (format-time-string "%Y-%m-%d %H:%M:%S" (jma-amedas-latest-time)) 187 | 188 | 189 | 190 | ;;;; 全国計測データ取得 191 | 192 | (defun jma-amedas-map-samples (time) 193 | "全国にある観測所の指定時刻の計測データを返します。" 194 | (jma-json-get 195 | (format 196 | "https://www.jma.go.jp/bosai/amedas/data/map/%s.json" 197 | (format-time-string "%Y%m%d%H%M%S" time)))) 198 | ;;Example: (jma-amedas-map-samples (jma-amedas-latest-time)) 199 | 200 | 201 | 202 | ;;;; 観測所計測データ取得 203 | 204 | (defun jma-amedas-point-samples (amedas-code time) 205 | "指定地点、指定時間帯の計測データ(サンプル)のリストを返します。" 206 | (let* ((dt (decode-time time 32400)) 207 | (year (decoded-time-year dt)) 208 | (month (decoded-time-month dt)) 209 | (day (decoded-time-day dt)) 210 | (hour (decoded-time-hour dt))) 211 | (jma-json-get 212 | (format 213 | "https://www.jma.go.jp/bosai/amedas/data/point/%s/%04d%02d%02d_%02d.json" 214 | amedas-code 215 | year 216 | month 217 | day 218 | (- hour (% hour 3)))))) 219 | 220 | (defun jma-amedas-point-latest (amedas-code) 221 | "指定地点の最新の計測データを返します。" 222 | (car 223 | (last 224 | (jma-amedas-point-samples amedas-code (jma-amedas-latest-time))))) 225 | ;;Example: (jma-amedas-point-latest "44116") 226 | ;;Example: (jma-amedas-sample-temp (jma-amedas-point-latest "44116")) 227 | 228 | (defun jma-amedas-point-samples-between (amedas-code min-time max-time) 229 | (jma-amedas-trim-sorted-samples-between 230 | (cl-loop for time = min-time then (time-add time 10800) ;;3hours 231 | while (not (time-less-p max-time time)) ;; time <= max-time 232 | append (jma-amedas-point-samples amedas-code time)) 233 | min-time max-time)) 234 | 235 | (provide 'jma-amedas) 236 | ;;; jma-amedas.el ends here 237 | -------------------------------------------------------------------------------- /jma-utils.el: -------------------------------------------------------------------------------- 1 | ;;; jma-utils.el --- JMA Utilities -*- lexical-binding: t; -*- 2 | 3 | ;; Copyright (C) 2022 AKIYAMA Kouhei 4 | 5 | ;; Author: AKIYAMA Kouhei 6 | ;; Keywords: 7 | 8 | ;; This program is free software; you can redistribute it and/or modify 9 | ;; it under the terms of the GNU General Public License as published by 10 | ;; the Free Software Foundation, either version 3 of the License, or 11 | ;; (at your option) any later version. 12 | 13 | ;; This program is distributed in the hope that it will be useful, 14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ;; GNU General Public License for more details. 17 | 18 | ;; You should have received a copy of the GNU General Public License 19 | ;; along with this program. If not, see . 20 | 21 | ;;; Commentary: 22 | 23 | ;; 24 | 25 | ;;; Code: 26 | 27 | (require 'cl-lib) 28 | (require 'calendar) 29 | (require 'parse-time) 30 | 31 | ;;;; Customize 32 | 33 | (defgroup jma nil 34 | "Access to Japan Meteorological Agency" 35 | :prefix "jma-" 36 | :group 'comm) 37 | 38 | ;;;; HTTP 39 | 40 | (defun jma-http-parse-response (buffer) 41 | (with-current-buffer buffer 42 | (set-buffer-multibyte t) 43 | (goto-char (point-min)) 44 | (unless (looking-at "^HTTP/\\([^ ]+\\) +\\([0-9]+\\) +\\(.*\\)$") 45 | (error "Invalid HTTP response : %s" (buffer-substring (line-beginning-position) (line-end-position)))) 46 | (let ((http-ver (match-string 1)) 47 | (status (string-to-number (match-string 2))) 48 | (message (match-string 3)) 49 | (headers (cl-loop while (progn (forward-line) (not (eolp))) 50 | when (looking-at "^\\([^:\n]+\\): \\([^\n]*\\)$") 51 | collect (cons (match-string 1) (match-string 2)))) 52 | (body (progn 53 | (forward-line) 54 | (buffer-substring (point) (point-max))))) 55 | (list http-ver status message headers body)))) 56 | 57 | (defun jma-http-ver (res) (nth 0 res)) 58 | (defun jma-http-status (res) (nth 1 res)) 59 | (defun jma-http-message (res) (nth 2 res)) 60 | (defun jma-http-headers (res) (nth 3 res)) 61 | (defun jma-http-body (res) (nth 4 res)) 62 | 63 | (defun jma-http-get (url) 64 | (let ((buffer (url-retrieve-synchronously url))) 65 | (unwind-protect 66 | (jma-http-parse-response buffer) 67 | (kill-buffer buffer)))) 68 | 69 | ;;;; JSON 70 | 71 | (defun jma-json-get (url) 72 | (let* ((res (jma-http-get url)) 73 | (status (jma-http-status res))) 74 | (unless (= status 200) 75 | (error "HTTP status is not OK : %s" status)) 76 | (json-parse-string (jma-http-body res) :object-type 'alist))) 77 | 78 | ;;;; 日付処理 79 | 80 | (defun jma-date (y m d) 81 | (list m d y)) 82 | 83 | (defun jma-date-today (&optional tz) 84 | (let ((dt (decode-time nil tz))) 85 | (jma-date 86 | (decoded-time-year dt) 87 | (decoded-time-month dt) 88 | (decoded-time-day dt)))) 89 | 90 | (defun jma-date-to-time (date) 91 | (if (= (length date) 3) 92 | (encode-time 93 | (list 94 | 0 0 0 95 | (calendar-extract-day date) 96 | (calendar-extract-month date) 97 | (calendar-extract-year date) 98 | nil nil 99 | 32400 ;;常にJST(+09:00)で考える。 100 | )) 101 | ;; @todo support decoded time 102 | ;; encoded time? 103 | date)) 104 | 105 | (defun jma-date-inc-day (date &optional n) 106 | (jma-date 107 | (calendar-extract-year date) 108 | (calendar-extract-month date) 109 | (+ (calendar-extract-day date) (or n 1)))) 110 | 111 | ;;;; 時刻処理 112 | 113 | (defun jma-time-next-hour (time hours) 114 | "TIMEの次の時を返します。" 115 | (let* ((dt (decode-time time 32400)) 116 | (y (decoded-time-year dt)) 117 | (m (decoded-time-month dt)) 118 | (d (decoded-time-day dt)) 119 | (hour 120 | (cl-find-if 121 | (lambda (hour) 122 | (time-less-p 123 | time 124 | (encode-time (list 0 0 hour d m y nil nil 32400)))) 125 | hours))) 126 | (if hour 127 | (encode-time (list 0 0 hour d m y nil nil 32400)) 128 | (encode-time (list 0 0 (car hours) (1+ d) m y nil nil 32400))))) 129 | ;;(format-time-string "%Y-%m-%d %H:%M:%S" (jma-time-next-hour (encode-time '(0 0 17 22 2 2022 nil nil 32400)) '(5 11 17))) 130 | 131 | ;;;; 時系列データ処理 132 | 133 | (defun jma-not-empty-range-p (pair) 134 | (and pair 135 | (< (car pair) (cdr pair)))) 136 | 137 | (defun jma-time-series-range-in-time (time-series lower-time upper-time) 138 | "時系列データ TIME-SERIES 内で時間が LOWER-TIME 以上 UPPER-TIME 未満の範囲を要素インデックス値のペアで返します。" 139 | (let ((times (mapcar #'parse-iso8601-time-string (alist-get 'timeDefines time-series))) 140 | (i 0) lower-index upper-index) 141 | (while (and times 142 | (time-less-p (car times) lower-time)) 143 | (cl-incf i) 144 | (setq times (cdr times))) 145 | (setq lower-index i) 146 | (while (and times 147 | (time-less-p (car times) upper-time)) 148 | (cl-incf i) 149 | (setq times (cdr times))) 150 | (setq upper-index i) 151 | (cons lower-index upper-index))) 152 | 153 | (defun jma-time-series-range-in-date (time-series date) 154 | "時系列データ TIME-SERIES 内の DATE で指定した日付に該当する範囲を要素インデックス値のペアで返します。" 155 | (jma-time-series-range-in-time 156 | time-series 157 | (jma-date-to-time date) 158 | (jma-date-to-time (jma-date-inc-day date)))) 159 | 160 | (defun jma-time-series-area (time-series area-code) 161 | "時系列データ TIME-SERIES 内の AREA-CODE で指定された場所のデータを返します。" 162 | (cond 163 | ;; シーケンスの場合は要素のコードから探す。 164 | ((listp area-code) 165 | (seq-some 166 | (lambda (code) (jma-time-series-area time-series code)) 167 | area-code)) 168 | (t 169 | (seq-find 170 | (lambda (area) (equal (alist-get 'code (alist-get 'area area)) area-code)) 171 | (alist-get 'areas time-series))))) 172 | 173 | (defun jma-time-series-area-at (time-series area-index) 174 | (elt (alist-get 'areas time-series) area-index)) 175 | 176 | (defun jma-time-series-area-value-at (area field-name time-index) 177 | "時系列データの場所 AREA 内の FIELD-NAME で指定したデータの TIME-INDEX 番目を返します。" 178 | (elt (alist-get field-name area) time-index)) 179 | 180 | (defun jma-time-series-value-at (time-series area-code field-name time-index) 181 | "時系列データ TIME-SERIES から一つの値を取り出します。" 182 | (elt (alist-get field-name (jma-time-series-area time-series area-code)) time-index)) 183 | 184 | ;;;; 文字列テンプレート 185 | 186 | (defun jma-expand-template (template params) 187 | "TEMPLATEをPARAMSを使って展開します。 188 | 189 | TEMPLATEが関数の場合、単にTEMPLATEにPARAMSを引き渡します。 190 | 191 | TEMPLATEが文字列の場合、文字列中の展開指定を展開後文字列に置き換えます。 192 | 193 | 展開指定は {{{PNAME}}} または {{{PNAME:FMT}}} の形式です。" 194 | (cond 195 | ((functionp template) 196 | (funcall template params)) 197 | ((stringp template) 198 | (let ((result "") 199 | (pos 0)) 200 | (while (string-match "{{{\\([^:}]+\\)\\(?::\\([^}]+\\)\\)?}}}" template pos) 201 | (let* ((placeholder-beg (match-beginning 0)) 202 | (placeholder-end (match-end 0)) 203 | (pname (match-string 1 template)) 204 | (fmt (match-string 2 template)) 205 | ;; paramsのキーは文字列でもシンボルでもどちらでもOK 206 | (pvalue (cdr (or (assoc pname params) 207 | (assq (intern pname) params)))) 208 | ;; pvalueが関数なら、その関数を呼び出す 209 | (pvalue (if (functionp pvalue) 210 | (funcall pvalue params) 211 | pvalue)) 212 | ;; pvalueが非nilのときだけfmtを使って文字列化 213 | ;; {{{xxx: %s度}}}のように前後の文字を制御できるようにする 214 | (fmted-pvalue 215 | (if pvalue 216 | (format (or fmt "%s") pvalue) 217 | ""))) 218 | (setq result 219 | (concat 220 | result 221 | (substring template pos placeholder-beg) 222 | fmted-pvalue)) 223 | (setq pos placeholder-end))) 224 | (setq result (concat result (substring template pos))) 225 | result)))) 226 | 227 | ;;;; ユーザー入力 228 | 229 | (defun jma-choose-from-alist (prompt alist) 230 | (cdr (assoc (completing-read prompt alist nil t) alist))) 231 | 232 | ;;;; シンボル 233 | 234 | (defun jma-ensure-symbol (obj) 235 | (cond 236 | ((stringp obj) (intern obj)) 237 | ((symbolp obj) obj) 238 | ((integerp obj) (format "%s" obj)) 239 | (t (error "Not symbol or string")))) 240 | 241 | (provide 'jma-utils) 242 | ;;; jma-utils.el ends here 243 | -------------------------------------------------------------------------------- /example-data/jma-amedas-4416-20220226_06.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-json-get "https://www.jma.go.jp/bosai/amedas/data/point/44116/20220226_06.json") 2 | 3 | ( 4 | ;;2022-02-26 06:00:00 ~ 2022-02-26 08:50:00 まで10分毎 18個 5 | 6 | (\20220226060000 7 | (prefNumber . 44) 8 | (observationNumber . 116) 9 | (temp . [0.4 0]) 10 | (snow1h . [0 :null]) 11 | (snow6h . [0 :null]) 12 | (snow12h . [0 :null]) 13 | (snow24h . [0 :null]) 14 | (sun10m . [0 0]) 15 | (sun1h . [0.0 0]) 16 | (precipitation10m . [0.0 0]) 17 | (precipitation1h . [0.0 0]) 18 | (precipitation3h . [0.0 0]) 19 | (precipitation24h . [0.0 0]) 20 | (windDirection . [11 0]) 21 | (wind . [1.4 0]) 22 | (maxTempTime (hour . 15) (minute . 15)) 23 | (maxTemp . [2.9 0]) 24 | (minTempTime (hour . 20) (minute . 33)) 25 | (minTemp . [0.1 0]) 26 | (gustTime (hour . 20) (minute . 58)) 27 | (gustDirection . [12 0]) 28 | (gust . [2.7 0])) 29 | 30 | (\20220226061000 (prefNumber . 44) (observationNumber . 116) (temp . [0.2 0]) (sun10m . [0 0]) (sun1h . [0.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [11 0]) (wind . [1.3 0]) (maxTempTime (hour . 15) (minute . 15)) (maxTemp . [2.9 0]) (minTempTime (hour . 20) (minute . 33)) (minTemp . [0.1 0]) (gustTime (hour . 20) (minute . 58)) (gustDirection . [12 0]) (gust . [2.7 0])) 31 | (\20220226062000 (prefNumber . 44) (observationNumber . 116) (temp . [0.3 0]) (sun10m . [0 0]) (sun1h . [0.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [12 0]) (wind . [1.0 0]) (maxTempTime (hour . 15) (minute . 15)) (maxTemp . [2.9 0]) (minTempTime (hour . 21) (minute . 16)) (minTemp . [0.0 0]) (gustTime (hour . 20) (minute . 58)) (gustDirection . [12 0]) (gust . [2.7 0])) 32 | (\20220226063000 (prefNumber . 44) (observationNumber . 116) (temp . [0.1 0]) (sun10m . [0 0]) (sun1h . [0.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [12 0]) (wind . [1.3 0]) (maxTempTime (hour . 15) (minute . 15)) (maxTemp . [2.9 0]) (minTempTime (hour . 21) (minute . 16)) (minTemp . [0.0 0]) (gustTime (hour . 20) (minute . 58)) (gustDirection . [12 0]) (gust . [2.7 0])) 33 | (\20220226064000 (prefNumber . 44) (observationNumber . 116) (temp . [0.4 0]) (sun10m . [0 0]) (sun1h . [0.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [12 0]) (wind . [1.1 0]) (maxTempTime (hour . 15) (minute . 15)) (maxTemp . [2.9 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 20) (minute . 58)) (gustDirection . [12 0]) (gust . [2.7 0])) 34 | (\20220226065000 (prefNumber . 44) (observationNumber . 116) (temp . [0.8 0]) (sun10m . [7 0]) (sun1h . [0.1 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [11 0]) (wind . [1.2 0]) (maxTempTime (hour . 15) (minute . 15)) (maxTemp . [2.9 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 20) (minute . 58)) (gustDirection . [12 0]) (gust . [2.7 0])) 35 | (\20220226070000 (prefNumber . 44) (observationNumber . 116) (temp . [1.2 0]) (snow1h . [0 :null]) (snow6h . [0 :null]) (snow12h . [0 :null]) (snow24h . [0 :null]) (sun10m . [10 0]) (sun1h . [0.3 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [12 0]) (wind . [1.4 0]) (maxTempTime (hour . 15) (minute . 15)) (maxTemp . [2.9 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 20) (minute . 58)) (gustDirection . [12 0]) (gust . [2.7 0])) 36 | (\20220226071000 (prefNumber . 44) (observationNumber . 116) (temp . [1.4 0]) (sun10m . [10 0]) (sun1h . [0.5 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [12 0]) (wind . [1.7 0]) (maxTempTime (hour . 15) (minute . 15)) (maxTemp . [2.9 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 20) (minute . 58)) (gustDirection . [12 0]) (gust . [2.7 0])) 37 | (\20220226072000 (prefNumber . 44) (observationNumber . 116) (temp . [2.0 0]) (sun10m . [10 0]) (sun1h . [0.6 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [12 0]) (wind . [1.4 0]) (maxTempTime (hour . 15) (minute . 15)) (maxTemp . [2.9 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 11)) (gustDirection . [11 0]) (gust . [2.8 0])) 38 | (\20220226073000 (prefNumber . 44) (observationNumber . 116) (temp . [2.5 0]) (sun10m . [10 0]) (sun1h . [0.8 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [12 0]) (wind . [1.7 0]) (maxTempTime (hour . 15) (minute . 15)) (maxTemp . [2.9 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 22)) (gustDirection . [13 0]) (gust . [3.2 0])) 39 | (\20220226074000 (prefNumber . 44) (observationNumber . 116) (temp . [3.0 0]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [12 0]) (wind . [1.6 0]) (maxTempTime (hour . 22) (minute . 40)) (maxTemp . [3.0 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 40 | (\20220226075000 (prefNumber . 44) (observationNumber . 116) (temp . [3.5 0]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [12 0]) (wind . [1.5 0]) (maxTempTime (hour . 22) (minute . 50)) (maxTemp . [3.5 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 41 | (\20220226080000 (prefNumber . 44) (observationNumber . 116) (temp . [4.2 0]) (snow1h . [0 :null]) (snow6h . [0 :null]) (snow12h . [0 :null]) (snow24h . [0 :null]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [12 0]) (wind . [1.6 0]) (maxTempTime (hour . 23) (minute . 0)) (maxTemp . [4.2 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 42 | (\20220226081000 (prefNumber . 44) (observationNumber . 116) (temp . [4.8 0]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [12 0]) (wind . [1.4 0]) (maxTempTime (hour . 23) (minute . 10)) (maxTemp . [4.8 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 43 | (\20220226082000 (prefNumber . 44) (observationNumber . 116) (temp . [5.5 0]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [13 0]) (wind . [1.3 0]) (maxTempTime (hour . 23) (minute . 20)) (maxTemp . [5.5 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 44 | (\20220226083000 (prefNumber . 44) (observationNumber . 116) (temp . [5.6 0]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [11 0]) (wind . [1.8 0]) (maxTempTime (hour . 23) (minute . 30)) (maxTemp . [5.6 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 45 | (\20220226084000 (prefNumber . 44) (observationNumber . 116) (temp . [5.9 0]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [11 0]) (wind . [1.7 0]) (maxTempTime (hour . 23) (minute . 39)) (maxTemp . [6.1 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 46 | (\20220226085000 (prefNumber . 44) (observationNumber . 116) (temp . [6.5 0]) (sun10m . [10 0]) (sun1h . [1.0 0]) (precipitation10m . [0.0 0]) (precipitation1h . [0.0 0]) (precipitation3h . [0.0 0]) (precipitation24h . [0.0 0]) (windDirection . [11 0]) (wind . [1.5 0]) (maxTempTime (hour . 23) (minute . 48)) (maxTemp . [6.9 0]) (minTempTime (hour . 21) (minute . 32)) (minTemp . [0.0 0]) (gustTime (hour . 22) (minute . 38)) (gustDirection . [12 0]) (gust . [3.7 0])) 47 | ) 48 | -------------------------------------------------------------------------------- /example-data/jma-forecast-area.json.el: -------------------------------------------------------------------------------- 1 | ;;(jma-json-get "https://www.jma.go.jp/bosai/forecast/const/forecast_area.json") 2 | 3 | ( 4 | (\011000 . [((class10 . "011000") (amedas . ["11016"]) (class20 . "0121400"))]) 5 | (\012000 . [((class10 . "012010") (amedas . ["12442"]) (class20 . "0120400")) ((class10 . "012020") (amedas . ["13277"]) (class20 . "0121200"))]) 6 | (\013000 . [((class10 . "013010") (amedas . ["17341"]) (class20 . "0121100")) ((class10 . "013020") (amedas . ["17521"]) (class20 . "0120801")) ((class10 . "013030") (amedas . ["17112"]) (class20 . "0121900"))]) 7 | (\014030 . [((class10 . "014030") (amedas . ["20432"]) (class20 . "0120700"))]) 8 | (\014100 . [((class10 . "014010") (amedas . ["18273"]) (class20 . "0122300")) ((class10 . "014020") (amedas . ["19432"]) (class20 . "0120601"))]) 9 | (\015000 . [((class10 . "015010") (amedas . ["21323"]) (class20 . "0120500")) ((class10 . "015020") (amedas . ["22327"]) (class20 . "0160700"))]) 10 | (\016000 . [((class10 . "016010") (amedas . ["14163"]) (class20 . "0110000")) ((class10 . "016020") (amedas . ["15356"]) (class20 . "0121000")) ((class10 . "016030") (amedas . ["16217"]) (class20 . "0140000"))]) 11 | (\017000 . [((class10 . "017010") (amedas . ["23232"]) (class20 . "0120200")) ((class10 . "017020") (amedas . ["24217"]) (class20 . "0136100"))]) 12 | (\020000 . [((class10 . "020010") (amedas . ["31312" "31436" "31461"]) (class20 . "0220100")) ((class10 . "020020") (amedas . ["31111"]) (class20 . "0220800")) ((class10 . "020030") (amedas . ["31602"]) (class20 . "0220300"))]) 13 | (\030000 . [((class10 . "030010") (amedas . ["33431" "33071" "33911"]) (class20 . "0320100")) ((class10 . "030020") (amedas . ["33472"]) (class20 . "0320200")) ((class10 . "030030") (amedas . ["33877"]) (class20 . "0320300"))]) 14 | (\040000 . [((class10 . "040010") (amedas . ["34392" "34292" "34216"]) (class20 . "0410001")) ((class10 . "040020") (amedas . ["34461"]) (class20 . "0420600"))]) 15 | (\050000 . [((class10 . "050010") (amedas . ["32402"]) (class20 . "0520100")) ((class10 . "050020") (amedas . ["32126" "32596"]) (class20 . "0521300"))]) 16 | (\060000 . [((class10 . "060010") (amedas . ["35426"]) (class20 . "0620100")) ((class10 . "060020") (amedas . ["35552"]) (class20 . "0620200")) ((class10 . "060030") (amedas . ["35052"]) (class20 . "0620400")) ((class10 . "060040") (amedas . ["35162"]) (class20 . "0620500"))]) 17 | (\070000 . [((class10 . "070010") (amedas . ["36127" "36667" "36476"]) (class20 . "0720100")) ((class10 . "070020") (amedas . ["36846" "36151"]) (class20 . "0720400")) ((class10 . "070030") (amedas . ["36361" "36641"]) (class20 . "0720200"))]) 18 | (\080000 . [((class10 . "080010") (amedas . ["40201"]) (class20 . "0820100")) ((class10 . "080020") (amedas . ["40341"]) (class20 . "0820300"))]) 19 | (\090000 . [((class10 . "090010") (amedas . ["41277"]) (class20 . "0920100")) ((class10 . "090020") (amedas . ["41141"]) (class20 . "0921000"))]) 20 | (\100000 . [((class10 . "100010") (amedas . ["42251"]) (class20 . "1020100")) ((class10 . "100020") (amedas . ["42091"]) (class20 . "1044900"))]) 21 | (\110000 . [((class10 . "110010") (amedas . ["43241"]) (class20 . "1110000")) ((class10 . "110020") (amedas . ["43056"]) (class20 . "1120200")) ((class10 . "110030") (amedas . ["43156"]) (class20 . "1120700"))]) 22 | (\120000 . [((class10 . "120010") (amedas . ["45212"]) (class20 . "1210000")) ((class10 . "120020") (amedas . ["45147"]) (class20 . "1220200")) ((class10 . "120030") (amedas . ["45401"]) (class20 . "1220500"))]) 23 | (\130000 . [((class10 . "130010") (amedas . ["44132"]) (class20 . "1310100")) ((class10 . "130020") (amedas . ["44172"]) (class20 . "1336100")) ((class10 . "130030") (amedas . ["44263"]) (class20 . "1340100")) ((class10 . "130040") (amedas . ["44301"]) (class20 . "1342100"))]) 24 | (\140000 . [((class10 . "140010") (amedas . ["46106"]) (class20 . "1410000")) ((class10 . "140020") (amedas . ["46166"]) (class20 . "1420600"))]) 25 | (\150000 . [((class10 . "150010") (amedas . ["54232" "54421"]) (class20 . "1510000")) ((class10 . "150020") (amedas . ["54501" "54841"]) (class20 . "1520200")) ((class10 . "150030") (amedas . ["54651"]) (class20 . "1522200")) ((class10 . "150040") (amedas . ["54157"]) (class20 . "1522400"))]) 26 | (\160000 . [((class10 . "160010") (amedas . ["55102"]) (class20 . "1620100")) ((class10 . "160020") (amedas . ["55091"]) (class20 . "1620200"))]) 27 | (\170000 . [((class10 . "170010") (amedas . ["56227"]) (class20 . "1720100")) ((class10 . "170020") (amedas . ["56052"]) (class20 . "1720400"))]) 28 | (\180000 . [((class10 . "180010") (amedas . ["57066" "57121"]) (class20 . "1820100")) ((class10 . "180020") (amedas . ["57248"]) (class20 . "1820200"))]) 29 | (\190000 . [((class10 . "190010") (amedas . ["49142"]) (class20 . "1920100")) ((class10 . "190020") (amedas . ["49251"]) (class20 . "1943000"))]) 30 | (\200000 . [((class10 . "200010") (amedas . ["48156"]) (class20 . "2020100")) ((class10 . "200020") (amedas . ["48361" "48491" "48331"]) (class20 . "2020201")) ((class10 . "200030") (amedas . ["48767"]) (class20 . "2020500"))]) 31 | (\210000 . [((class10 . "210010") (amedas . ["52586"]) (class20 . "2120100")) ((class10 . "210020") (amedas . ["52146"]) (class20 . "2120300"))]) 32 | (\220000 . [((class10 . "220010") (amedas . ["50331"]) (class20 . "2210001")) ((class10 . "220020") (amedas . ["50281" "50561"]) (class20 . "2220500")) ((class10 . "220030") (amedas . ["50206"]) (class20 . "2220600")) ((class10 . "220040") (amedas . ["50456" "50551"]) (class20 . "2213001"))]) 33 | (\230000 . [((class10 . "230010") (amedas . ["51106"]) (class20 . "2310000")) ((class10 . "230020") (amedas . ["51331"]) (class20 . "2320100"))]) 34 | (\240000 . [((class10 . "240010") (amedas . ["53133" "53061" "53112"]) (class20 . "2420100")) ((class10 . "240020") (amedas . ["53378"]) (class20 . "2420900"))]) 35 | (\250000 . [((class10 . "250010") (amedas . ["60216"]) (class20 . "2520101")) ((class10 . "250020") (amedas . ["60131"]) (class20 . "2520200"))]) 36 | (\260000 . [((class10 . "260010") (amedas . ["61286"]) (class20 . "2610000")) ((class10 . "260020") (amedas . ["61111"]) (class20 . "2620200"))]) 37 | (\270000 . [((class10 . "270000") (amedas . ["62078"]) (class20 . "2710000"))]) 38 | (\280000 . [((class10 . "280010") (amedas . ["63518" "63576" "63571" "63383"]) (class20 . "2810000")) ((class10 . "280020") (amedas . ["63051"]) (class20 . "2820900"))]) 39 | (\290000 . [((class10 . "290010") (amedas . ["64036"]) (class20 . "2920100")) ((class10 . "290020") (amedas . ["64227"]) (class20 . "2944900"))]) 40 | (\300000 . [((class10 . "300010") (amedas . ["65042"]) (class20 . "3020100")) ((class10 . "300020") (amedas . ["65356"]) (class20 . "3042800"))]) 41 | (\310000 . [((class10 . "310010") (amedas . ["69122"]) (class20 . "3120101")) ((class10 . "310020") (amedas . ["69076"]) (class20 . "3120200"))]) 42 | (\320000 . [((class10 . "320010") (amedas . ["68132"]) (class20 . "3220100")) ((class10 . "320020") (amedas . ["68376"]) (class20 . "3220200")) ((class10 . "320030") (amedas . ["68022"]) (class20 . "3252800"))]) 43 | (\330000 . [((class10 . "330010") (amedas . ["66408"]) (class20 . "3310000")) ((class10 . "330020") (amedas . ["66186"]) (class20 . "3320300"))]) 44 | (\340000 . [((class10 . "340010") (amedas . ["67437" "67511" "67401"]) (class20 . "3410000")) ((class10 . "340020") (amedas . ["67116"]) (class20 . "3421000"))]) 45 | (\350000 . [((class10 . "350010") (amedas . ["81428"]) (class20 . "3520100")) ((class10 . "350020") (amedas . ["81286"]) (class20 . "3520300")) ((class10 . "350030") (amedas . ["81481"]) (class20 . "3521200")) ((class10 . "350040") (amedas . ["81071"]) (class20 . "3520400"))]) 46 | (\360000 . [((class10 . "360010") (amedas . ["71106" "71066"]) (class20 . "3620100")) ((class10 . "360020") (amedas . ["71266"]) (class20 . "3638700"))]) 47 | (\370000 . [((class10 . "370000") (amedas . ["72086"]) (class20 . "3720100"))]) 48 | (\380000 . [((class10 . "380010") (amedas . ["73166"]) (class20 . "3820100")) ((class10 . "380020") (amedas . ["73136" "73141"]) (class20 . "3820500")) ((class10 . "380030") (amedas . ["73442"]) (class20 . "3820300"))]) 49 | (\390000 . [((class10 . "390010") (amedas . ["74181"]) (class20 . "3920100")) ((class10 . "390020") (amedas . ["74372"]) (class20 . "3920200")) ((class10 . "390030") (amedas . ["74516"]) (class20 . "3920900"))]) 50 | (\400000 . [((class10 . "400010") (amedas . ["82182"]) (class20 . "4013000")) ((class10 . "400020") (amedas . ["82056"]) (class20 . "4010000")) ((class10 . "400030") (amedas . ["82136"]) (class20 . "4020500")) ((class10 . "400040") (amedas . ["82306"]) (class20 . "4020300"))]) 51 | (\410000 . [((class10 . "410010") (amedas . ["85142"]) (class20 . "4120100")) ((class10 . "410020") (amedas . ["85116"]) (class20 . "4120500"))]) 52 | (\420000 . [((class10 . "420010") (amedas . ["84496"]) (class20 . "4220100")) ((class10 . "420020") (amedas . ["84266"]) (class20 . "4220201")) ((class10 . "420030") (amedas . ["84072"]) (class20 . "4220901")) ((class10 . "420040") (amedas . ["84536"]) (class20 . "4221100"))]) 53 | (\430000 . [((class10 . "430010") (amedas . ["86141"]) (class20 . "4310000")) ((class10 . "430020") (amedas . ["86111"]) (class20 . "4321400")) ((class10 . "430030") (amedas . ["86491"]) (class20 . "4321500")) ((class10 . "430040") (amedas . ["86467"]) (class20 . "4320300"))]) 54 | (\440000 . [((class10 . "440010") (amedas . ["83216"]) (class20 . "4420100")) ((class10 . "440020") (amedas . ["83051"]) (class20 . "4420300")) ((class10 . "440030") (amedas . ["83137"]) (class20 . "4420400")) ((class10 . "440040") (amedas . ["83401"]) (class20 . "4420500"))]) 55 | (\450000 . [((class10 . "450010") (amedas . ["87376" "87492"]) (class20 . "4520100")) ((class10 . "450020") (amedas . ["87141"]) (class20 . "4520300")) ((class10 . "450030") (amedas . ["87426"]) (class20 . "4520200")) ((class10 . "450040") (amedas . ["87041"]) (class20 . "4544100"))]) 56 | (\460040 . [((class10 . "460040") (amedas . ["88836" "88971"]) (class20 . "4622200"))]) 57 | (\460100 . [((class10 . "460010") (amedas . ["88317" "88061" "88466"]) (class20 . "4620100")) ((class10 . "460020") (amedas . ["88442"]) (class20 . "4620300")) ((class10 . "460030") (amedas . ["88612"]) (class20 . "4621300"))]) 58 | (\471000 . [((class10 . "471010") (amedas . ["91197"]) (class20 . "4720100")) ((class10 . "471020") (amedas . ["91107"]) (class20 . "4720900")) ((class10 . "471030") (amedas . ["91146"]) (class20 . "4736100"))]) 59 | (\472000 . [((class10 . "472000") (amedas . ["92011"]) (class20 . "4735700"))]) 60 | (\473000 . [((class10 . "473000") (amedas . ["93041"]) (class20 . "4721400"))]) 61 | (\474000 . [((class10 . "474010") (amedas . ["94081"]) (class20 . "4720700")) ((class10 . "474020") (amedas . ["94017"]) (class20 . "4738200"))])) 62 | -------------------------------------------------------------------------------- /docs/how-to-get-jma-area-info.org: -------------------------------------------------------------------------------- 1 | #+TITLE: 気象庁データにおける場所に関する情報の扱い方 2 | #+DATE: [2022-02-25 Fri] 3 | #+AUTHOR: AKIYAMA Kouhei 4 | 5 | * 情報源 6 | ** 発表区域情報 7 | :PROPERTIES: 8 | :CUSTOM_ID: common-area-json 9 | :END: 10 | 11 | URL: https://www.jma.go.jp/bosai/common/const/area.json 12 | 13 | [[https://www.jma.go.jp/jma/kishou/know/saibun/][気象庁 | 気象警報・注意報や天気予報の発表区域]]に対応する情報。日本全国を5階層に分割している。用語の定義は左記リンク先を参照のこと。 14 | 15 | #+begin_src elisp 16 | ;; (jma-json-get "https://www.jma.go.jp/bosai/common/const/area.json")の結果: 17 | ( 18 | ;; 地方予報区(11区) 19 | (centers 20 | (\010100 (name . "北海道地方") (enName . "Hokkaido") (officeName . "札幌管区気象台") (children . ["011000" "012000" "013000" "014030" "014100" "015000" "016000" "017000"])) 21 | (\010200 (name . "東北地方") (enName . "Tohoku") (officeName . "仙台管区気象台") (children . ["020000" "030000" "040000" "050000" "060000" "070000"])) 22 | ...) 23 | 24 | ;; 府県予報区(58区) 25 | (offices 26 | (\011000 (name . "宗谷地方") (enName . "Soya") (officeName . "稚内地方気象台") (parent . "010100") (children . ["011000"])) 27 | (\012000 (name . "上川・留萌地方") (enName . "Kamikawa Rumoi") (officeName . "旭川地方気象台") (parent . "010100") (children . ["012010" "012020"])) 28 | ...) 29 | 30 | ;; 一次細分区域(142区) 31 | (class10s 32 | (\011000 (name . "宗谷地方") (enName . "Soya Region") (parent . "011000") (children . ["011011" "011012" "011013"])) 33 | (\012010 (name . "上川地方") (enName . "Kamikawa Region") (parent . "012000") (children . ["012011" "012012" "012013"])) 34 | ...) 35 | 36 | ;; 市町村等をまとめた地域(375区) 37 | (class15s 38 | (\011011 (name . "宗谷北部") (enName . "Northern Soya") (parent . "011000") (children . ["0121400" "0151100" "0151600" "0152000"])) 39 | (\011012 (name . "宗谷南部") (enName . "Southern Soya") (parent . "011000") (children . ["0151200" "0151300" "0151400"])) 40 | ...) 41 | 42 | ;; 二次細分区域(1776区) 43 | (class20s 44 | (\0110000 (name . "札幌市") (enName . "Sapporo City") (kana . "さっぽろし") (parent . "016012")) 45 | (\0120200 (name . "函館市") (enName . "Hakodate City") (kana . "はこだてし") (parent . "017012")) 46 | ...) 47 | ) 48 | #+end_src 49 | 50 | エリアコードは階層内でのみ一意であることに注意。例えば011000は「宗谷地方」だが、それが府県予報区と次細分区域のどちらを指しているかはコードだけでは判別できない。 51 | 52 | 異なる階層でも同じ名称(同じ範囲を表すもの)には同じコードを付ける傾向がある。全てそうなっているかは未確認。 53 | 54 | 二次細分区域の説明には「[[https://www.jma.go.jp/jma/kishou/know/saibun/][市町村(東京特別区は区)を原則としますが、一部市町村を分割して設定している場合があります。]]」とあるので、概ね市区町村名からそれが属する全階層の区域を求めることができる。ただし「○○市北部」のような名称もあるので注意。 55 | 56 | ** 府県予報区と府県天気予報の予報区との対応関係 57 | :PROPERTIES: 58 | :CUSTOM_ID: forecast-area-json 59 | :END: 60 | 61 | URL: https://www.jma.go.jp/bosai/forecast/const/forecast_area.json 62 | 63 | 府県予報区内の天気予報を行う予報区(一次細分区域)とアメダス観測所の一覧。 64 | 65 | #+begin_src elisp 66 | ;;(jma-json-get "https://www.jma.go.jp/bosai/forecast/const/forecast_area.json")の結果(58区): 67 | ( 68 | ;; 府県予報区 class10=一次細分区域 amedas=アメダス観測所 class20=二次細分区域(何の?) 69 | (\011000 . [((class10 . "011000") (amedas . ["11016"]) (class20 . "0121400"))]) 70 | (\012000 . [((class10 . "012010") (amedas . ["12442"]) (class20 . "0120400")) 71 | ((class10 . "012020") (amedas . ["13277"]) (class20 . "0121200"))]) 72 | (\013000 . [((class10 . "013010") (amedas . ["17341"]) (class20 . "0121100")) 73 | ((class10 . "013020") (amedas . ["17521"]) (class20 . "0120801")) 74 | ((class10 . "013030") (amedas . ["17112"]) (class20 . "0121900"))]) 75 | ...以下amedasが複数あるものを全て抜粋... 76 | (\020000 . [((class10 . "020010") (amedas . ["31312" "31436" "31461"]) (class20 . "0220100")) 77 | ... 78 | (\030000 . [((class10 . "030010") (amedas . ["33431" "33071" "33911"]) (class20 . "0320100")) 79 | ... 80 | (\040000 . [((class10 . "040010") (amedas . ["34392" "34292" "34216"]) (class20 . "0410001")) 81 | ... 82 | ((class10 . "050020") (amedas . ["32126" "32596"]) (class20 . "0521300"))]) 83 | ... 84 | (\070000 . [((class10 . "070010") (amedas . ["36127" "36667" "36476"]) (class20 . "0720100")) 85 | ((class10 . "070020") (amedas . ["36846" "36151"]) (class20 . "0720400")) 86 | ((class10 . "070030") (amedas . ["36361" "36641"]) (class20 . "0720200"))]) 87 | ... 88 | (\150000 . [((class10 . "150010") (amedas . ["54232" "54421"]) (class20 . "1510000")) 89 | ((class10 . "150020") (amedas . ["54501" "54841"]) (class20 . "1520200")) 90 | ... 91 | (\180000 . [((class10 . "180010") (amedas . ["57066" "57121"]) (class20 . "1820100")) 92 | ... 93 | ((class10 . "200020") (amedas . ["48361" "48491" "48331"]) (class20 . "2020201")) 94 | ... 95 | ((class10 . "220020") (amedas . ["50281" "50561"]) (class20 . "2220500")) 96 | ... 97 | ((class10 . "220040") (amedas . ["50456" "50551"]) (class20 . "2213001"))]) 98 | ... 99 | (\240000 . [((class10 . "240010") (amedas . ["53133" "53061" "53112"]) (class20 . "2420100")) 100 | ... 101 | (\280000 . [((class10 . "280010") (amedas . ["63518" "63576" "63571" "63383"]) (class20 . "2810000")) 102 | ... 103 | (\340000 . [((class10 . "340010") (amedas . ["67437" "67511" "67401"]) (class20 . "3410000")) 104 | ... 105 | (\360000 . [((class10 . "360010") (amedas . ["71106" "71066"]) (class20 . "3620100")) 106 | ... 107 | ((class10 . "380020") (amedas . ["73136" "73141"]) (class20 . "3820500")) 108 | ... 109 | (\450000 . [((class10 . "450010") (amedas . ["87376" "87492"]) (class20 . "4520100")) 110 | ... 111 | (\460040 . [((class10 . "460040") (amedas . ["88836" "88971"]) (class20 . "4622200"))]) 112 | (\460100 . [((class10 . "460010") (amedas . ["88317" "88061" "88466"]) (class20 . "4620100")) 113 | ...) 114 | #+end_src 115 | 116 | 一次細分区域内に気温の予報を行うアメダス観測所が複数存在する場合がある。 117 | 118 | アメダス観測所が複数ある場合、より下位の区域(例えば二次細分区域)との対応関係の情報は無い。気象庁のWebサイトでも、市を選択しても気温の予報は一つに絞り込まれない。例えば津軽(class10=020010)には三つのアメダス観測所(青森31312, 深浦31436, 弘前31461)が存在する。中泊町(class20=0238700)は津軽の一部だが、[[https://www.jma.go.jp/bosai/forecast/#area_type=class20s&area_code=0238700][Webサイト]]を開いても三つの内のどのアメダス観測所を参照すべきかは明確には示されない。JSONにも対応情報は無い。中泊町は北五津軽(class15=020012)に属するが、三つのアメダス観測所はいずれも北五津軽には無い。強いて言えば緯度経度情報から最も近いものを選ぶくらいしかない。近所にある複数のアメダス観測所の予報を複合的に見て判断しろという事なのかもしれない。 119 | 120 | ** 府県予報区と府県週間天気予報の予報区との対応関係 121 | :PROPERTIES: 122 | :CUSTOM_ID: forecast-week-area-json 123 | :END: 124 | 125 | URL: https://www.jma.go.jp/bosai/forecast/const/week_area.json 126 | 127 | 府県予報区内の週間予報区域(府県週間天気予報のために細分化された区域)の一覧。 128 | 129 | #+begin_src elisp 130 | ;;(jma-json-get "https://www.jma.go.jp/bosai/forecast/const/week_area.json")の結果(58区): 131 | ( 132 | ;; 府県予報区 一次細分区域 週間予報区域 アメダス観測所 133 | ;; 千葉県 北東部 千葉県 銚子 134 | (\120000 . [((srf . "120020") (week . "120000") (amedas . "45147"))]) 135 | ;; 静岡県 中部 静岡県 静岡 136 | (\220000 . [((srf . "220010") (week . "220000") (amedas . "50331"))]) 137 | ;; 岐阜県 美濃地方 岐阜県 岐阜 138 | (\210000 . [((srf . "210010") (week . "210000") (amedas . "52586")) 139 | ;; 美濃地方 岐阜県美濃地方 岐阜 (↑季節細分) 140 | ((srf . "210010") (week . "210010") (amedas . "52586")) 141 | ;; 飛騨地方 岐阜県飛騨地方 高山 (↑季節細分) 142 | ((srf . "210020") (week . "210020") (amedas . "52146"))]) 143 | ... 144 | ;; 長野県 北部 長野県 長野 145 | (\200000 . [((srf . "200010") (week . "200000") (amedas . "48156")) 146 | ;; 北部 長野県北部 長野 (↑季節細分) 147 | ((srf . "200010") (week . "200010") (amedas . "48156")) 148 | ;; 中部 長野県中部・南部 松本 (↑季節細分) 149 | ((srf . "200020") (week . "200100") (amedas . "48361"))]) 150 | ... 151 | ;; 東京都 東京地方 東京地方 東京 (常時細分) 152 | (\130000 . [((srf . "130010") (week . "130010") (amedas . "44132")) 153 | ;; 伊豆諸島南部 伊豆諸島 八丈島 (常時細分) 154 | ((srf . "130030") (week . "130100") (amedas . "44263")) 155 | ;; 伊豆諸島北部 伊豆諸島北部 大島 (↑季節細分) 156 | ((srf . "130020") (week . "130020") (amedas . "44172")) 157 | ;; 伊豆諸島南部 伊豆諸島南部 八丈島 (↑季節細分) 158 | ((srf . "130030") (week . "130030") (amedas . "44263")) 159 | ;; 小笠原諸島 小笠原諸島 父島 (常時細分) 160 | ((srf . "130040") (week . "130040") (amedas . "44301"))]) 161 | ...) 162 | #+end_src 163 | 164 | srfの意味は不明。一次細分区域のコード。地域を代表する一次細分区域? アメダス観測所がある一次細分区域? 165 | 166 | [[https://www.jma.go.jp/jma/kishou/know/kurashi/shukan.html][気象庁|週間天気予報の解説]]に書かれている通り、地理的な理由で常時細分化されている地域や季節的な理由で一時的に細分化されている地域がある。従って配列の中の全ての地域が予報で常に使われるわけではない。 167 | 168 | ** 一次細分区域と府県週間天気予報の予報区との対応関係 169 | :PROPERTIES: 170 | :CUSTOM_ID: forecast-week-area05.json 171 | :END: 172 | 173 | URL: https://www.jma.go.jp/bosai/forecast/const/week_area05.json 174 | 175 | 一次細分区域がどの週間予報区域(府県週間天気予報のために細分化された区域)に対応しうるかの対応表。 176 | 177 | #+begin_src elisp 178 | ;;(jma-json-get "https://www.jma.go.jp/bosai/forecast/const/week_area05.json")の結果(142区): 179 | ( 180 | ;; 一次細分区域 [週間予報区域...] 181 | ;; 北西部 千葉県 182 | (\120010 . ["120000"]) 183 | ;; 北東部 千葉県 184 | (\120020 . ["120000"]) 185 | ;; 南部 千葉県 186 | (\120030 . ["120000"]) 187 | ;; 中部 静岡県 188 | (\220010 . ["220000"]) 189 | ;; 伊豆 静岡県 190 | (\220020 . ["220000"]) 191 | ;; 東部 静岡県 192 | (\220030 . ["220000"]) 193 | ;; 西部 静岡県 194 | (\220040 . ["220000"]) 195 | ;; 美濃地方 岐阜県 岐阜県美濃地方 196 | (\210010 . ["210000" "210010"]) 197 | ;; 飛騨地方 岐阜県 岐阜県飛騨地方 198 | (\210020 . ["210000" "210020"]) 199 | ... 200 | ;; 北部 長野県 長野県北部 201 | (\200010 . ["200000" "200010"]) 202 | ;; 中部 長野県 長野県中部・南部 203 | (\200020 . ["200000" "200100"]) 204 | ;; 南部 長野県 長野県中部・南部 205 | (\200030 . ["200000" "200100"]) 206 | ... 207 | ;; 東京地方 東京地方 208 | (\130010 . ["130010"]) 209 | ;; 伊豆諸島北部 伊豆諸島 伊豆諸島北部 210 | (\130020 . ["130100" "130020"]) 211 | ;; 伊豆諸島南部 伊豆諸島 伊豆諸島南部 212 | (\130030 . ["130100" "130030"]) 213 | ;; 小笠原諸島 小笠原諸島 214 | (\130040 . ["130040"]) 215 | ...) 216 | #+end_src 217 | 218 | 一次細分区域が属する週間予報区域は[[https://www.jma.go.jp/jma/kishou/know/kurashi/shukan_saibun.html][気象庁|週間天気予報の季節細分についての解説]]に書かれている通り季節によって変わりうる。配列は可能性のあるものを全て列挙している。 219 | 220 | ** 二次細分区域の緯度経度範囲 221 | :PROPERTIES: 222 | :CUSTOM_ID: common-class20relm-json 223 | :END: 224 | 225 | URL: https://www.jma.go.jp/bosai/common/const/class20relm.json 226 | 227 | おそらく二次細分区域を内包する緯度経度範囲。 228 | 229 | #+begin_src elisp 230 | ;;(jma-json-get "https://www.jma.go.jp/bosai/common/const/class20relm.json")の結果(1772区) 231 | ( 232 | ;; ne=北東角 sw=南西角 parent=市町村等をまとめた地域(class15) 233 | (\0110000 (name . "札幌市") (ne . [43.1894 141.5054]) (sw . [42.7807 140.9905]) (parent . "016012")) 234 | (\0120200 (name . "函館市") (ne . [42.0094 141.1874]) (sw . [41.71 140.6924]) (parent . "017012")) 235 | ...) 236 | #+end_src 237 | 238 | ** 二次細分区域とアメダス観測所の対応リスト 239 | :PROPERTIES: 240 | :CUSTOM_ID: amedas-class20-list-json 241 | :END: 242 | 243 | URL: https://www.jma.go.jp/bosai/amedas/const/amedas_class20_list.json 244 | 245 | 二次細分区域(概ね市区町村)とアメダス観測所の対応リスト。 246 | 247 | #+begin_src elisp 248 | ;;(jma-json-get "https://www.jma.go.jp/bosai/amedas/const/amedas_class20_list.json")の結果(1776区): 249 | ( 250 | ;; 札幌市 山口 手稲山 札幌 小金湯 石狩 251 | (\0110000 . ["14116" "14157" "14163" "14191" "14121"]) 252 | ;; 函館市 川汲 函館 高松 戸井泊 北斗 253 | (\0120200 . ["23206" "23232" "23281" "23291" "23226"]) 254 | ;; 小樽市 小樽 山口 手稲山 赤井川 余市 255 | (\0120300 . ["16091" "14116" "14157" "16126" "16076"]) 256 | ;; 旭川市 江丹別 旭川 瑞穂 東神楽 東川 257 | (\0120400 . ["12386" "12442" "12457" "12501" "12451"]) 258 | ... 259 | ;; 立川市 所沢 府中 八王子 青梅 飯能 260 | (\1320200 . ["43266" "44116" "44112" "44056" "43231"]) 261 | ;; 武蔵野市 練馬 府中 世田谷 所沢 東京 262 | (\1320300 . ["44071" "44116" "44126" "43266" "44132"]) 263 | ;; 三鷹市 練馬 世田谷 府中 東京 日吉 264 | (\1320400 . ["44071" "44126" "44116" "44132" "46061"]) 265 | ;; 青梅市 青梅 飯能 小沢 所沢 八王子 266 | (\1320500 . ["44056" "43231" "44051" "43266" "44112"]) 267 | ;; 府中市 府中 練馬 世田谷 所沢 相模原中央 268 | (\1320600 . ["44116" "44071" "44126" "43266" "46046"]) 269 | ... 270 | ;; 御蔵島村 三宅坪田 三宅島 神津島 271 | (\1338200 . ["44228" "44226" "44216"]) 272 | ;; 八丈町 八重見ヶ原 八丈島 273 | (\1340100 . ["44262" "44263"]) 274 | ;; 青ヶ島村 青ヶ島 275 | (\1340200 . ["44281"]) 276 | ... 277 | ;; 高山市 栃尾 清見 高山 丹生川 六厩 船山 宮之前 278 | (\2120300 . ["52111" "52137" "52146" "52152" "52181" "52192" "52196"]) 279 | ...) 280 | #+end_src 281 | 282 | おそらく付近の観測所を並べたもの。 283 | 284 | 天気予報・週間天気予報で使うアメダス観測所が含まれているとは限らない。 285 | 286 | ** アメダス観測所リスト 287 | :PROPERTIES: 288 | :CUSTOM_ID: amedas-amedastable-json 289 | :END: 290 | 291 | URL: https://www.jma.go.jp/bosai/amedas/const/amedastable.json 292 | 293 | アメダス観測所(地域気象観測所)の一覧。アメダスに関する説明は[[https://www.jma.go.jp/jma/kishou/know/amedas/kaisetsu.html#:~:text=%E3%82%A2%E3%83%A1%E3%83%80%E3%82%B9%E3%81%AF1974%E5%B9%B411,%E3%81%95%E3%82%82%E8%A6%B3%E6%B8%AC%E3%81%97%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82][気象庁 | アメダス]]を参照のこと。 294 | 295 | #+begin_src elisp 296 | ;;(jma-json-get "https://www.jma.go.jp/bosai/amedas/const/amedastable.json")の結果(1286箇所): 297 | ( 298 | (\11001 (type . "C") (elems . "11112010") (lat . [45 31.2]) (lon . [141 56.1]) (alt . 26) (kjName . "宗谷岬") (knName . "ソウヤミサキ") (enName . "Cape Soya")) 299 | (\11016 (type . "A") (elems . "11111111") (lat . [45 24.9]) (lon . [141 40.7]) (alt . 3) (kjName . "稚内") (knName . "ワッカナイ") (enName . "Wakkanai")) 300 | (\11046 (type . "C") (elems . "11112010") (lat . [45 18.3]) (lon . [141 2.7]) (alt . 65) (kjName . "礼文") (knName . "レブン") (enName . "Rebun")) 301 | ...) 302 | #+end_src 303 | 304 | 位置情報としては、緯度、経度、高度を含む。 305 | 306 | * 市区町村から天気予報のエリアコードを求める方法 307 | 308 | 天気予報のJSON( =https://www.jma.go.jp/bosai/forecast/data/forecast/.json= )から特定の場所の天気予報を取り出すには次の5つのエリアコードが必要となる。 309 | 310 | - 府県予報区コード(office) 311 | - 一次細分区域コード(class10) 312 | - アメダス観測所コード(amedas) 313 | - 週間予報区域コード(week) 314 | - アメダス観測所コード(週間予報用)(amedas-week) 315 | 316 | 市区町村からこれらのエリアコードを求めるには、次のようにする。(A→Bは上URLの情報を使って、AのコードからBのコードを求めることを意味する) 317 | 318 | 1. https://www.jma.go.jp/bosai/common/const/area.json ([[#common-area-json][発表区域情報]]) 319 | 1. class20→class15 320 | 2. class15→class10(天気予報(詳細)を求めるのに使うコード) 321 | 3. class10→office(ダウンロードするURLを求めるのに使うコード) 322 | 2. https://www.jma.go.jp/bosai/forecast/const/forecast_area.json ([[#forecast-area-json][府県予報区と府県天気予報の予報区との対応関係]]) 323 | 1. class10→amedas(気温を求めるのに使うコード) 324 | 325 | *注意:複数のアメダス観測所が存在する区域がある。一つに絞り込む簡単な方法は見当たらない。また、安易に絞り込んで良いのかも分からない。* 326 | 3. https://www.jma.go.jp/bosai/forecast/const/week_area05.json ([[#forecast-week-area05.json][一次細分区域と府県週間天気予報の予報区との対応関係]]) 327 | 1. class10→week(可能性のあるもの複数) (週間天気予報を求めるのに使うコード) 328 | 4. https://www.jma.go.jp/bosai/forecast/const/week_area.json ([[#forecast-week-area-json][府県予報区と府県週間天気予報の予報区との対応関係]]) 329 | 1. week(可能性のあるもの複数)→amedas(可能性のあるもの複数) (週間天気予報の気温を求めるのに使うコード) 330 | 331 | 週間天気予報のエリア分けは季節によって変わるので、可能性のあるエリアを全て列挙すること。 332 | -------------------------------------------------------------------------------- /jma-weather-code.el: -------------------------------------------------------------------------------- 1 | ;;; jma-weather-code.el --- JMA Weather Code -*- lexical-binding: t; -*- 2 | 3 | ;; Copyright (C) 2022 AKIYAMA Kouhei 4 | 5 | ;; Author: AKIYAMA Kouhei 6 | ;; Keywords: 7 | 8 | ;; This program is free software; you can redistribute it and/or modify 9 | ;; it under the terms of the GNU General Public License as published by 10 | ;; the Free Software Foundation, either version 3 of the License, or 11 | ;; (at your option) any later version. 12 | 13 | ;; This program is distributed in the hope that it will be useful, 14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ;; GNU General Public License for more details. 17 | 18 | ;; You should have received a copy of the GNU General Public License 19 | ;; along with this program. If not, see . 20 | 21 | ;;; Commentary: 22 | 23 | ;; 24 | 25 | ;;; Code: 26 | 27 | ;;;; 設定 28 | 29 | (defcustom jma-weather-code-image-dir 30 | (locate-user-emacs-file ".jma-weather-cache") 31 | "天気アイコン画像の置き場所" 32 | :type 'directory 33 | :group 'jma) 34 | 35 | (defcustom jma-weather-code-image-default-height nil 36 | "デフォルトの画像の高さ 37 | 38 | nilのとき (default-font-height) を使います。" 39 | :type '(choice (const nil) integer) 40 | :group 'jma) 41 | 42 | (defcustom jma-use-images 'auto 43 | "画像を使用するかどうか 44 | 45 | 値は次のいずれかです。 46 | nil = 使用しない 47 | t = 使用する 48 | auto = 自動的に判別する(SVG画像が表示できる環境またはbatchモード時)" 49 | :type '(choice (const auto) (const t) (const nil)) 50 | :group 'jma) 51 | 52 | (defun jma-use-images-p () 53 | "画像を使用するなら非nilを返します。 54 | 55 | どんな時に画像を使用するかは`jma-use-images'でカスタマイズ可能です。" 56 | (pcase jma-use-images 57 | ('nil nil) 58 | ('t t) 59 | ('auto 60 | (or 61 | noninteractive 62 | (and 63 | (display-graphic-p) 64 | (fboundp 'image-type-available-p) 65 | (image-type-available-p 'svg)))) 66 | (_ nil))) 67 | 68 | ;;;; 天気コード 69 | 70 | (defconst jma-weather-code-list 71 | ;; コード 昼画像 夜画像 ? 日本語 英語 72 | '((100 "100.svg" "500.svg" "100" "晴" "CLEAR") 73 | (101 "101.svg" "501.svg" "100" "晴時々曇" "PARTLY CLOUDY") 74 | (102 "102.svg" "502.svg" "300" "晴一時雨" "CLEAR OCCASIONAL SCATTERED SHOWERS") 75 | (103 "102.svg" "502.svg" "300" "晴時々雨" "CLEAR FREQUENT SCATTERED SHOWERS") 76 | (104 "104.svg" "504.svg" "400" "晴一時雪" "CLEAR SNOW FLURRIES") 77 | (105 "104.svg" "504.svg" "400" "晴時々雪" "CLEAR FREQUENT SNOW FLURRIES") 78 | (106 "102.svg" "502.svg" "300" "晴一時雨か雪" "CLEAR OCCASIONAL SCATTERED SHOWERS OR SNOW FLURRIES") 79 | (107 "102.svg" "502.svg" "300" "晴時々雨か雪" "CLEAR FREQUENT SCATTERED SHOWERS OR SNOW FLURRIES") 80 | (108 "102.svg" "502.svg" "300" "晴一時雨か雷雨" "CLEAR OCCASIONAL SCATTERED SHOWERS AND/OR THUNDER") 81 | (110 "110.svg" "510.svg" "100" "晴後時々曇" "CLEAR PARTLY CLOUDY LATER") 82 | (111 "110.svg" "510.svg" "100" "晴後曇" "CLEAR CLOUDY LATER") 83 | (112 "112.svg" "512.svg" "300" "晴後一時雨" "CLEAR OCCASIONAL SCATTERED SHOWERS LATER") 84 | (113 "112.svg" "512.svg" "300" "晴後時々雨" "CLEAR FREQUENT SCATTERED SHOWERS LATER") 85 | (114 "112.svg" "512.svg" "300" "晴後雨" "CLEAR RAIN LATER") 86 | (115 "115.svg" "515.svg" "400" "晴後一時雪" "CLEAR OCCASIONAL SNOW FLURRIES LATER") 87 | (116 "115.svg" "515.svg" "400" "晴後時々雪" "CLEAR FREQUENT SNOW FLURRIES LATER") 88 | (117 "115.svg" "515.svg" "400" "晴後雪" "CLEAR SNOW LATER") 89 | (118 "112.svg" "512.svg" "300" "晴後雨か雪" "CLEAR RAIN OR SNOW LATER") 90 | (119 "112.svg" "512.svg" "300" "晴後雨か雷雨" "CLEAR RAIN AND/OR THUNDER LATER") 91 | (120 "102.svg" "502.svg" "300" "晴朝夕一時雨" "OCCASIONAL SCATTERED SHOWERS IN THE MORNING AND EVENING CLEAR DURING THE DAY") 92 | (121 "102.svg" "502.svg" "300" "晴朝の内一時雨" "OCCASIONAL SCATTERED SHOWERS IN THE MORNING CLEAR DURING THE DAY") 93 | (122 "112.svg" "512.svg" "300" "晴夕方一時雨" "CLEAR OCCASIONAL SCATTERED SHOWERS IN THE EVENING") 94 | (123 "100.svg" "500.svg" "100" "晴山沿い雷雨" "CLEAR IN THE PLAINS RAIN AND THUNDER NEAR MOUTAINOUS AREAS") 95 | (124 "100.svg" "500.svg" "100" "晴山沿い雪" "CLEAR IN THE PLAINS SNOW NEAR MOUTAINOUS AREAS") 96 | (125 "112.svg" "512.svg" "300" "晴午後は雷雨" "CLEAR RAIN AND THUNDER IN THE AFTERNOON") 97 | (126 "112.svg" "512.svg" "300" "晴昼頃から雨" "CLEAR RAIN IN THE AFTERNOON") 98 | (127 "112.svg" "512.svg" "300" "晴夕方から雨" "CLEAR RAIN IN THE EVENING") 99 | (128 "112.svg" "512.svg" "300" "晴夜は雨" "CLEAR RAIN IN THE NIGHT") 100 | (130 "100.svg" "500.svg" "100" "朝の内霧後晴" "FOG IN THE MORNING CLEAR LATER") 101 | (131 "100.svg" "500.svg" "100" "晴明け方霧" "FOG AROUND DAWN CLEAR LATER") 102 | (132 "101.svg" "501.svg" "100" "晴朝夕曇" "CLOUDY IN THE MORNING AND EVENING CLEAR DURING THE DAY") 103 | (140 "102.svg" "502.svg" "300" "晴時々雨で雷を伴う" "CLEAR FREQUENT SCATTERED SHOWERS AND THUNDER") 104 | (160 "104.svg" "504.svg" "400" "晴一時雪か雨" "CLEAR SNOW FLURRIES OR OCCASIONAL SCATTERED SHOWERS") 105 | (170 "104.svg" "504.svg" "400" "晴時々雪か雨" "CLEAR FREQUENT SNOW FLURRIES OR SCATTERED SHOWERS") 106 | (181 "115.svg" "515.svg" "400" "晴後雪か雨" "CLEAR SNOW OR RAIN LATER") 107 | (200 "200.svg" "200.svg" "200" "曇" "CLOUDY") 108 | (201 "201.svg" "601.svg" "200" "曇時々晴" "MOSTLY CLOUDY") 109 | (202 "202.svg" "202.svg" "300" "曇一時雨" "CLOUDY OCCASIONAL SCATTERED SHOWERS") 110 | (203 "202.svg" "202.svg" "300" "曇時々雨" "CLOUDY FREQUENT SCATTERED SHOWERS") 111 | (204 "204.svg" "204.svg" "400" "曇一時雪" "CLOUDY OCCASIONAL SNOW FLURRIES") 112 | (205 "204.svg" "204.svg" "400" "曇時々雪" "CLOUDY FREQUENT SNOW FLURRIES") 113 | (206 "202.svg" "202.svg" "300" "曇一時雨か雪" "CLOUDY OCCASIONAL SCATTERED SHOWERS OR SNOW FLURRIES") 114 | (207 "202.svg" "202.svg" "300" "曇時々雨か雪" "CLOUDY FREQUENT SCCATERED SHOWERS OR SNOW FLURRIES") 115 | (208 "202.svg" "202.svg" "300" "曇一時雨か雷雨" "CLOUDY OCCASIONAL SCATTERED SHOWERS AND/OR THUNDER") 116 | (209 "200.svg" "200.svg" "200" "霧" "FOG") 117 | (210 "210.svg" "610.svg" "200" "曇後時々晴" "CLOUDY PARTLY CLOUDY LATER") 118 | (211 "210.svg" "610.svg" "200" "曇後晴" "CLOUDY CLEAR LATER") 119 | (212 "212.svg" "212.svg" "300" "曇後一時雨" "CLOUDY OCCASIONAL SCATTERED SHOWERS LATER") 120 | (213 "212.svg" "212.svg" "300" "曇後時々雨" "CLOUDY FREQUENT SCATTERED SHOWERS LATER") 121 | (214 "212.svg" "212.svg" "300" "曇後雨" "CLOUDY RAIN LATER") 122 | (215 "215.svg" "215.svg" "400" "曇後一時雪" "CLOUDY SNOW FLURRIES LATER") 123 | (216 "215.svg" "215.svg" "400" "曇後時々雪" "CLOUDY FREQUENT SNOW FLURRIES LATER") 124 | (217 "215.svg" "215.svg" "400" "曇後雪" "CLOUDY SNOW LATER") 125 | (218 "212.svg" "212.svg" "300" "曇後雨か雪" "CLOUDY RAIN OR SNOW LATER") 126 | (219 "212.svg" "212.svg" "300" "曇後雨か雷雨" "CLOUDY RAIN AND/OR THUNDER LATER") 127 | (220 "202.svg" "202.svg" "300" "曇朝夕一時雨" "OCCASIONAL SCCATERED SHOWERS IN THE MORNING AND EVENING CLOUDY DURING THE DAY") 128 | (221 "202.svg" "202.svg" "300" "曇朝の内一時雨" "CLOUDY OCCASIONAL SCCATERED SHOWERS IN THE MORNING") 129 | (222 "212.svg" "212.svg" "300" "曇夕方一時雨" "CLOUDY OCCASIONAL SCCATERED SHOWERS IN THE EVENING") 130 | (223 "201.svg" "601.svg" "200" "曇日中時々晴" "CLOUDY IN THE MORNING AND EVENING PARTLY CLOUDY DURING THE DAY ") 131 | (224 "212.svg" "212.svg" "300" "曇昼頃から雨" "CLOUDY RAIN IN THE AFTERNOON") 132 | (225 "212.svg" "212.svg" "300" "曇夕方から雨" "CLOUDY RAIN IN THE EVENING") 133 | (226 "212.svg" "212.svg" "300" "曇夜は雨" "CLOUDY RAIN IN THE NIGHT") 134 | (228 "215.svg" "215.svg" "400" "曇昼頃から雪" "CLOUDY SNOW IN THE AFTERNOON") 135 | (229 "215.svg" "215.svg" "400" "曇夕方から雪" "CLOUDY SNOW IN THE EVENING") 136 | (230 "215.svg" "215.svg" "400" "曇夜は雪" "CLOUDY SNOW IN THE NIGHT") 137 | (231 "200.svg" "200.svg" "200" "曇海上海岸は霧か霧雨" "CLOUDY FOG OR DRIZZLING ON THE SEA AND NEAR SEASHORE") 138 | (240 "202.svg" "202.svg" "300" "曇時々雨で雷を伴う" "CLOUDY FREQUENT SCCATERED SHOWERS AND THUNDER") 139 | (250 "204.svg" "204.svg" "400" "曇時々雪で雷を伴う" "CLOUDY FREQUENT SNOW AND THUNDER") 140 | (260 "204.svg" "204.svg" "400" "曇一時雪か雨" "CLOUDY SNOW FLURRIES OR OCCASIONAL SCATTERED SHOWERS") 141 | (270 "204.svg" "204.svg" "400" "曇時々雪か雨" "CLOUDY FREQUENT SNOW FLURRIES OR SCATTERED SHOWERS") 142 | (281 "215.svg" "215.svg" "400" "曇後雪か雨" "CLOUDY SNOW OR RAIN LATER") 143 | (300 "300.svg" "300.svg" "300" "雨" "RAIN") 144 | (301 "301.svg" "701.svg" "300" "雨時々晴" "RAIN PARTLY CLOUDY") 145 | (302 "302.svg" "302.svg" "300" "雨時々止む" "SHOWERS THROUGHOUT THE DAY") 146 | (303 "303.svg" "303.svg" "400" "雨時々雪" "RAIN FREQUENT SNOW FLURRIES") 147 | (304 "300.svg" "300.svg" "300" "雨か雪" "RAINORSNOW") 148 | (306 "300.svg" "300.svg" "300" "大雨" "HEAVYRAIN") 149 | (308 "308.svg" "308.svg" "300" "雨で暴風を伴う" "RAINSTORM") 150 | (309 "303.svg" "303.svg" "400" "雨一時雪" "RAIN OCCASIONAL SNOW") 151 | (311 "311.svg" "711.svg" "300" "雨後晴" "RAIN CLEAR LATER") 152 | (313 "313.svg" "313.svg" "300" "雨後曇" "RAIN CLOUDY LATER") 153 | (314 "314.svg" "314.svg" "400" "雨後時々雪" "RAIN FREQUENT SNOW FLURRIES LATER") 154 | (315 "314.svg" "314.svg" "400" "雨後雪" "RAIN SNOW LATER") 155 | (316 "311.svg" "711.svg" "300" "雨か雪後晴" "RAIN OR SNOW CLEAR LATER") 156 | (317 "313.svg" "313.svg" "300" "雨か雪後曇" "RAIN OR SNOW CLOUDY LATER") 157 | (320 "311.svg" "711.svg" "300" "朝の内雨後晴" "RAIN IN THE MORNING CLEAR LATER") 158 | (321 "313.svg" "313.svg" "300" "朝の内雨後曇" "RAIN IN THE MORNING CLOUDY LATER") 159 | (322 "303.svg" "303.svg" "400" "雨朝晩一時雪" "OCCASIONAL SNOW IN THE MORNING AND EVENING RAIN DURING THE DAY") 160 | (323 "311.svg" "711.svg" "300" "雨昼頃から晴" "RAIN CLEAR IN THE AFTERNOON") 161 | (324 "311.svg" "711.svg" "300" "雨夕方から晴" "RAIN CLEAR IN THE EVENING") 162 | (325 "311.svg" "711.svg" "300" "雨夜は晴" "RAIN CLEAR IN THE NIGHT") 163 | (326 "314.svg" "314.svg" "400" "雨夕方から雪" "RAIN SNOW IN THE EVENING") 164 | (327 "314.svg" "314.svg" "400" "雨夜は雪" "RAIN SNOW IN THE NIGHT") 165 | (328 "300.svg" "300.svg" "300" "雨一時強く降る" "RAIN EXPECT OCCASIONAL HEAVY RAINFALL") 166 | (329 "300.svg" "300.svg" "300" "雨一時みぞれ" "RAIN OCCASIONAL SLEET") 167 | (340 "400.svg" "400.svg" "400" "雪か雨" "SNOWORRAIN") 168 | (350 "300.svg" "300.svg" "300" "雨で雷を伴う" "RAIN AND THUNDER") 169 | (361 "411.svg" "811.svg" "400" "雪か雨後晴" "SNOW OR RAIN CLEAR LATER") 170 | (371 "413.svg" "413.svg" "400" "雪か雨後曇" "SNOW OR RAIN CLOUDY LATER") 171 | (400 "400.svg" "400.svg" "400" "雪" "SNOW") 172 | (401 "401.svg" "801.svg" "400" "雪時々晴" "SNOW FREQUENT CLEAR") 173 | (402 "402.svg" "402.svg" "400" "雪時々止む" "SNOWTHROUGHOUT THE DAY") 174 | (403 "403.svg" "403.svg" "400" "雪時々雨" "SNOW FREQUENT SCCATERED SHOWERS") 175 | (405 "400.svg" "400.svg" "400" "大雪" "HEAVYSNOW") 176 | (406 "406.svg" "406.svg" "400" "風雪強い" "SNOWSTORM") 177 | (407 "406.svg" "406.svg" "400" "暴風雪" "HEAVYSNOWSTORM") 178 | (409 "403.svg" "403.svg" "400" "雪一時雨" "SNOW OCCASIONAL SCCATERED SHOWERS") 179 | (411 "411.svg" "811.svg" "400" "雪後晴" "SNOW CLEAR LATER") 180 | (413 "413.svg" "413.svg" "400" "雪後曇" "SNOW CLOUDY LATER") 181 | (414 "414.svg" "414.svg" "400" "雪後雨" "SNOW RAIN LATER") 182 | (420 "411.svg" "811.svg" "400" "朝の内雪後晴" "SNOW IN THE MORNING CLEAR LATER") 183 | (421 "413.svg" "413.svg" "400" "朝の内雪後曇" "SNOW IN THE MORNING CLOUDY LATER") 184 | (422 "414.svg" "414.svg" "400" "雪昼頃から雨" "SNOW RAIN IN THE AFTERNOON") 185 | (423 "414.svg" "414.svg" "400" "雪夕方から雨" "SNOW RAIN IN THE EVENING") 186 | (425 "400.svg" "400.svg" "400" "雪一時強く降る" "SNOW EXPECT OCCASIONAL HEAVY SNOWFALL") 187 | (426 "400.svg" "400.svg" "400" "雪後みぞれ" "SNOW SLEET LATER") 188 | (427 "400.svg" "400.svg" "400" "雪一時みぞれ" "SNOW OCCASIONAL SLEET") 189 | (450 "400.svg" "400.svg" "400" "雪で雷を伴う" "SNOW AND THUNDER"))) 190 | 191 | ;;;;; 天気コードデータの取得とアクセッサ 192 | 193 | (defun jma-weather-code-data (code) 194 | (assq (if (stringp code) (string-to-number code) code) jma-weather-code-list)) 195 | 196 | (defun jma-weather-code-data-image-daytime (data) (nth 1 data)) 197 | (defun jma-weather-code-data-image-night (data) (nth 2 data)) 198 | (defun jma-weather-code-data-image (data night-p) (nth (if night-p 2 1) data)) 199 | (defun jma-weather-code-data-text-ja (data) (nth 4 data)) 200 | (defun jma-weather-code-data-text-en (data) (nth 5 data)) 201 | 202 | ;;;;; 天気コードから各種情報の取得 203 | 204 | (defun jma-weather-code-image-daytime (code) 205 | (jma-weather-code-data-image-daytime (jma-weather-code-data code))) 206 | 207 | (defun jma-weather-code-image-night (code) 208 | (jma-weather-code-data-image-night (jma-weather-code-data code))) 209 | 210 | (defun jma-weather-code-image (code night-p) 211 | (jma-weather-code-data-image (jma-weather-code-data code) night-p)) 212 | 213 | (defun jma-weather-code-text-ja (code) 214 | (jma-weather-code-data-text-ja (jma-weather-code-data code))) 215 | 216 | (defun jma-weather-code-text-en (code) 217 | (jma-weather-code-data-text-en (jma-weather-code-data code))) 218 | 219 | ;;;;; 画像 220 | 221 | (defun jma-weather-code-image-delete-all () 222 | (interactive) 223 | (when jma-weather-code-image-dir 224 | (let ((files (directory-files jma-weather-code-image-dir t "\\.svg$"))) 225 | (unless files 226 | (error "No file is found")) 227 | (when (yes-or-no-p (format "%s\nDelete above files in `%s'? " 228 | (mapconcat #'file-name-nondirectory files " ") 229 | jma-weather-code-image-dir)) 230 | (dolist (path files) 231 | (delete-file path)))))) 232 | 233 | (defun jma-weather-code-image-download-file (filename &optional override-p) 234 | "画像をダウンロードします。" 235 | (let ((url (concat "https://www.jma.go.jp/bosai/forecast/img/" filename)) 236 | (dst-file (expand-file-name filename jma-weather-code-image-dir))) 237 | (when (or override-p 238 | (not (file-exists-p dst-file))) 239 | (make-directory jma-weather-code-image-dir t) 240 | (url-copy-file url dst-file t)))) 241 | 242 | (defun jma-weather-code-image-download-all (&optional override-p) 243 | "全ての天気コード画像をダウンロードします。" 244 | (interactive) 245 | (dolist (data jma-weather-code-list) 246 | (jma-weather-code-image-download-file 247 | (jma-weather-code-data-image-daytime data) override-p) 248 | (jma-weather-code-image-download-file 249 | (jma-weather-code-data-image-night data) override-p))) 250 | 251 | (defun jma-weather-code-image-download (code night-p &optional override-p) 252 | (jma-weather-code-image-download-file 253 | (jma-weather-code-image code night-p) 254 | override-p)) 255 | 256 | (defun jma-weather-code-image-file-path (code night-p) 257 | (expand-file-name 258 | (jma-weather-code-image code night-p) 259 | jma-weather-code-image-dir)) 260 | 261 | (defun jma-weather-code-image-create (code &optional night-p image-height) 262 | "指定された天気コードに対応するImage Descriptorを返します。 263 | 264 | テキスト端末の場合やSVGをサポートしていない場合はnilを返します。" 265 | (when (jma-use-images-p) 266 | (jma-weather-code-image-download code night-p) 267 | (create-image (jma-weather-code-image-file-path code night-p) 268 | 'svg nil 269 | :height (or image-height 270 | jma-weather-code-image-default-height 271 | ;; バッチモード時(default-font-height)は1になる 272 | (if noninteractive 273 | 16 274 | (default-font-height))) 275 | :scale 1 276 | :ascent 'center))) 277 | ;;Usage: (insert-image (jma-weather-code-image-create 300 nil)) 278 | 279 | (defun jma-weather-code-image-string (code &optional night-p image-height) 280 | "指定された天気コードに対応する画像を表示する文字列を返します。 281 | 282 | テキスト端末の場合やSVGをサポートしていない場合はnilを返します。" 283 | (when (jma-use-images-p) 284 | (propertize "_" 285 | 'display 286 | (jma-weather-code-image-create code night-p image-height)))) 287 | ;;Usage: (insert (jma-weather-code-image-string 100 nil)) 288 | 289 | (provide 'jma-weather-code) 290 | ;;; jma-weather-code.el ends here 291 | -------------------------------------------------------------------------------- /jma-forecast.el: -------------------------------------------------------------------------------- 1 | ;;; jma-forecast.el --- JMA Forecast -*- lexical-binding: t; -*- 2 | 3 | ;; Copyright (C) 2022 AKIYAMA Kouhei 4 | 5 | ;; Author: AKIYAMA Kouhei 6 | ;; Keywords: Japan,Weather,Diary,Org 7 | 8 | ;; This program is free software; you can redistribute it and/or modify 9 | ;; it under the terms of the GNU General Public License as published by 10 | ;; the Free Software Foundation, either version 3 of the License, or 11 | ;; (at your option) any later version. 12 | 13 | ;; This program is distributed in the hope that it will be useful, 14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ;; GNU General Public License for more details. 17 | 18 | ;; You should have received a copy of the GNU General Public License 19 | ;; along with this program. If not, see . 20 | 21 | ;;; Commentary: 22 | 23 | ;; * 使用例 24 | ;; 25 | ;; ** 今日の東京の天気予報を取得する 26 | ;; 27 | ;; (jma-forecast-weather-for-date 28 | ;; (jma-forecast-get "130000") ;;130000はoffice-code(府県予報区) 29 | ;; "130010" ;;class10-code(一次細分区域) 30 | ;; "44132" ;;amedas-code(アメダス観測所番号) 31 | ;; "130010" ;;week-area-code(週間予報区域。府県予報区を少し細分化したもの) 32 | ;; "44132" ;;week-amedas-code(週間予報でのアメダス観測所番号) 33 | ;; (jma-date-today)) ;; 日付はcalendarパッケージと同じ形式(MM DD YYYY) 34 | ;; 35 | ;; ** 東京の生の予報データを取得する 36 | ;; 37 | ;; (let ((forecast (jma-forecast-get "130000"))) 38 | ;; ....) 39 | ;; 40 | ;; ** 長野県の特定の日の天気予報を取得し、文字列化し、バッファに挿入する 41 | ;; 42 | ;; (let* ((forecast (jma-forecast-get "200000")) 43 | ;; (weather (jma-forecast-weather-for-date 44 | ;; forecast 45 | ;; "200020" ;;中部 46 | ;; "48491" ;;諏訪 47 | ;; '("200100" "200000") ;;中部・南部 または 長野県全域 48 | ;; '("48361" "48156") ;;松本 または 長野 49 | ;; (jma-date 2022 2 23))) ;;2022年2月23日 50 | ;; (weather-str (jma-weather-to-string weather))) 51 | ;; (when weather-str 52 | ;; (insert weather-str))) 53 | 54 | ;; * エリアコード 55 | ;; 56 | ;; 天気予報で使用する場所を指定するためのコードには次のものがある。 57 | ;; 58 | ;; - office : 府県予報区 (概ね都道府県) 59 | ;; - class10 : 一次細分区域 (府県の中を大ざっぱに分割したもの) 60 | ;; - week-area : 週間予報区域(府県予報区を少し細分化したもの)(※独自呼称) 61 | ;; - amedas : アメダス観測所 62 | ;; 63 | ;; 天気予報データは府県予報区(office)単位で取得できる。 64 | ;; 65 | ;; 天気予報(明後日までの詳細)は一次細分区域(class10)毎に行われている。 66 | ;; (参考: https://www.jma.go.jp/jma/kishou/know/saibun/) 67 | ;; 68 | ;; 週間天気予報は原則として府県予報区毎に行われているが、地形や季節等 69 | ;; の都合で多少の細分化が行われている。ここでは細分化後の区域を週間予 70 | ;; 報区域(week-area)と呼ぶことにする。 71 | ;; (参考: https://www.jma.go.jp/jma/kishou/know/kurashi/shukan.html) 72 | ;; 73 | ;; 気温や降水量に関する情報はアメダス観測所(amedas)毎に発表されている。 74 | ;; (参考: https://www.jma.go.jp/jma/kishou/know/amedas/kaisetsu.html) 75 | ;; 76 | ;; 例: 77 | ;; 長野県(office=200000) 78 | ;; - 詳細予報 79 | ;; - 一次細分区域(class10) 80 | ;; - 200010 北部 81 | ;; - 200020 中部 82 | ;; - 200030 南部 83 | ;; - アメダス観測所(amedas) 84 | ;; - 48156 長野 (北部) 85 | ;; - 48361 松本 (中部) 86 | ;; - 48491 諏訪 (中部) 87 | ;; - 48767 飯田 (南部) 88 | ;; - 48331 軽井沢 (中部) 89 | ;; - 週間予報 90 | ;; - 週間予報区域(week-area) (※季節によっては分割されないことに注意) 91 | ;; - 200010 北部 92 | ;; - 200100 中部・南部 93 | ;; - アメダス観測所(amedas) 94 | ;; - 48156 長野 (北部) 95 | ;; - 48361 松本 (中部・南部) 96 | ;; (2022-02-23現在) 97 | ;; 人間閲覧用URL: https://www.jma.go.jp/bosai/forecast/#area_type=offices&area_code=200000 98 | ;; JSON URL: https://www.jma.go.jp/bosai/forecast/data/forecast/200000.json 99 | ;; 100 | ;; 各エリア間の関係性は次のURLから得られる。 101 | ;; - https://www.jma.go.jp/bosai/forecast/const/forecast_area.json (class10とamedas) 102 | ;; - https://www.jma.go.jp/bosai/forecast/const/week_area.json (week-areaとamedas) 103 | ;; - https://www.jma.go.jp/bosai/common/const/area.json (officeとclass10) 104 | ;; 105 | 106 | ;; * 天気予報のミニバッファ表示 107 | ;; 108 | ;; M-x jma-forecast-show を実行するとミニバッファに天気予報を表示する。 109 | ;; 110 | ;; 事前に次の変数で予報する地域を設定しておく必要がある。 111 | ;; - jma-forecast-location-office 112 | ;; - jma-forecast-location-class10 113 | ;; - jma-forecast-location-amedas 114 | ;; - jma-forecast-location-week-area 115 | ;; - jma-forecast-location-week-amedas 116 | ;; 117 | ;; M-x jma-forecast-location-setup を実行すると入力補完付きで予報地域 118 | ;; を設定できる。 119 | 120 | ;; * Diary連携 121 | ;; 122 | ;; ダイアリーエントリーやorg-modeのagendaファイルに次の文を追加すると、 123 | ;; 現在の日付から向こう8日間に天気予報のエントリーが追加される。 124 | ;; 125 | ;; %%(jma-diary-weathers "130000" "130010" "44132" "130010" "44132") 126 | ;; 127 | 128 | ;;; Code: 129 | 130 | (require 'parse-time) 131 | (require 'jma-utils) 132 | (require 'jma-area) 133 | (require 'jma-weather-code) 134 | (require 'jma-amedas) 135 | 136 | ;;;; 天気予報 137 | 138 | ;;;;; 天気予報データの取得 139 | 140 | (defun jma-forecast-get (office-code) 141 | "OFFICE-CODE で指定される府県予報区の天気予報データを返します。" 142 | (when (symbolp office-code) 143 | (setq office-code (symbol-name office-code))) 144 | (when (string-match-p "\\`[0-9]+\\'" office-code) 145 | (or (jma-forecast-cache-get office-code) 146 | (jma-forecast-cache-put 147 | office-code 148 | ;; Download 149 | (jma-json-get 150 | (format "https://www.jma.go.jp/bosai/forecast/data/forecast/%s.json" 151 | office-code)))))) 152 | 153 | ;; キャッシュ 154 | 155 | (defvar jma-forecast-cache nil) 156 | 157 | (defun jma-forecast-cache-make-key (office-code) 158 | (cond 159 | ((symbolp office-code) 160 | office-code) 161 | ((stringp office-code) 162 | (intern office-code)) 163 | (t 164 | (error "Invalid type office-code=%s" office-code)))) 165 | 166 | (defun jma-forecast-cache-put (office-code forecast) 167 | (let ((key (jma-forecast-cache-make-key office-code))) 168 | (setf (alist-get key jma-forecast-cache) 169 | ;; (CACHE-TIME FORECAST) 170 | (list (current-time) forecast)) 171 | forecast)) 172 | 173 | (defun jma-forecast-cache-get (office-code) 174 | (let* ((key (jma-forecast-cache-make-key office-code)) 175 | (cache (alist-get key jma-forecast-cache))) 176 | (when cache 177 | (let* (;; (CACHE-TIME FORECAST) 178 | (cache-time (nth 0 cache)) 179 | (forecast (nth 1 cache)) 180 | (next-time (jma-forecast-next-report-time forecast)) 181 | (curr-time (current-time)) 182 | (ttl (if (time-less-p curr-time next-time) 183 | 10800 ;;3*60*60 次回更新予定時刻を過ぎていないとき 184 | 120))) ;;2*60 次回更新予定時刻を過ぎているとき 185 | (when (time-less-p curr-time (time-add cache-time ttl)) 186 | forecast))))) 187 | 188 | 189 | 190 | ;;;;; 天気予報データの中身へのアクセス 191 | 192 | ;; 天気予報データには次の二つの発表データが含まれています。 193 | ;; - 詳細予報(明後日までの詳細) 194 | ;; - 週間予報(翌日から7日間) 195 | 196 | (defun jma-forecast-report-at (forecast report-index) 197 | "天気予報データ FORECAST 内の REPORT-INDEX 番目の発表データを返します。" 198 | (elt forecast report-index)) 199 | 200 | (defun jma-forecast-detailed-report (forecast) 201 | "天気予報データ FORECAST 内の詳細予報発表データを返します。" 202 | (jma-forecast-report-at forecast 0)) 203 | 204 | (defun jma-forecast-week-report (forecast) 205 | "天気予報データ FORECAST 内の週間予報発表データを返します。" 206 | (jma-forecast-report-at forecast 1)) 207 | 208 | (defun jma-forecast-next-report-time (forecast) 209 | "予報の次の更新日時を返します。" 210 | (let ((t0 (jma-forecast-report-datetime-next 211 | (jma-forecast-detailed-report forecast) nil)) 212 | (t1 (jma-forecast-report-datetime-next 213 | (jma-forecast-week-report forecast) t))) 214 | (if (time-less-p t0 t1) t0 t1))) 215 | 216 | ;;;;; 発表データの中身へのアクセス 217 | 218 | (defun jma-forecast-report-publisher (report) 219 | "発表データ REPORT の発表者を返します。" 220 | (alist-get 'publishingOffice report)) 221 | 222 | (defun jma-forecast-report-datetime-string (report) 223 | "発表データ REPORT の発表日時を文字列で返します。" 224 | (alist-get 'reportDatetime report)) 225 | 226 | (defun jma-forecast-report-datetime (report) 227 | "発表データ REPORT の発表日時を返します。" 228 | (parse-iso8601-time-string (jma-forecast-report-datetime-string report))) 229 | 230 | (defun jma-forecast-report-time-series-vector (report) 231 | "発表データ REPORT 内の全時系列データベクトルを返します。" 232 | (alist-get 'timeSeries report)) 233 | 234 | (defun jma-forecast-report-time-series-at (report time-series-index) 235 | "発表データ REPORT の TIME-SERIES-INDEX 番目の時系列データを返します。" 236 | (elt (jma-forecast-report-time-series-vector report) time-series-index)) 237 | 238 | (defun jma-forecast-report-datetime-next (report week-p) 239 | (jma-time-next-hour 240 | (jma-forecast-report-datetime report) 241 | (if week-p '(11 17) '(5 11 17)))) 242 | 243 | ;;(jma-forecast-report-datetime-next (elt tokyo-forecast 0) '(5 11 17)) 244 | 245 | ;;;;; 特定位置・特定日の予報へのアクセス 246 | 247 | (defun jma-forecast-weather-for-date (forecast class10-code amedas-code week-area-code week-amedas-code date) 248 | "天気予報データ FORECAST から指定した場所・日付の予報を取り出します。 249 | 250 | CLASS10-CODE 一次細分区域コード。 251 | 252 | AMEDAS-CODE 気温を取得するためのAMEDAS観測所コード。 253 | 254 | WEEK-AREA-CODE 週間予報のための区域コード。 255 | 256 | WEEK-AMEDAS-CODE 週間予報における気温を取得するためのAMEDAS観測所コード。" 257 | (or (jma-forecast-weather-for-date-from-detailed-report 258 | (jma-forecast-detailed-report forecast) class10-code amedas-code date) 259 | (jma-forecast-weather-for-date-from-week-report 260 | (jma-forecast-week-report forecast) week-area-code week-amedas-code date))) 261 | 262 | ;;(jma-forecast-weather-for-date tokyo-forecast "130010" "130010" "44132" (jma-date 2022 2 23)) 263 | 264 | ;;;;;; (2日間)詳細予報 265 | 266 | (defun jma-forecast-weather-for-date-from-detailed-report (detailed-report class10-code amedas-code date) 267 | "指定した場所・日付の詳細予報を返します。" 268 | (let* ((time-series-0 (jma-forecast-report-time-series-at detailed-report 0)) 269 | (range (jma-time-series-range-in-date time-series-0 date))) 270 | 271 | (when (jma-not-empty-range-p range) 272 | (let ((time-index (car range))) 273 | ;; 注意: 明後日の天気は詳細予報に含まれるが、降水確率や気温の情報は無い。 274 | ;; 全情報無ければnilを返して週間予報を使うようにする。 275 | (when-let ((area (jma-time-series-area time-series-0 class10-code)) 276 | (weather (jma-time-series-area-value-at area 'weathers time-index)) 277 | (weather-code (jma-time-series-area-value-at area 'weatherCodes time-index)) 278 | (wind (jma-time-series-area-value-at area 'winds time-index)) 279 | (pops (jma-forecast-pops-for-date-from-detailed-report detailed-report class10-code date))) 280 | (let (;; 波は海に面していない区域では含まれない。 281 | (wave (jma-time-series-area-value-at area 'waves time-index))) 282 | (append 283 | (list 284 | (cons 'report-type "detailed") 285 | (cons 'class10-area (alist-get 'area area)) 286 | (cons 'weather weather) 287 | (cons 'weather-code weather-code) 288 | (cons 'wind wind) 289 | (cons 'wave wave) 290 | (cons 'pops pops) 291 | (cons 'pop (mapconcat #'identity pops "/"))) 292 | (jma-forecast-temps-for-date-from-detailed-report detailed-report amedas-code date)))))))) 293 | 294 | (defun jma-forecast-pops-for-date-from-detailed-report (detailed-report class10-code date) 295 | (let* ((time-series-1 (jma-forecast-report-time-series-at detailed-report 1)) 296 | (range (jma-time-series-range-in-date time-series-1 date))) 297 | 298 | (when (jma-not-empty-range-p range) 299 | (when-let ((area (jma-time-series-area time-series-1 class10-code))) 300 | (cl-loop for time-index from (car range) to (1- (cdr range)) 301 | collect (jma-time-series-area-value-at area 'pops time-index)))))) 302 | 303 | (defun jma-forecast-temps-for-date-from-detailed-report (detailed-report amedas-code date) 304 | (let* ((time-series-2 (jma-forecast-report-time-series-at detailed-report 2)) 305 | (range (jma-time-series-range-in-date time-series-2 date))) 306 | (when (jma-not-empty-range-p range) 307 | (let ((time-index (car range))) 308 | (when-let ((area (jma-time-series-area time-series-2 amedas-code)) 309 | (tempMin (jma-time-series-area-value-at area 'temps time-index)) 310 | (tempMax (jma-time-series-area-value-at area 'temps (1+ time-index)))) 311 | (list 312 | (cons 'amedas-point (alist-get 'area area)) 313 | (cons 'temp-min tempMin) 314 | (cons 'temp-max tempMax))))))) 315 | 316 | ;;;;;; (翌日以降7日間)週間予報 317 | 318 | (defun jma-forecast-weather-for-date-from-week-report (week-report week-area-code amedas-code date) 319 | "指定した場所・日付の週間予報を返します。" 320 | (let* ((time-series-0 (jma-forecast-report-time-series-at week-report 0)) 321 | (range (jma-time-series-range-in-date time-series-0 date))) 322 | (when (jma-not-empty-range-p range) 323 | (let ((time-index (car range))) 324 | (when-let ((area (jma-time-series-area time-series-0 week-area-code)) 325 | (weather-code (jma-time-series-area-value-at area 'weatherCodes time-index)) 326 | (p-o-p (jma-time-series-area-value-at area 'pops time-index)) 327 | (reliability (jma-time-series-area-value-at area 'reliabilities time-index))) 328 | 329 | (let ((selected-amedas-code 330 | ;; week-area-codeとamedas-codeがリスト表現の時、 331 | ;; 実際に選択されたweek-areaと対応するamedas-codeを使わなければならない。 332 | ;; 例えば(津軽の例) 333 | ;; week-area-codeが("020000" "020010" "020100")で 334 | ;; amedas-codeが(nil "31312" "31312")のとき、 335 | ;; weekで"020010"を選択したら 336 | ;; amedasは"31312"でなければならない。 337 | (if (and (sequencep week-area-code) (sequencep amedas-code)) 338 | (let* ((selected-week-area-code (alist-get 'code (alist-get 'area area))) 339 | (index (seq-position week-area-code selected-week-area-code))) 340 | (if (and index (< index (length amedas-code))) 341 | (elt amedas-code index) 342 | amedas-code)) 343 | amedas-code))) 344 | (append 345 | (list 346 | (cons 'report-type "week") 347 | (cons 'week-area (alist-get 'area area)) 348 | (cons 'weather (jma-weather-code-text-ja weather-code)) 349 | (cons 'weather-code weather-code) 350 | (cons 'pop p-o-p) 351 | (cons 'reliability reliability)) 352 | (jma-forecast-temps-for-date-from-week-report 353 | week-report 354 | selected-amedas-code 355 | date)))))))) 356 | 357 | (defun jma-forecast-temps-for-date-from-week-report (week-report amedas-code date) 358 | (let* ((time-series-1 (jma-forecast-report-time-series-at week-report 1)) 359 | (range (jma-time-series-range-in-date time-series-1 date))) 360 | (when (jma-not-empty-range-p range) 361 | (let ((time-index (car range))) 362 | (when-let ((area (jma-time-series-area time-series-1 amedas-code))) 363 | (list 364 | (cons 'amedas-point (alist-get 'area area)) 365 | (cons 'temp-min (jma-time-series-area-value-at area 'tempsMin time-index)) 366 | (cons 'temp-min-lower (jma-time-series-area-value-at area 'tempsMinLower time-index)) 367 | (cons 'temp-min-upper (jma-time-series-area-value-at area 'tempsMinUpper time-index)) 368 | (cons 'temp-max (jma-time-series-area-value-at area 'tempsMax time-index)) 369 | (cons 'temp-max-lower (jma-time-series-area-value-at area 'tempsMaxLower time-index)) 370 | (cons 'temp-max-upper (jma-time-series-area-value-at area 'tempsMaxUpper time-index)))))))) 371 | 372 | 373 | 374 | ;;;;; 天気予報の文字列化 375 | 376 | (defcustom jma-weather-default-template 377 | "{{{weather-image:%s }}}{{{weather}}}{{{pop: %s%%}}}{{{temp-min: %s~}}}{{{temp-max:%s℃}}}" 378 | "テンプレート文字列(see: `jma-expand-template')" 379 | :group 'jma 380 | :type '(choice (string :tag "テンプレート文字列") 381 | (function :tag "文字列化関数"))) 382 | 383 | (defconst jma-weather-default-template-params 384 | '((weather-image . jma-weather-to-weather-image))) ;;{{{weather-image}}}を指定可能にする 385 | 386 | (defun jma-weather-to-weather-image (weather) 387 | (when-let ((code (alist-get 'weather-code weather))) 388 | (jma-weather-code-image-string code))) 389 | 390 | (defun jma-weather-to-string (weather &optional template) 391 | (when weather 392 | (jma-expand-template 393 | (or template jma-weather-default-template) 394 | (append 395 | weather 396 | jma-weather-default-template-params)))) 397 | 398 | ;;(setq tokyo-forecast (jma-forecast-get "130000")) 399 | ;;(insert (jma-weather-to-string (jma-forecast-weather-for-date (jma-forecast-get "130000") "130010" "130010" "44132" (jma-date-today)) nil)) 400 | 401 | ;;;;; 天気予報エリア選択 402 | 403 | ;; キャッシュ 404 | 405 | (defvar jma-forecast-cache-forecast-area nil) 406 | (defvar jma-forecast-cache-week-area nil) 407 | (defvar jma-forecast-cache-week-area05 nil) 408 | (defvar jma-forecast-cache-week-area-name nil) 409 | 410 | (defconst jma-forecast-cache-data-alist 411 | '((jma-forecast-cache-forecast-area . "https://www.jma.go.jp/bosai/forecast/const/forecast_area.json") 412 | (jma-forecast-cache-week-area . "https://www.jma.go.jp/bosai/forecast/const/week_area.json") 413 | (jma-forecast-cache-week-area05 . "https://www.jma.go.jp/bosai/forecast/const/week_area05.json") 414 | (jma-forecast-cache-week-area-name . "https://www.jma.go.jp/bosai/forecast/const/week_area_name.json"))) 415 | 416 | (defun jma-forecast-cache-data-get (var) 417 | (or (symbol-value var) 418 | (when-let ((url (alist-get var jma-forecast-cache-data-alist))) 419 | (set var (jma-json-get url))))) 420 | 421 | (defun jma-forecast-cache-data-load-all () 422 | (dolist (data jma-forecast-cache-data-alist) 423 | (let ((var (car data)) 424 | (url (cdr data))) 425 | (unless (symbol-value var) 426 | (set var (jma-json-get url)))))) 427 | 428 | ;; コード変換 429 | 430 | (defun jma-forecast-area-amedas-codes-from-class10-code (class10-code) 431 | "一次細分区域コードから(詳細)天気予報で使うアメダス観測所コードリストを求めます。" 432 | (mapcar ;;vectorからlistへ変換 433 | #'identity 434 | (seq-some 435 | (lambda (odata) 436 | (seq-some 437 | (lambda (c10data) 438 | (and (equal (alist-get 'class10 c10data) class10-code) 439 | (alist-get 'amedas c10data))) 440 | (cdr odata))) 441 | (jma-forecast-cache-data-get 442 | 'jma-forecast-cache-forecast-area)))) 443 | 444 | (defun jma-forecast-area-week-area-codes-from-class10-code (class10-code) 445 | "一次細分区域コードから週間予報区域コード(可能性のある全コード)リストを求めます。" 446 | (mapcar ;;vectorからlistへ変換 447 | #'identity 448 | (alist-get (jma-ensure-symbol class10-code) 449 | (jma-forecast-cache-data-get 450 | 'jma-forecast-cache-week-area05)))) 451 | 452 | (defun jma-forecast-area-amedas-code-from-week-area-code (week-area-code) 453 | "週間予報区域コードから週間天気予報で使うアメダス観測所コードを求めます。" 454 | (seq-some 455 | (lambda (odata) 456 | (seq-some 457 | (lambda (wdata) 458 | (and (equal (alist-get 'week wdata) week-area-code) 459 | (alist-get 'amedas wdata))) 460 | (cdr odata))) 461 | (jma-forecast-cache-data-get 462 | 'jma-forecast-cache-week-area))) 463 | 464 | ;; ユーザー入力 465 | 466 | (defun jma-forecast-area-read () 467 | "天気予報取得用のエリアコードをミニバッファから読み取ります。" 468 | (interactive) 469 | (let* (;; 府県予報区を選択 470 | (office-code (jma-area-read-office)) 471 | ;; 一次細分区域を選択 472 | (class10-code (jma-area-read-class10 office-code)) 473 | ;; アメダス観測所を選択 474 | (amedas-code (jma-amedas-read-amedas-code 475 | (jma-forecast-area-amedas-codes-from-class10-code 476 | class10-code)))) 477 | (jma-forecast-area-read--common 478 | office-code class10-code amedas-code 479 | (called-interactively-p 'interactive)))) 480 | 481 | ;; 市区町村から読み取る方法 482 | 483 | (defun jma-forecast-area-read-class20 () 484 | "ミニバッファから二次細分区域(概ね市区町村)を読み取り、天気予報 485 | の取得に必要なエリアコードを返します。" 486 | (interactive) 487 | (let* (;; 府県予報区を選択 488 | (office-code (jma-area-read-office)) 489 | ;; 二次細分区域を選択し、一次細分区域を割り出す 490 | (class20-code (jma-area-read-class20-in-office office-code)) 491 | (class15-code (jma-area-parent-code (jma-area-class20 class20-code))) 492 | (class10-code (jma-area-parent-code (jma-area-class15 class15-code))) 493 | ;; アメダス観測所を選択 494 | ;;@todo 入力なしに一つに絞り込みたい。緯度経度で二次細分区域から一番近い観測所を求めるくらいしか方法が見当たらない。ユーザーに委ねる方がマシ? 495 | (amedas-code (jma-amedas-read-amedas-code 496 | (jma-forecast-area-amedas-codes-from-class10-code 497 | class10-code)))) 498 | (jma-forecast-area-read--common 499 | office-code class10-code amedas-code 500 | (called-interactively-p 'interactive)))) 501 | ;;(jma-forecast-area-read-class20) 502 | 503 | (defun jma-forecast-area-read--common (office-code 504 | class10-code 505 | amedas-code 506 | interactive-p) 507 | (let* (;; 週間予報区域を割り出す 508 | (week-area-codes 509 | (jma-forecast-area-week-area-codes-from-class10-code class10-code)) 510 | ;; 週間予報用のアメダス観測所を割り出す 511 | (week-amedas-codes 512 | (mapcar 513 | #'jma-forecast-area-amedas-code-from-week-area-code 514 | week-area-codes)) 515 | ;; 結果のリストを作る 516 | (result 517 | (list 518 | office-code 519 | class10-code 520 | amedas-code 521 | (if (cdr week-area-codes) 522 | week-area-codes (car week-area-codes)) 523 | (if (cdr week-amedas-codes) 524 | week-amedas-codes (car week-amedas-codes))))) 525 | (when interactive-p 526 | (let ((str (substring (prin1-to-string result) 1 -1))) 527 | (kill-new str) 528 | (message "Copy %s" str))) 529 | result)) 530 | 531 | 532 | ;;;;; お手軽表示 533 | 534 | (defcustom jma-forecast-location-office nil;;"130000" 535 | "府県予報区" 536 | :group 'jma 537 | :type '(string :tag "番号")) 538 | 539 | (defcustom jma-forecast-location-class10 nil;;"130010" 540 | "一次細分区域" 541 | :group 'jma 542 | :type '(choice (string :tag "番号") 543 | (repeat :tag "優先順リスト" (string :tag "番号")))) 544 | 545 | (defcustom jma-forecast-location-amedas nil;;"44132" 546 | "アメダス観測所" 547 | :group 'jma 548 | :type '(choice (string :tag "番号") 549 | (repeat :tag "優先順リスト" (string :tag "番号")))) 550 | 551 | (defcustom jma-forecast-location-week-area nil;;"130010" 552 | "週間予報区域" 553 | :group 'jma 554 | :type '(choice (string :tag "番号") 555 | (repeat :tag "優先順リスト" (string :tag "番号")))) 556 | 557 | (defcustom jma-forecast-location-week-amedas nil;;"44132" 558 | "アメダス観測所(週間)" 559 | :group 'jma 560 | :type '(choice (string :tag "番号") 561 | (repeat :tag "週間予報区域と対応するリスト" (string :tag "番号")))) 562 | 563 | (defcustom jma-forecast-date-format "%m/%d(%a)" 564 | "日付の形式" 565 | :group 'jma 566 | :type '(choice (string :tag "`format-time-string'の書式") 567 | (function :tag "文字列化関数"))) 568 | 569 | (defun jma-forecast-date-format (date) 570 | (let ((time (jma-date-to-time date))) 571 | (cond 572 | ((functionp jma-forecast-date-format) 573 | (funcall jma-forecast-date-format time)) 574 | ((stringp jma-forecast-date-format) 575 | (format-time-string jma-forecast-date-format time)) 576 | (t "")))) 577 | 578 | (defun jma-forecast-show () 579 | (interactive) 580 | (unless (and jma-forecast-location-office 581 | jma-forecast-location-class10 582 | jma-forecast-location-amedas 583 | jma-forecast-location-week-area 584 | jma-forecast-location-week-amedas) 585 | (call-interactively #'jma-forecast-location-setup)) 586 | (let ((forecast (jma-forecast-get jma-forecast-location-office))) 587 | (message "%s" 588 | (mapconcat 589 | #'identity 590 | (cl-loop for n from 0 to 7 591 | for date = (jma-date-inc-day (jma-date-today) n) 592 | collect 593 | (concat 594 | (jma-forecast-date-format date) 595 | " " 596 | (jma-weather-to-string 597 | (jma-forecast-weather-for-date 598 | forecast 599 | jma-forecast-location-class10 600 | jma-forecast-location-amedas 601 | jma-forecast-location-week-area 602 | jma-forecast-location-week-amedas 603 | date)))) 604 | "\n")))) 605 | 606 | (defun jma-forecast-location-setup (office-code class10-code amedas-code week-area-code week-amedas-code) 607 | "デフォルトの予報地点を設定します。 608 | 609 | 次の変数を変更します。 610 | 611 | `jma-forecast-location-office' 612 | `jma-forecast-location-class10' 613 | `jma-forecast-location-amedas' 614 | `jma-forecast-location-week-area' 615 | `jma-forecast-location-week-amedas' 616 | 617 | " 618 | (interactive 619 | (jma-forecast-area-read)) 620 | (customize-set-variable 'jma-forecast-location-office office-code) 621 | (customize-set-variable 'jma-forecast-location-class10 class10-code) 622 | (customize-set-variable 'jma-forecast-location-amedas amedas-code) 623 | (customize-set-variable 'jma-forecast-location-week-area week-area-code) 624 | (customize-set-variable 'jma-forecast-location-week-amedas week-amedas-code) 625 | (when (y-or-n-p "変更を保存しますか?") 626 | (customize-save-variable 'jma-forecast-location-office office-code) 627 | (customize-save-variable 'jma-forecast-location-class10 class10-code) 628 | (customize-save-variable 'jma-forecast-location-amedas amedas-code) 629 | (customize-save-variable 'jma-forecast-location-week-area week-area-code) 630 | (customize-save-variable 'jma-forecast-location-week-amedas week-amedas-code))) 631 | 632 | ;;;;; diary連携 633 | 634 | (defun jma-diary-weathers (&optional office-code class10-code amedas-code week-area-code week-amedas-code template) 635 | "`date'変数が示す日付の天気予報文字列を返します。 636 | 637 | 予報する場所は次の引数で指定します。 638 | 639 | OFFICE-CODE : 府県予報区 640 | 641 | CLASS10-CODE : 一次細分区域 642 | 643 | AMEDAS-CODE : アメダス観測所(詳細予報で使用) 644 | 645 | WEEK-AREA-CODE : 週間予報区域(府県予報区を必要に応じて多少細分化したもの) 646 | 647 | WEEK-AMEDAS-CODE : アメダス観測所(週間予報で使用) 648 | 649 | 天気予報からデータから文字列への変換にはTEMPLATE引数を使用します。 650 | テンプレートの書き方は`jma-expand-template'関数を参照してください。 651 | 指定しなかった場合、`jma-weather-default-template'変数の値が使われます。" 652 | (with-no-warnings (defvar date)) 653 | (let* ((forecast (jma-forecast-get (or office-code jma-forecast-location-office))) 654 | (weather (jma-forecast-weather-for-date 655 | forecast 656 | (or class10-code jma-forecast-location-class10) 657 | (or amedas-code jma-forecast-location-amedas) 658 | (or week-area-code jma-forecast-location-week-area) 659 | (or week-amedas-code jma-forecast-location-week-amedas) 660 | date))) 661 | (jma-weather-to-string weather template))) 662 | 663 | 664 | (provide 'jma-forecast) 665 | ;;; jma-forecast.el ends here 666 | -------------------------------------------------------------------------------- /docs/how-to-get-jma-forecast.org: -------------------------------------------------------------------------------- 1 | #+TITLE: 気象庁が提供する天気予報データの読み解き方 2 | #+DATE: [2022-02-21 Mon] 3 | #+AUTHOR: AKIYAMA Kouhei 4 | 5 | * 情報の取得先 6 | ** URL一覧 7 | *** JSON 8 | | URL | 格納されている情報 | 9 | |-----------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 10 | | =https://www.jma.go.jp/bosai/forecast/data/forecast/.json= | 天気予報 | 11 | | =https://www.jma.go.jp/bosai/forecast/data/overview_forecast/.json= | 短期天気概況 | 12 | | =https://www.jma.go.jp/bosai/forecast/data/overview_week/.json= | 週間天気概況(複数のofficeをまとめた地方単位。例えば東北地方の概況は宮城県が代表して行う) | 13 | |-----------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 14 | | https://www.jma.go.jp/bosai/common/const/area.json | 各エリア階層(centers, offices, class10s, class15s, class20s)毎のID(コード), 名前, 気象台名, 親階層エリア, 子階層エリア | 15 | | https://www.jma.go.jp/bosai/forecast/const/forecast_area.json | 天気予報で使用するエリア階層情報(office(一つ)に対応するclass10(一つ), class20(一つ), アメダス観測所(複数)) | 16 | | https://www.jma.go.jp/bosai/forecast/const/week_area.json | 週間天気予報で使用するエリア階層情報(office(一つ)に対応する週間天気予報エリア[fn::週間天気予報は天気予報とは異なるエリア単位で行われている。例えば福島県(office=070000)では、天気予報は中通り(070010)、浜通り(070020)、会津(070030)の三地域で行われているが、週間天気予報は中通り・浜通り(week=070100)、会津(week=070030)の二地域で行われる。](複数)) | 17 | | https://www.jma.go.jp/bosai/forecast/const/week_area05.json | 天気予報のエリアから週間天気予報エリアへの対応関係 | 18 | | https://www.jma.go.jp/bosai/forecast/const/week_area_name.json | 週間天気予報エリアの名前 | 19 | | https://www.jma.go.jp/bosai/forecast/const/en_amedas.json | 天気予報で使用するアメダス観測所(気温等の表示に使う)の英語名 | 20 | |-----------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 21 | | https://www.jma.go.jp/bosai/forecast/const/anniversary.json | 祝日の日付 | 22 | |-----------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 23 | | https://www.jma.go.jp/bosai/common/const/class20relm.json | 二次細分区域の緯度経度範囲 | 24 | | https://www.jma.go.jp/bosai/amedas/const/amedastable.json | アメダス観測所リスト | 25 | | https://www.jma.go.jp/bosai/amedas/const/amedas_class20_list.json | 二次細分区域とアメダス観測所の対応リスト | 26 | 27 | *** 画像 28 | | URL | 中身 | 29 | |--------------------------------------------------------------+------------| 30 | | =https://www.jma.go.jp/bosai/forecast/img/.svg= | 天気マーク | 31 | 32 | ** HTML埋め込み定数 33 | いくつかの定数はHTML(https://www.jma.go.jp/bosai/forecast/)内のSCRIPT要素に埋め込まれており、JavaScriptのオブジェクトとして参照できる。 34 | 35 | | プロパティ名 | 中身 | 36 | |-----------------------------+----------------------------------| 37 | | ~Forecast.Const.AREA_FUKEN~ | 地方予報区代表情報 | 38 | | ~Forecast.Const.TELOPS~ | 天気コード | 39 | | ~Forecast.Const.WEEK_AREAS~ | 週間天気予報エリアのローマ字表記 | 40 | 41 | *** 天気コード(weatherCode) 42 | 43 | 118種類が定義されている(2022-02-21現在)。 44 | 45 | #+begin_src js 46 | Forecast.Const.TELOPS = { 47 | //コード:[昼画像,夜画像,?,日本語,英語], 48 | 100:["100.svg","500.svg","100","晴","CLEAR"], 49 | 101:["101.svg","501.svg","100","晴時々曇","PARTLY CLOUDY"], 50 | 102:["102.svg","502.svg","300","晴一時雨","CLEAR, OCCASIONAL SCATTERED SHOWERS"], 51 | 103:["102.svg","502.svg","300","晴時々雨","CLEAR, FREQUENT SCATTERED SHOWERS"], 52 | 104:["104.svg","504.svg","400","晴一時雪","CLEAR, SNOW FLURRIES"], 53 | 105:["104.svg","504.svg","400","晴時々雪","CLEAR, FREQUENT SNOW FLURRIES"], 54 | 106:["102.svg","502.svg","300","晴一時雨か雪","CLEAR, OCCASIONAL SCATTERED SHOWERS OR SNOW FLURRIES"], 55 | 107:["102.svg","502.svg","300","晴時々雨か雪","CLEAR, FREQUENT SCATTERED SHOWERS OR SNOW FLURRIES"], 56 | 108:["102.svg","502.svg","300","晴一時雨か雷雨","CLEAR, OCCASIONAL SCATTERED SHOWERS AND/OR THUNDER"], 57 | 110:["110.svg","510.svg","100","晴後時々曇","CLEAR, PARTLY CLOUDY LATER"], 58 | 111:["110.svg","510.svg","100","晴後曇","CLEAR, CLOUDY LATER"], 59 | 112:["112.svg","512.svg","300","晴後一時雨","CLEAR, OCCASIONAL SCATTERED SHOWERS LATER"], 60 | 113:["112.svg","512.svg","300","晴後時々雨","CLEAR, FREQUENT SCATTERED SHOWERS LATER"], 61 | 114:["112.svg","512.svg","300","晴後雨","CLEAR,RAIN LATER"], 62 | 115:["115.svg","515.svg","400","晴後一時雪","CLEAR, OCCASIONAL SNOW FLURRIES LATER"], 63 | 116:["115.svg","515.svg","400","晴後時々雪","CLEAR, FREQUENT SNOW FLURRIES LATER"], 64 | 117:["115.svg","515.svg","400","晴後雪","CLEAR,SNOW LATER"], 65 | 118:["112.svg","512.svg","300","晴後雨か雪","CLEAR, RAIN OR SNOW LATER"], 66 | 119:["112.svg","512.svg","300","晴後雨か雷雨","CLEAR, RAIN AND/OR THUNDER LATER"], 67 | 120:["102.svg","502.svg","300","晴朝夕一時雨","OCCASIONAL SCATTERED SHOWERS IN THE MORNING AND EVENING, CLEAR DURING THE DAY"], 68 | 121:["102.svg","502.svg","300","晴朝の内一時雨","OCCASIONAL SCATTERED SHOWERS IN THE MORNING, CLEAR DURING THE DAY"], 69 | 122:["112.svg","512.svg","300","晴夕方一時雨","CLEAR, OCCASIONAL SCATTERED SHOWERS IN THE EVENING"], 70 | 123:["100.svg","500.svg","100","晴山沿い雷雨","CLEAR IN THE PLAINS, RAIN AND THUNDER NEAR MOUTAINOUS AREAS"], 71 | 124:["100.svg","500.svg","100","晴山沿い雪","CLEAR IN THE PLAINS, SNOW NEAR MOUTAINOUS AREAS"], 72 | 125:["112.svg","512.svg","300","晴午後は雷雨","CLEAR, RAIN AND THUNDER IN THE AFTERNOON"], 73 | 126:["112.svg","512.svg","300","晴昼頃から雨","CLEAR, RAIN IN THE AFTERNOON"], 74 | 127:["112.svg","512.svg","300","晴夕方から雨","CLEAR, RAIN IN THE EVENING"], 75 | 128:["112.svg","512.svg","300","晴夜は雨","CLEAR, RAIN IN THE NIGHT"], 76 | 130:["100.svg","500.svg","100","朝の内霧後晴","FOG IN THE MORNING, CLEAR LATER"], 77 | 131:["100.svg","500.svg","100","晴明け方霧","FOG AROUND DAWN, CLEAR LATER"], 78 | 132:["101.svg","501.svg","100","晴朝夕曇","CLOUDY IN THE MORNING AND EVENING, CLEAR DURING THE DAY"], 79 | 140:["102.svg","502.svg","300","晴時々雨で雷を伴う","CLEAR, FREQUENT SCATTERED SHOWERS AND THUNDER"], 80 | 160:["104.svg","504.svg","400","晴一時雪か雨","CLEAR, SNOW FLURRIES OR OCCASIONAL SCATTERED SHOWERS"], 81 | 170:["104.svg","504.svg","400","晴時々雪か雨","CLEAR, FREQUENT SNOW FLURRIES OR SCATTERED SHOWERS"], 82 | 181:["115.svg","515.svg","400","晴後雪か雨","CLEAR, SNOW OR RAIN LATER"], 83 | 200:["200.svg","200.svg","200","曇","CLOUDY"], 84 | 201:["201.svg","601.svg","200","曇時々晴","MOSTLY CLOUDY"], 85 | 202:["202.svg","202.svg","300","曇一時雨","CLOUDY, OCCASIONAL SCATTERED SHOWERS"], 86 | 203:["202.svg","202.svg","300","曇時々雨","CLOUDY, FREQUENT SCATTERED SHOWERS"], 87 | 204:["204.svg","204.svg","400","曇一時雪","CLOUDY, OCCASIONAL SNOW FLURRIES"], 88 | 205:["204.svg","204.svg","400","曇時々雪","CLOUDY FREQUENT SNOW FLURRIES"], 89 | 206:["202.svg","202.svg","300","曇一時雨か雪","CLOUDY, OCCASIONAL SCATTERED SHOWERS OR SNOW FLURRIES"], 90 | 207:["202.svg","202.svg","300","曇時々雨か雪","CLOUDY, FREQUENT SCCATERED SHOWERS OR SNOW FLURRIES"], 91 | 208:["202.svg","202.svg","300","曇一時雨か雷雨","CLOUDY, OCCASIONAL SCATTERED SHOWERS AND/OR THUNDER"], 92 | 209:["200.svg","200.svg","200","霧","FOG"], 93 | 210:["210.svg","610.svg","200","曇後時々晴","CLOUDY, PARTLY CLOUDY LATER"], 94 | 211:["210.svg","610.svg","200","曇後晴","CLOUDY, CLEAR LATER"], 95 | 212:["212.svg","212.svg","300","曇後一時雨","CLOUDY, OCCASIONAL SCATTERED SHOWERS LATER"], 96 | 213:["212.svg","212.svg","300","曇後時々雨","CLOUDY, FREQUENT SCATTERED SHOWERS LATER"], 97 | 214:["212.svg","212.svg","300","曇後雨","CLOUDY, RAIN LATER"], 98 | 215:["215.svg","215.svg","400","曇後一時雪","CLOUDY, SNOW FLURRIES LATER"], 99 | 216:["215.svg","215.svg","400","曇後時々雪","CLOUDY, FREQUENT SNOW FLURRIES LATER"], 100 | 217:["215.svg","215.svg","400","曇後雪","CLOUDY, SNOW LATER"], 101 | 218:["212.svg","212.svg","300","曇後雨か雪","CLOUDY, RAIN OR SNOW LATER"], 102 | 219:["212.svg","212.svg","300","曇後雨か雷雨","CLOUDY, RAIN AND/OR THUNDER LATER"], 103 | 220:["202.svg","202.svg","300","曇朝夕一時雨","OCCASIONAL SCCATERED SHOWERS IN THE MORNING AND EVENING, CLOUDY DURING THE DAY"], 104 | 221:["202.svg","202.svg","300","曇朝の内一時雨","CLOUDY OCCASIONAL SCCATERED SHOWERS IN THE MORNING"], 105 | 222:["212.svg","212.svg","300","曇夕方一時雨","CLOUDY, OCCASIONAL SCCATERED SHOWERS IN THE EVENING"], 106 | 223:["201.svg","601.svg","200","曇日中時々晴","CLOUDY IN THE MORNING AND EVENING, PARTLY CLOUDY DURING THE DAY,"], 107 | 224:["212.svg","212.svg","300","曇昼頃から雨","CLOUDY, RAIN IN THE AFTERNOON"], 108 | 225:["212.svg","212.svg","300","曇夕方から雨","CLOUDY, RAIN IN THE EVENING"], 109 | 226:["212.svg","212.svg","300","曇夜は雨","CLOUDY, RAIN IN THE NIGHT"], 110 | 228:["215.svg","215.svg","400","曇昼頃から雪","CLOUDY, SNOW IN THE AFTERNOON"], 111 | 229:["215.svg","215.svg","400","曇夕方から雪","CLOUDY, SNOW IN THE EVENING"], 112 | 230:["215.svg","215.svg","400","曇夜は雪","CLOUDY, SNOW IN THE NIGHT"], 113 | 231:["200.svg","200.svg","200","曇海上海岸は霧か霧雨","CLOUDY, FOG OR DRIZZLING ON THE SEA AND NEAR SEASHORE"], 114 | 240:["202.svg","202.svg","300","曇時々雨で雷を伴う","CLOUDY, FREQUENT SCCATERED SHOWERS AND THUNDER"], 115 | 250:["204.svg","204.svg","400","曇時々雪で雷を伴う","CLOUDY, FREQUENT SNOW AND THUNDER"], 116 | 260:["204.svg","204.svg","400","曇一時雪か雨","CLOUDY, SNOW FLURRIES OR OCCASIONAL SCATTERED SHOWERS"], 117 | 270:["204.svg","204.svg","400","曇時々雪か雨","CLOUDY, FREQUENT SNOW FLURRIES OR SCATTERED SHOWERS"], 118 | 281:["215.svg","215.svg","400","曇後雪か雨","CLOUDY, SNOW OR RAIN LATER"], 119 | 300:["300.svg","300.svg","300","雨","RAIN"], 120 | 301:["301.svg","701.svg","300","雨時々晴","RAIN, PARTLY CLOUDY"], 121 | 302:["302.svg","302.svg","300","雨時々止む","SHOWERS THROUGHOUT THE DAY"], 122 | 303:["303.svg","303.svg","400","雨時々雪","RAIN,FREQUENT SNOW FLURRIES"], 123 | 304:["300.svg","300.svg","300","雨か雪","RAINORSNOW"], 124 | 306:["300.svg","300.svg","300","大雨","HEAVYRAIN"], 125 | 308:["308.svg","308.svg","300","雨で暴風を伴う","RAINSTORM"], 126 | 309:["303.svg","303.svg","400","雨一時雪","RAIN,OCCASIONAL SNOW"], 127 | 311:["311.svg","711.svg","300","雨後晴","RAIN,CLEAR LATER"], 128 | 313:["313.svg","313.svg","300","雨後曇","RAIN,CLOUDY LATER"], 129 | 314:["314.svg","314.svg","400","雨後時々雪","RAIN, FREQUENT SNOW FLURRIES LATER"], 130 | 315:["314.svg","314.svg","400","雨後雪","RAIN,SNOW LATER"], 131 | 316:["311.svg","711.svg","300","雨か雪後晴","RAIN OR SNOW, CLEAR LATER"], 132 | 317:["313.svg","313.svg","300","雨か雪後曇","RAIN OR SNOW, CLOUDY LATER"], 133 | 320:["311.svg","711.svg","300","朝の内雨後晴","RAIN IN THE MORNING, CLEAR LATER"], 134 | 321:["313.svg","313.svg","300","朝の内雨後曇","RAIN IN THE MORNING, CLOUDY LATER"], 135 | 322:["303.svg","303.svg","400","雨朝晩一時雪","OCCASIONAL SNOW IN THE MORNING AND EVENING, RAIN DURING THE DAY"], 136 | 323:["311.svg","711.svg","300","雨昼頃から晴","RAIN, CLEAR IN THE AFTERNOON"], 137 | 324:["311.svg","711.svg","300","雨夕方から晴","RAIN, CLEAR IN THE EVENING"], 138 | 325:["311.svg","711.svg","300","雨夜は晴","RAIN, CLEAR IN THE NIGHT"], 139 | 326:["314.svg","314.svg","400","雨夕方から雪","RAIN, SNOW IN THE EVENING"], 140 | 327:["314.svg","314.svg","400","雨夜は雪","RAIN,SNOW IN THE NIGHT"], 141 | 328:["300.svg","300.svg","300","雨一時強く降る","RAIN, EXPECT OCCASIONAL HEAVY RAINFALL"], 142 | 329:["300.svg","300.svg","300","雨一時みぞれ","RAIN, OCCASIONAL SLEET"], 143 | 340:["400.svg","400.svg","400","雪か雨","SNOWORRAIN"], 144 | 350:["300.svg","300.svg","300","雨で雷を伴う","RAIN AND THUNDER"], 145 | 361:["411.svg","811.svg","400","雪か雨後晴","SNOW OR RAIN, CLEAR LATER"], 146 | 371:["413.svg","413.svg","400","雪か雨後曇","SNOW OR RAIN, CLOUDY LATER"], 147 | 400:["400.svg","400.svg","400","雪","SNOW"], 148 | 401:["401.svg","801.svg","400","雪時々晴","SNOW, FREQUENT CLEAR"], 149 | 402:["402.svg","402.svg","400","雪時々止む","SNOWTHROUGHOUT THE DAY"], 150 | 403:["403.svg","403.svg","400","雪時々雨","SNOW,FREQUENT SCCATERED SHOWERS"], 151 | 405:["400.svg","400.svg","400","大雪","HEAVYSNOW"], 152 | 406:["406.svg","406.svg","400","風雪強い","SNOWSTORM"], 153 | 407:["406.svg","406.svg","400","暴風雪","HEAVYSNOWSTORM"], 154 | 409:["403.svg","403.svg","400","雪一時雨","SNOW, OCCASIONAL SCCATERED SHOWERS"], 155 | 411:["411.svg","811.svg","400","雪後晴","SNOW,CLEAR LATER"], 156 | 413:["413.svg","413.svg","400","雪後曇","SNOW,CLOUDY LATER"], 157 | 414:["414.svg","414.svg","400","雪後雨","SNOW,RAIN LATER"], 158 | 420:["411.svg","811.svg","400","朝の内雪後晴","SNOW IN THE MORNING, CLEAR LATER"], 159 | 421:["413.svg","413.svg","400","朝の内雪後曇","SNOW IN THE MORNING, CLOUDY LATER"], 160 | 422:["414.svg","414.svg","400","雪昼頃から雨","SNOW, RAIN IN THE AFTERNOON"], 161 | 423:["414.svg","414.svg","400","雪夕方から雨","SNOW, RAIN IN THE EVENING"], 162 | 425:["400.svg","400.svg","400","雪一時強く降る","SNOW, EXPECT OCCASIONAL HEAVY SNOWFALL"], 163 | 426:["400.svg","400.svg","400","雪後みぞれ","SNOW, SLEET LATER"], 164 | 427:["400.svg","400.svg","400","雪一時みぞれ","SNOW, OCCASIONAL SLEET"], 165 | 450:["400.svg","400.svg","400","雪で雷を伴う","SNOW AND THUNDER"]} 166 | #+end_src 167 | 168 | *** 地方予報区代表情報 169 | 170 | 同じ地方予報区に属する府県予報区の中で、代表となる府県予報区の情報。 171 | 172 | #+begin_src js 173 | Forecast.Const.AREA_FUKEN=[ 174 | //北海道地方 175 | {center:"016000",offices:["016000","011000","013000","014030","014100","015000","012000","017000"]}, 176 | //東北地方 177 | {center:"040000",offices:["040000","060000","070000","020000","050000","030000"]}, 178 | //関東甲信越地方 179 | {center:"130000",offices:["130000","120000","140000","190000","090000","100000","110000","080000","200000"]}, 180 | // 北陸地方 181 | {center:"150000",offices:["150000","170000","180000","160000"]}, 182 | // 東海地方 183 | {center:"230000",offices:["230000","240000","220000","210000"]}, 184 | // 近畿地方 185 | {center:"270000",offices:["270000","300000","260000","250000","280000","290000"]}, 186 | // 中国地方(山口県を除く) 187 | {center:"340000",offices:["340000","310000","330000","320000"]}, 188 | // 四国地方 189 | {center:"370000",offices:["370000","380000","360000","390000"]}, 190 | // 九州北部地方(山口県を含む) 191 | {center:"400000",offices:["400000","440000","410000","430000","420000","350000"]}, 192 | // 九州南部・奄美地方 193 | {center:"460100",offices:["460100","450000","460040"]}, 194 | // 沖縄地方 195 | {center:"471000",offices:["471000","473000","474000","472000"]} 196 | ] 197 | #+end_src 198 | 199 | centerはarea.jsonのcentersコードではなくofficesコードである点に注意。地方を代表するoffice(府県予報区)を指す。 200 | 201 | 週間天気概況は地方を代表する一つの府県予報区(office)のみが発表する。例えば福島県(office=070000)の週間天気概況は東北地方のcenterである宮城県(office=040000)が代表して行う。URLは https://www.jma.go.jp/bosai/forecast/data/overview_week/070000.json (Not Found)ではなく https://www.jma.go.jp/bosai/forecast/data/overview_week/040000.json となる。 202 | 203 | 同じ情報は https://www.jma.go.jp/bosai/common/const/area.json から求めることはできるが、気象台名(officeName)を元に検索しなければならない。 204 | 205 | *** 週間天気予報エリアのローマ字表記 206 | 207 | 91個(2022-02-21現在) 208 | 209 | #+begin_src js 210 | Forecast.Const.WEEK_AREAS = { 211 | "011000":"Soya Region", 212 | "012000":"Kamikawa Rumoi Region", 213 | ... 214 | 473e3:"Miyakojima Region", 215 | 474e3:"Yaeyama Region"} 216 | #+end_src 217 | 218 | https://www.jma.go.jp/bosai/forecast/const/week_area_name.json にもほぼ同じデータがあるので不要(Soya RegionがSoyaになっているなど表記に若干の違いがある)。 219 | 220 | * 場所の情報 221 | ** 発表区域 222 | 223 | 発表区域の情報は次のURLから取得できる。 224 | 225 | https://www.jma.go.jp/bosai/common/const/area.json 226 | 227 | トップレベルオブジェクトのプロパティ名と発表区域との対応関係は次表の通り。 228 | 229 | | プロパティ | 階層 | 230 | |------------+------------------------| 231 | | centers | 地方予報区(11区) | 232 | | offices | 府県予報区(58区) | 233 | | class10s | 一次細分区域(142区) | 234 | | class15s | 市町村等をまとめた地域 | 235 | | class20s | 二次細分区域 | 236 | 237 | (参考: [[https://www.jma.go.jp/jma/kishou/know/saibun/index.html][気象庁 | 気象警報・注意報や天気予報の発表区域]]) 238 | 239 | 日本全国を5段階の階層で分割している。各階層の区域を表すオブジェクトにはparentプロパティとchildrenプロパティがあり、上下の階層との関係が示されている。 240 | 241 | ** アメダス観測所 242 | 243 | 気温や降水量はアメダス観測所の地点のものが示されている。アメダス観測所は観測所番号で識別される。 244 | 245 | (参考: [[https://www.jma.go.jp/jma/kishou/know/amedas/kaisetsu.html][気象庁 | アメダス]]) 246 | 247 | アメダス観測所の一般的な情報は次のURL等から求められる。 248 | 249 | - https://www.jma.go.jp/bosai/amedas/const/amedastable.json 250 | - https://www.jma.go.jp/bosai/amedas/const/amedas_class20_list.json 251 | 252 | ** 府県天気予報のアメダス観測所 253 | 254 | 天気予報は一次細分区域毎に発表されるが、気温や降水量はアメダス観測所の観測所番号を用いて発表される。一次細分区域とアメダス観測所との対応関係は次のURLから取得できる。 255 | 256 | https://www.jma.go.jp/bosai/forecast/const/forecast_area.json 257 | 258 | ** 府県週間天気予報 259 | 260 | 府県週間天気予報は原則的には府県予報区毎に発表されることになっているが、実際には地域の地形的・季節的状況に合わせて細分化されている(参考: [[https://www.jma.go.jp/jma/kishou/know/kurashi/shukan.html][気象庁|週間天気予報の解説]])。これは一次細分区域とは異なる。この文書では便宜上週間予報区域と呼んでいる。 261 | 262 | 府県週間天気予報の予報区に関する情報は次のURLから取得できる。 263 | 264 | - https://www.jma.go.jp/bosai/forecast/const/week_area.json 265 | - https://www.jma.go.jp/bosai/forecast/const/week_area05.json 266 | - https://www.jma.go.jp/bosai/forecast/const/week_area_name.json 267 | 268 | ** 詳細説明 269 | 270 | より詳しい説明は[[file:how-to-get-jma-area-info.org][気象庁データにおける場所に関する情報の扱い方]]を参照のこと。 271 | 272 | * 天気予報データの読み解き方 273 | 274 | 天気予報のデータは =https://www.jma.go.jp/bosai/forecast/data/forecast/.json= から取得できる。 == は府県予報区のコード。 275 | 276 | 例えば福島県のデータを取得するには次のようにする([[https://github.com/misohena/el-jma][el-jma]]を使用)。 277 | 278 | #+begin_src elisp 279 | (jma-forecast-get "070000") 280 | #+end_src 281 | 282 | 結果は次の通り。 283 | 284 | #+begin_src elisp 285 | ;; 発表の配列(おそらく固定長) 286 | [ 287 | ;; 一つ目は府県天気予報(毎日5時・11時・17時、他必要に応じて発表) 288 | ((publishingOffice . "福島地方気象台") 289 | (reportDatetime . "2022-02-21T05:00:00+09:00") ;;朝5時の定期発表 290 | (timeSeries 291 | . [ 292 | ;; 天気、風、波(海のある区域のみ) 293 | ;; 日単位(2~3日分)。 294 | ((timeDefines . ["2022-02-21T05:00:00+09:00" "2022-02-22T00:00:00+09:00"]) 295 | (areas 296 | . [ 297 | ;; 一次細分区域(class10s)単位 298 | ((area (name . "中通り") (code . "070010")) 299 | (weatherCodes . ["205" "201"]) 300 | (weathers . ["くもり 昼過ぎ まで 時々 雪 で ふぶく" "くもり 時々 晴れ 所により 雪"]) 301 | (winds . ["西の風 やや強く" "西の風 日中 北西の風"])) 302 | 303 | ((area (name . "浜通り") (code . "070020")) 304 | (weatherCodes . ["101" "101"]) 305 | (weathers . ["晴れ 時々 くもり 所により 昼前 まで 雪" "晴れ 時々 くもり 所により 昼前 から 雪"]) 306 | (winds . ["西の風 やや強く 海上 では 西の風 強く" "北西の風 海上 では はじめ 西の風 強く"]) 307 | (waves . ["3メートル 後 2.5メートル" "2メートル"])) 308 | 309 | ((area (name . "会津") (code . "070030")) 310 | (weatherCodes . ["400" "400"]) 311 | (weathers . ["雪 で ふぶく" "雪"]) 312 | (winds . ["西の風 日中 やや強く" "西の風"]))]) 313 | ) 314 | ;; 降水確率 315 | ;; 6時間単位(発表時点で過ぎた時刻は含まれない)。 316 | ((timeDefines . ["2022-02-21T06:00:00+09:00" "2022-02-21T12:00:00+09:00" "2022-02-21T18:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-22T06:00:00+09:00" "2022-02-22T12:00:00+09:00" "2022-02-22T18:00:00+09:00"]) 317 | (areas 318 | . [ 319 | ;; 一次細分区域(class10s)単位 320 | ((area (name . "中通り") (code . "070010")) (pops . ["30" "40" "20" "20" "20" "30" "30"])) 321 | ((area (name . "浜通り") (code . "070020")) (pops . ["20" "10" "10" "10" "20" "20" "20"])) 322 | ((area (name . "会津") (code . "070030")) (pops . ["80" "70" "70" "60" "50" "60" "70"])) 323 | ]) 324 | ) 325 | ;; 最低気温、最高気温 326 | ;; 時刻には厳密な意味は無さそう。二つの要素がペアになっていて、最初の要素が最低気温、二つ目の要素が最高気温となる。 327 | ;; 発表当日の最低気温は基本的に無効。Webサイトでも必ず「-」となっている。時刻はなぜか9時を指しており、値は最高気温と同じになっている。 328 | ;; 5時、11時の発表には当日・翌日の4要素が含まれており、17時発表には翌日の2要素のみ含まれている。その他予定時刻以外の発表については不明。 329 | ((timeDefines . ["2022-02-21T09:00:00+09:00" "2022-02-21T00:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-22T09:00:00+09:00"]) 330 | (areas 331 | . [ 332 | ;; アメダス観測所(amedas)単位 333 | ;; 観測所がどの一次細分区域に属するかは https://www.jma.go.jp/bosai/forecast/const/forecast_area.json から求められる。 334 | ((area (name . "福島") (code . "36127")) (temps . ["1" "1" "-2" "2"])) 335 | ((area (name . "小名浜") (code . "36846")) (temps . ["4" "4" "-3" "6"])) 336 | ((area (name . "若松") (code . "36361")) (temps . ["1" "1" "-3" "1"])) 337 | ((area (name . "白河") (code . "36667")) (temps . ["1" "1" "-4" "3"])) 338 | ((area (name . "郡山") (code . "36476")) (temps . ["0" "0" "-4" "2"])) 339 | ((area (name . "相馬") (code . "36151")) (temps . ["2" "2" "-4" "3"])) 340 | ((area (name . "田島") (code . "36641")) (temps . ["-4" "-4" "-7" "-2"])) 341 | ]) 342 | ) 343 | ])) 344 | 345 | ;; 二つ目は府県週間天気予報(毎日11時と17時に発表) 346 | ;; 参考: https://www.jma.go.jp/jma/kishou/know/kurashi/shukan.html : 気象庁|週間天気予報の解説 347 | ((publishingOffice . "福島地方気象台") 348 | (reportDatetime . "2022-02-20T17:00:00+09:00") 349 | (timeSeries 350 | . [ 351 | ((timeDefines . ["2022-02-21T00:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00"]) 352 | (areas 353 | . [ 354 | ;; 週間予報区域単位(原則として府県予報区単位だが、地形や季節によって細分化している) 355 | ((area (name . "中通り・浜通り") (code . "070100")) (weatherCodes . ["201" "200" "201" "101" "101" "101" "201"]) (pops . ["" "40" "20" "20" "20" "20" "30"]) (reliabilities . ["" "" "A" "A" "A" "A" "A"])) 356 | ((area (name . "会津") (code . "070030")) (weatherCodes . ["400" "402" "205" "204" "200" "200" "206"]) (pops . ["" "80" "70" "50" "40" "30" "60"]) (reliabilities . ["" "" "A" "C" "B" "B" "C"])) 357 | ]) 358 | ) 359 | ((timeDefines . ["2022-02-21T00:00:00+09:00" "2022-02-22T00:00:00+09:00" "2022-02-23T00:00:00+09:00" "2022-02-24T00:00:00+09:00" "2022-02-25T00:00:00+09:00" "2022-02-26T00:00:00+09:00" "2022-02-27T00:00:00+09:00"]) 360 | (areas 361 | . [ 362 | ;; アメダス観測所(amedas)単位 363 | ;; 観測所がどの週間予報区域に属するかは https://www.jma.go.jp/bosai/forecast/const/week_area.json から求められる。 364 | ((area (name . "福島") (code . "36127")) 365 | (tempsMin . ["" "-2" "-3" "-2" "2" "1" "2"]) 366 | (tempsMinUpper . ["" "-1" "-2" "0" "3" "3" "3"]) 367 | (tempsMinLower . ["" "-5" "-5" "-4" "0" "-4" "-3"]) 368 | (tempsMax . ["" "3" "2" "6" "9" "13" "11"]) 369 | (tempsMaxUpper . ["" "5" "4" "8" "12" "15" "15"]) 370 | (tempsMaxLower . ["" "1" "0" "3" "7" "10" "9"])) 371 | 372 | ((area (name . "若松") (code . "36361")) 373 | (tempsMin . ["" "-3" "-4" "-3" "-1" "-3" "-2"]) 374 | (tempsMinUpper . ["" "-2" "-3" "-2" "1" "-1" "1"]) 375 | (tempsMinLower . ["" "-9" "-6" "-5" "-6" "-9" "-7"]) 376 | (tempsMax . ["" "1" "0" "2" "6" "9" "8"]) 377 | (tempsMaxUpper . ["" "3" "2" "4" "8" "12" "11"]) 378 | (tempsMaxLower . ["" "-2" "-3" "-1" "4" "7" "6"])) 379 | ]) 380 | ) 381 | ]) 382 | ;; 気温の平年値 383 | (tempAverage (areas . [((area (name . "福島") (code . "36127")) (min . "-0.7") (max . "8.1")) ((area (name . "若松") (code . "36361")) (min . "-2.8") (max . "5.2"))])) 384 | ;; 降水量の平年値 385 | (precipAverage (areas . [((area (name . "福島") (code . "36127")) (min . "3.4") (max . "14.0")) ((area (name . "若松") (code . "36361")) (min . "9.5") (max . "21.1"))])) 386 | ) 387 | ] 388 | #+end_src 389 | 390 | これが実際にWebサイト上でどのように表示されるかは https://www.jma.go.jp/bosai/forecast/#area_type=offices&area_code=070000 から確認できる。 391 | 392 | 情報は複数の地点の情報を寄せ集めた状態で提供されているので、特定の地点の天気予報を求めるには次のエリアコードをあらかじめ決めておく必要がある。 393 | 394 | - 府県予報区コード : どの府県予報区の天気予報をダウンロードするか 395 | - 一次細分区域コード : どの一次細分区域の天気予報(明後日までの詳細)を取り出すか 396 | - アメダス観測所番号 : どのアメダス観測所の最低気温・最高気温を取り出すか 397 | - 週間予報区域コード : どの週間予報区域の週間天気予報(翌日から7日間)を取り出すか 398 | - アメダス観測所番号(週間予報用) : どのアメダス観測所の週間の最低気温・最高気温を取り出すか 399 | --------------------------------------------------------------------------------