MENU

    C# .NETで気象庁のアメダスを取得する

    computer program language text

    私は最近プログラミングにはまっていて、よくJSONデータを扱います。

    C# .NETでJSONをデシリアライズするときはいつもこれを使っていました。

    Newtonsoft.Json.JsonConvert.DeserializeObject<クラス>(JSONデータ);

    しかし、これでは対応できないようなデータがあります。それが、気象庁のアメダスデータです。

    {
    {
      "11001": {
        "temp": [
          -1.1,
          0
        ],
        "humidity": [
          100,
          0
        ],
        "snow1h": [
          0,
          null
        ],
        "snow6h": [
          0,
          null
        ],
        "snow12h": [
          0,
          null
        ],
        "snow24h": [
          0,
          null
        ],
        "sun10m": [
          0,
          0
        ],
        "sun1h": [
          0.0,
          0
        ],
        "precipitation10m": [
          0.0,
          0
        ],
        "precipitation1h": [
          0.0,
          0
        ],
        "precipitation3h": [
          0.0,
          0
        ],
        "precipitation24h": [
          0.5,
          0
        ],
        "windDirection": [
          4,
          0
        ],
        "wind": [
          1.2,
          0
        ]
      }
    }

    ※データは、”https://www.jma.go.jp/bosai/amedas/data/map/”最終更新時刻(yyyyMMddHHmmss)”.json”でアクセスすることが可能です。最終更新時刻はhttps://www.jma.go.jp/bosai/amedas/data/latest_time.txtで取得できます。

    観測点によってJSONのKeyが異なるのでクラスにするとえらいことになります。

    えらいことになってる図

    これでは観測点の情報を処理するときとっても面倒ですよね。

    var amedas = Newtonsoft.Json.JsonConvert.DeserializeObject<クラス>(JSONデータ);
    List<double> wind = new();
    wind.Add(amedas._11001.wind[0]);
    wind.Add(amedas._11016.wind[0]);
    wind.Add(amedas._11046.wind[0]);
    wind.Add(amedas._11061.wind[0]);
    続く....

    そこで、keyが定まっていないJSONをデシリアライズする方法について書こうと思います。

    あらすじ

    どうやってkeyが定まっていないJSONをデシリアライズするのか

    Newtonsoft.JsonでJSONをデシリアライズする方法はJsonConvert.DeserializeObject以外にもあります。それが、JObject.Parseです。

    使い方

    JObject amedas = JObject.Parse(JSONデータ);
    パースした後のamedasの中身

    これをうまく使うことによってデシリアライズしていきます。

    情報を取得

    まずは情報の取得から行きましょう。

    string latest_Time = await client.GetStringAsync("https://www.jma.go.jp/bosai/amedas/data/latest_time.txt");
    
    DateTime dateTime = DateTime.Parse(latest_Time);

    latest_time.txtをDateTimeにします。

    string url = "https://www.jma.go.jp/bosai/amedas/data/map/" + dateTime.ToString("yyyyMMddHHmmss") + ".json";
    
    string amedas_Data = await client.GetStringAsync(url);

    最終更新時刻をURLに入れて、GetStringAsyncでJSONデータを取得します。

    これでJSONデータの取得は完了です。

    デシリアライズ

    次に、本命のデシリアライズをしていきます。今回は風速のみを取得していきます。(ほかの部分でも使用できるよう、クラスにはそのほかのものも入れています。)

    クラス
    JObject amedas = JObject.Parse(amedas_Data);
    var amedas_List = new List<JMA_amedas>();

    JObjectでパースした後、情報を入れるリストを作ります。

    foreach (var pair in amedas)
    {
    }

    このforeachのpairは一つの観測点の情報です。

    JValue? wind_content = null;
    wind_content = (JValue?)pair.Value?[key: "wind"]?[0];

    JValueを新たに作り、その中にwindの中身を入れます。この時、観測点によっては風速の情報がないので、?演算子をつけておきましょう。

    ※pairのKeyはpair.Key、Valueはpair.Valueとなっています。Valueは観測点の情報です。

    if (wind_content?.Value != null)
    {
          amedas_List.Add(new());
          amedas_List[amedas_List.Count - 1].id = Convert.ToInt32(pair.Key);
          amedas_List[amedas_List.Count - 1].wind = (double)wind_content;
    }

    もし、valueがnullでないならアメダスのリストに新しいものを追加して、末尾のidにpairのKey、windにwind_contentを入れます。

    最後に、風速順にしたいので、OrderByDescendingを使います。

    var amedas_Ranking = amedas_List.OrderByDescending(x => x.wind).ToList();
    foreach(var content in amedas_Ranking)
    {
          Console.WriteLine(content.id);
          Console.WriteLine(content.wind);
    }

    完成です!実行すると、このようになります。

    風速順になって、しっかり取得できていました。

    なお、今回のサンプルコードはGitHubに置いておきます。

    LifeOTE/JMASample: 気象庁のサイトからアメダスを取得するサンプル。 (github.com)

    今回はここまでです。最後までご覧いただきありがとうございました。

    よかったらシェアしてね!
    • URLをコピーしました!

    コメント

    コメントする

    CAPTCHA


    あらすじ