2023/12/08

つないでみよう:#4)天気予報取得のサンプルコード

Web 系アプリ開発のど素人がチャレンジする WebAPI 連携日記の第 4 回です。

前回に引き続き、気象庁の天気予報に関してです。前回は、Web サイトの仕組みやデータの取得方法、構造について整理しました。今回はその情報を使用して、ノーツで天気予報を取得するサンプルを紹介します。


サンプルプログラム

指定したエリアの天気予報を取得し、メッセージボックスで表示するだけの単純なエージェントです。メインルーチンは次の通りです。

Option Declare
Private xns As NotesSession

Sub Initialize
   Dim sAreaCD As String
   Dim vWeather As Variant

   Set xns = New NotesSession

   '大阪の天気予報を取得
   sAreaCD = "270000"
   Call xGetForecast(sAreaCD, vWeather)


   MsgBox Join(vWeather, Chr(10)), 64, "大阪の天気予報"
End Sub

エリアコードを指定して天気予報を取得する関数をコールします。戻り値の vWeather は文字列型の配列となる前提で、それをメッセージボックスで改行区切りで表示します。


天気予報の取得

天気予報を取得する関数は次の通りです。

引数で指定したエリアコードを使用してコールする URL を生成してから HTTP リクエストを実行しています。今回の API では、メソッドは Get となります。また、レスポンスは JSON を前提としています。

Function xGetForecast(ByVal vsAreaCD As String, rvWeather As Variant)
   Dim sURL As String
   Dim http As NotesHTTPRequest
   Dim jnav As NotesJSONNavigator
   Dim je3 As NotesJSONElement

   '天気予報の JSON を取得
   sURL = "https://www.jma.go.jp/bosai/forecast/data/forecast/" & vsAreaCD & ".json"
   Set http = xns.CreateHttpRequest()
   http.PreferJSONNavigator = True

   Set jnav = http.Get(sURL)

   '明後日までの天気予報の取得
   Set je3 = jnav.GetFirstElement()
   Call xGetForecast_3Days(je3, rvWeather)

End Function

返される JSON には、2つのオブジェクトがあり、明後日までの天気予報と週間天気予報となっていました。今回は、明後日までの天気予報を取得するので、1つ目のオブジェクト(エレメント)を取得しています。

実際に天気予報を取得するプログラムは、サブ関数 xGetForecast_3Days で行います。


明後日までの天気予報の取得

この部分は JSON の構造が少し複雑なので、取得したい天気予報(weathers)までの構造を改めて掲載します。

取得までの流れとしては、まず timeSeries を取得して、次に areas を取得、その中に目的の weathers が存在します。それぞれが配列の構造となっているので、段階を踏んで取得する必要があります。

具体的なプログラムは下記の通りですが、各段階の処理は理解しやすいようにコードをそろえるようにしました。流れとしては、

  1. エレメントを名称(キー)で検索し、NotesJSONElement オブジェクトとして取得
  2. 配列であるか確認
  3. 1つ目の要素を取得し、NotesJSONObject オブジェクトとして取得

としています。

Function xGetForecast_3Days(vje3Days As NotesJSONElement, rvWeather As Variant)
   Dim jeTmp As NotesJSONElement
   Dim jobjTmp As NotesJSONObject
   Dim jaTmp As NotesJSONArray

   Set jobjTmp = vje3Days.Value
   Set jeTmp = jobjTmp.GetElementByName("timeSeries")
   If jeTmp.Type = Jsonelem_type_array Then

      '配列の1つ目が天気予報
      Set jaTmp = jeTmp.Value
      Set jeTmp = jaTmp.GetFirstElement()
      Set jobjTmp = jeTmp.Value


      'エリア(areas)を取得
      Set jeTmp = jobjTmp.GetElementByName("areas")
      If jeTmp.Type = Jsonelem_type_array Then

         '配列だが1つしか要素がない
         Set jaTmp = jeTmp.Value
         Set jeTmp = jaTmp.GetFirstElement()
         Set jobjTmp = jeTmp.Value


         '天気
         Set jeTmp = jobjTmp.GetElementByName("weathers")
         rvWeather = xGetArray_String(jeTmp)
      End If
   End If
End Function

目的のオブジェクト weathers を取得した後は、その中身を配列に変換する関数を xGetArray_String をコールしています。

Function xGetArray_String(vje As NotesJSONElement) As Variant
   Dim jaVal As NotesJSONArray
   Dim jeVal As NotesJSONElement
   Dim i As Integer
   Dim vTmp As Variant

   If vje.Type = Jsonelem_type_array Then
      Set jaVal = vje.Value
      ReDim vTmp(jaVal.Size-1)
      For i = 1 To jaVal.Size
         Set jeVal = jaVal.Getnthelement(i)
         vTmp(i-1) = CStr(jeVal.Value)
      Next
   End If

   xGetArray_String = vTmp
End Function


まとめ

実行すると次のように、取得した天気予報を表示します。

サンプルがシンプルになるよう、天気予報をテキストで取得しているだけですが、このサンプルを応用すれば、降水確率や週間天気予報なども取得できるようになりますね。


今回は、気象庁の Web サイトから天気予報を取得するサンプルを紹介しました。

プログラム的には、

  1. HTTP リクエストを送信
  2. レスポンスが JSON となっている
  3. JSON を解析し、データを利用する

と、一般的な WebAPI と同じでしたね。このような背景から『つないでみよう』の連載で取り上げました。


前回 連載:つないでみよう 次回

0 件のコメント:

コメントを投稿