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


あらすじ