天気予報APIからリアル天気情報を取得する
本プログラムは、C#とWindows Formsを用いて開発されたシンプルな天気予報チェックアプリケーションです。ユーザーがコンボボックスから都市を選択すると、指定された都市の天気情報を取得し、アプリケーション上に表示します。天気情報は「気象庁の非公式API」を利用して取得します。
フリーの天気リアル情報サーバ(JSONで取得可能)
自分で、頑張って取得アプリを実現してみましょう!!
NewtonソフトのJsonコンバータを採用しているコードからSystem.Text.Jsonへの更新作業手順概要をベースにしてます
Newtonソフト版のJsonコンバータでは、同じコードになりませんが地域コードをサーバのものを採用、分析するためのクラスをサーバのものに合わせることで対応できます
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Windows.Forms;
namespace WeatherChecker
{
public partial class Form1 : Form
{
// 都市名とコードを紐付けるDictionary
private readonly Dictionary<string, string> cityNames;
public Form1()
{
InitializeComponent();
// 都市名と都市コードの辞書を初期化
cityNames = new Dictionary<string, string>
{
{ "東京都", "400040" },
{ "大阪府", "1" },
{ "愛知県", "2" },
{ "福岡県", "10" }
};
// 都市名をComboBoxに追加
foreach (KeyValuePair<string, string> data in cityNames)
{
areaBox.Items.Add(data.Key);
}
}
// 都市名が選択されたときの処理
private void CitySelected(object sender, EventArgs e)
{
// 天気情報サービスにアクセス
string cityCode = cityNames[areaBox.Text];
string url = $"https://weather.tsukumijima.net/api/forecast/city/{cityCode}";
HttpClient client = new HttpClient();
string result = client.GetStringAsync(url).Result;
// 天気情報からアイコンのURLを取り出す
var weatherInfo = JsonConvert.DeserializeObject<WeatherInfo>(result);
var data = weatherInfo.description.bodyText;
// 結果をtextBox1に表示したい場合
// textBox1.Text = data;
}
// 終了メニューがクリックされたときの処理
private void ExitMenuClicked(object sender, EventArgs e)
{
// フォームを閉じる
this.Close();
}
public class WeatherInfo
{
public DateTime publicTime { get; set; }
public string publicTimeFormatted { get; set; }
public string publishingOffice { get; set; }
public string title { get; set; }
public string link { get; set; }
public Description description { get; set; }
public Forecast[] forecasts { get; set; }
public Location location { get; set; }
public Copyright copyright { get; set; }
}
public class Description
{
public DateTime publicTime { get; set; }
public string publicTimeFormatted { get; set; }
public string headlineText { get; set; }
public string bodyText { get; set; }
public string text { get; set; }
}
public class Location
{
public string area { get; set; }
public string prefecture { get; set; }
public string district { get; set; }
public string city { get; set; }
}
public class Copyright
{
public string title { get; set; }
public string link { get; set; }
public Image image { get; set; }
public Provider[] provider { get; set; }
}
public class Image
{
public string title { get; set; }
public string link { get; set; }
public string url { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Provider
{
public string link { get; set; }
public string name { get; set; }
public string note { get; set; }
}
public class Forecast
{
public string date { get; set; }
public string dateLabel { get; set; }
public string telop { get; set; }
public Detail detail { get; set; }
public Temperature temperature { get; set; }
public Chanceofrain chanceOfRain { get; set; }
public Image1 image { get; set; }
}
public class Detail
{
public string weather { get; set; }
public string wind { get; set; }
public string wave { get; set; }
}
public class Temperature
{
public Min min { get; set; }
public Max max { get; set; }
}
public class Min
{
public string celsius { get; set; }
public string fahrenheit { get; set; }
}
public class Max
{
public string celsius { get; set; }
public string fahrenheit { get; set; }
}
public class Chanceofrain
{
public string T00_06 { get; set; }
public string T06_12 { get; set; }
public string T12_18 { get; set; }
public string T18_24 { get; set; }
}
public class Image1
{
public string title { get; set; }
public string url { get; set; }
public int width { get; set; }
public int height { get; set; }
}
}
}
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WeatherChecker
{
public partial class Form1 : Form
{
// 都市名とコードを紐付けるDictionary
private readonly Dictionary<string, string> cityNames;
// HttpClient は使い回す(ソケット枯渇を防ぐ)
private static readonly HttpClient http = new HttpClient
{
Timeout = TimeSpan.FromSeconds(10) // タイムアウト(必要に応じて調整)
};
public Form1()
{
InitializeComponent();
// 都市名と都市コードの辞書を初期化
cityNames = new Dictionary<string, string>
{
{ "東京都", "400040" },
{ "大阪府", "270000" }, // 実コードに差し替え推奨(例)
{ "愛知県", "230010" }, // 実コードに差し替え推奨(例)
{ "福岡県", "400010" } // 実コードに差し替え推奨(例)
};
// 都市名をComboBoxに追加
foreach (KeyValuePair<string, string> data in cityNames)
{
areaBox.Items.Add(data.Key);
}
// できれば UI 側でイベント配線:areaBox.SelectedIndexChanged += CitySelected;
}
// 都市名が選択されたときの処理(非同期)
private async void CitySelected(object sender, EventArgs e)
{
// 選択値検証
if (string.IsNullOrWhiteSpace(areaBox.Text))
{
ShowError("都市名が選択されていません。");
return;
}
if (!cityNames.TryGetValue(areaBox.Text, out string cityCode) || string.IsNullOrWhiteSpace(cityCode))
{
ShowError("都市コードが見つかりません。選択を確認してください。");
return;
}
string url = $"https://weather.tsukumijima.net/api/forecast/city/{cityCode}";
// フェッチ中のUI状態
var prevCursor = this.Cursor;
this.Cursor = Cursors.WaitCursor;
areaBox.Enabled = false;
// キャンセルが欲しければフォームに CancellationTokenSource を持たせる設計も可
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(12)))
{
try
{
// User-Agent を明示(API によっては必須になることがある)
if (!http.DefaultRequestHeaders.UserAgent.TryParseAdd("WeatherChecker/1.0"))
{
// 無視してよいが、必要ならログ
}
using (var resp = await http.GetAsync(url, cts.Token).ConfigureAwait(true))
{
// ステータスコード検証
resp.EnsureSuccessStatusCode();
string json = await resp.Content.ReadAsStringAsync().ConfigureAwait(true);
// JSON をオブジェクトへ
var weatherInfo = JsonConvert.DeserializeObject<WeatherInfo>(json);
if (weatherInfo == null || weatherInfo.description == null)
{
ShowError("天気データの形式が予期しないものでした。");
return;
}
string data = weatherInfo.description.bodyText ?? weatherInfo.description.text ?? "(説明なし)";
// 結果表示(必要に応じて UI を更新)
// textBox1.Text = data; // ←使用する場合はコメント解除
MessageBox.Show(this, data, "天気情報", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
catch (TaskCanceledException)
{
ShowError("通信がタイムアウトしました。ネットワーク環境を確認して再試行してください。");
}
catch (HttpRequestException ex)
{
ShowError($"通信エラーが発生しました: {ex.Message}");
}
catch (JsonException ex)
{
ShowError($"データの読み取りに失敗しました(JSON形式エラー): {ex.Message}");
}
catch (Exception ex)
{
// 想定外の例外も握りつぶさず通知
ShowError($"不明なエラーが発生しました: {ex.Message}");
}
finally
{
// UI 復帰
areaBox.Enabled = true;
this.Cursor = prevCursor;
}
}
}
// 終了メニューがクリックされたときの処理
private void ExitMenuClicked(object sender, EventArgs e)
{
this.Close();
}
private void ShowError(string message)
{
// textBox1 にも出したい場合はコメント解除
// textBox1.Text = message;
MessageBox.Show(this, message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
// 以降は API レスポンス用モデル
public class WeatherInfo
{
public DateTime publicTime { get; set; }
public string publicTimeFormatted { get; set; }
public string publishingOffice { get; set; }
public string title { get; set; }
public string link { get; set; }
public Description description { get; set; }
public Forecast[] forecasts { get; set; }
public Location location { get; set; }
public Copyright copyright { get; set; }
}
public class Description
{
public DateTime publicTime { get; set; }
public string publicTimeFormatted { get; set; }
public string headlineText { get; set; }
public string bodyText { get; set; }
public string text { get; set; }
}
public class Location
{
public string area { get; set; }
public string prefecture { get; set; }
public string district { get; set; }
public string city { get; set; }
}
public class Copyright
{
public string title { get; set; }
public string link { get; set; }
public Image image { get; set; }
public Provider[] provider { get; set; }
}
public class Image
{
public string title { get; set; }
public string link { get; set; }
public string url { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Provider
{
public string link { get; set; }
public string name { get; set; }
public string note { get; set; }
}
public class Forecast
{
public string date { get; set; }
public string dateLabel { get; set; }
public string telop { get; set; }
public Detail detail { get; set; }
public Temperature temperature { get; set; }
public Chanceofrain chanceOfRain { get; set; }
public Image1 image { get; set; }
}
public class Detail
{
public string weather { get; set; }
public string wind { get; set; }
public string wave { get; set; }
}
public class Temperature
{
public Min min { get; set; }
public Max max { get; set; }
}
public class Min
{
public string celsius { get; set; }
public string fahrenheit { get; set; }
}
public class Max
{
public string celsius { get; set; }
public string fahrenheit { get; set; }
}
public class Chanceofrain
{
public string T00_06 { get; set; }
public string T06_12 { get; set; }
public string T12_18 { get; set; }
public string T18_24 { get; set; }
}
public class Image1
{
public string title { get; set; }
public string url { get; set; }
public int width { get; set; }
public int height { get; set; }
}
}
}
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
using System.Windows.Forms;
namespace WeatherChecker
{
public partial class Form1 : Form
{
private Dictionary<string, string> cityNames;
public Form1()
{
InitializeComponent();
cityNames = new Dictionary<string, string>
{
{ "東京都", "400040" },
{ "大阪府", "1" },
{ "愛知県", "2" },
{ "福岡県", "10" }
};
foreach (KeyValuePair<string, string> data in cityNames)
{
areaBox.Items.Add(data.Key);
}
}
private async void CitySelected(object sender, EventArgs e)
{
try
{
// 天気情報サービスにアクセスする
string cityCode = cityNames[areaBox.Text];
string url = $"https://weather.tsukumijima.net/api/forecast/city/{cityCode}";
using (HttpClient client = new HttpClient())
{
string result = await client.GetStringAsync(url);
// 天気情報からアイコンのURLを取り出す
WeatherInfo weatherInfo = JsonSerializer.Deserialize<WeatherInfo>(result);
var data = weatherInfo.description.bodyText;
// textBox1.Text = data;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ExitMenuClicked(object sender, EventArgs e)
{
// フォームを閉じる
this.Close();
}
public class WeatherInfo
{
public DateTime publicTime { get; set; }
public string publicTimeFormatted { get; set; }
public string publishingOffice { get; set; }
public string title { get; set; }
public string link { get; set; }
public Description description { get; set; }
public Forecast[] forecasts { get; set; }
public Location location { get; set; }
public Copyright copyright { get; set; }
}
public class Description
{
public DateTime publicTime { get; set; }
public string publicTimeFormatted { get; set; }
public string headlineText { get; set; }
public string bodyText { get; set; }
public string text { get; set; }
}
public class Location
{
public string area { get; set; }
public string prefecture { get; set; }
public string district { get; set; }
public string city { get; set; }
}
public class Copyright
{
public string title { get; set; }
public string link { get; set; }
public Image image { get; set; }
public Provider[] provider { get; set; }
}
public class Image
{
public string title { get; set; }
public string link { get; set; }
public string url { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Provider
{
public string link { get; set; }
public string name { get; set; }
public string note { get; set; }
}
public class Forecast
{
public string date { get; set; }
public string dateLabel { get; set; }
public string telop { get; set; }
public Detail detail { get; set; }
public Temperature temperature { get; set; }
public Chanceofrain chanceOfRain { get; set; }
public Image1 image { get; set; }
}
public class Detail
{
public string weather { get; set; }
public string wind { get; set; }
public string wave { get; set; }
}
public class Temperature
{
public Min min { get; set; }
public Max max { get; set; }
}
public class Min
{
public string celsius { get; set; }
public string fahrenheit { get; set; }
}
public class Max
{
public string celsius { get; set; }
public string fahrenheit { get; set; }
}
public class Chanceofrain
{
public string T00_06 { get; set; }
public string T06_12 { get; set; }
public string T12_18 { get; set; }
public string T18_24 { get; set; }
}
public class Image1
{
public string title { get; set; }
public string url { get; set; }
public int width { get; set; }
public int height { get; set; }
}
}
}
訪問数 149 回, 今日の訪問数 1回
ディスカッション
コメント一覧
まだ、コメントがありません