お天気情報WebAPIを使ってGIF画像を表示する
2012年1月27日(金)

お天気の情報とGIF画像を表示する処理
[<<]と[>>]ボタンタップで増減するメンバ変数noの値で、条件分岐を行います。noの値が0の時は、メンバ変数myNowにtoday(今日)を格納し、[<<]ボタンを使用不可に、[>>]ボタンを使用可とします。1の時は、myNowにtomorrow(明日)を格納します。2の時は、myNowにdayaftertomorrow(明後日)を格納し、[<<]ボタンを使用可能に、[>>]ボタンを使用不可とします。 メンバ変数noの値をAddDaysメソッドに指定し、短いタイプの日付を変数myDateに格納します。指定した日数を加算、減算するのにDateTimeのインスタンスからAddDaysメソッドを使用します。 ImageTools.IO.Decoders.AddDecoder(Of GifDecoder)() の1文を追加します。これはGIFを表示させるために、初期化の際に一度だけ必要な処理です。このまま覚えてください。 新しいExtendedImageクラスのインスタンス、myImageオブジェクトを作成します。ExtendedImageクラスは、Image クラスのピクセルを格納し、ファイルやストリームのサイズ変更やカッティングのような操作から、イメージを読み込む機能を提供するクラスです。 各市のお天気情報を表示するには、各市のidが必要です。このidは http://weather.livedoor.com/forecast/rss/forecastmap.xml から取得することができます。上記URLに移動してブラウザの「ソースの表示(V)」を選択して、ソースを表示させると、図3のような構造のXMLになっています。この中の<city>要素の”id”属性の値を取得する必要があります。
| 図3:forecastmap.xmlの構造(クリックで拡大) |
Uri型の変数myUriにhttp://weather.livedoor.com/forecast/rss/forecastmap.xmlのUriを格納しておきます。新しいWebClientのインスタンスmyWebClientオブジェクトを作成します。DownloadStringAsyncメソッドで、Uri として指定したリソースをダウンロードします。
AddHandler ステートメントでダウンロードが完了した DownloadStringCompleted イベントに、イベント ハンドラを追加します。イベント ハンドラ内では、ダウンロードされた文字列としての結果 XML(resultArgs.Result) をXElement.Parseメソッドで文字列として読み込みます。読み込んだXMLの<city>要素の”title”属性の値が、cityTextBox.Textの値と同じ<city>要素を選択するクエリを定義します。そのクエリ内を反復処理しながら変数resultに各要素を格納していきます。メンバ変数cityIdに<city>要素の属性”id”の値を格納します。数値型のメンバ変数myIdに数値に変換したcityIdの値を格納します。
新しいWebClientのインスタンス、wcオブジェクトを作成します。お天気情報のAPI へのリクエストは、対象となる「市」や表示する「日」などの条件を下記のような URL で指定します。(REST)
Dim _uri As Uri = New Uri(String.Format("http://weather.livedoor.com/forecast/webservice/rest/v1?city={0}&day={1}", myId, myNow), UriKind.Absolute)
cityには、先に取得した「市」のidが入ります。dayには変数myNowの値が入ります。myNowの値はメンバ変数noの値によって、today(今日)、tomorrow(明日)、dayaftertomorrow(明後日)と変化します。DownloadStringAsyncメソッドに、上記Uriを指定しソースをダウンロードします。
cityに「松山」のidである104を指定し、dayに「今日」を表すtodayを指定すると、図4のようなXMLが返ってきます。<image>要素の子要素<url>を見るとGIF画像が指定されています。ImageToolsを使用しなければ、この画像はWindows Phoneでは表示できません。
| 図4:結果XML(クリックで拡大) |
AddHandler ステートメントでダウンロードが完了した DownloadStringCompleted イベントに、イベント ハンドラを追加します。イベント ハンドラ内では、ダウンロードされた文字列としての結果 XML(myresultArgs.Result) をXElement.Parseメソッドで文字列として読み込みます。変数areaに、最初に見つかった<title>要素の値を格納します。地域名が格納されます。areaTextBlock内に変数areaの内容と、日付を格納した変数myDateの値を連結して表示します。
変数weatherに<Image>要素の子要素<title>要素の値を格納します。天気情報が格納されます。weatherTextBlockに変数weatherの値を表示します。変数gifUriに<image>要素の子要素<url>の値を格納します。お天気のGIF画像のURLが格納されます。ExtendedImageクラスのインスタンスである、myImageのUriSourceプロパティにgifUriのUriを絶対Uriで指定します。UriSourceプロパティでは、ExtendedImageのUriのソースを設定できます。Try~Catch~End Tryで例外処理を行います。例外が発生した場合はメッセージを表示し、[>>]ボタンの使用を不可として処理を抜けます。
GIF画像の読み込みが完了した時に発生する、LoadingCompletedイベントに、イベントハンドラを追加します。イベントハンドラ内では、Image1のSourceプロパティに、ExtendedImageクラスのインスタンス、myImageオブジェクトをBitmapに変換して指定しています。GIF画像を表示するには、Dispatcherが関連付けられているスレッドで、デリゲートを実行する必要があります。これには、非同期処理であるBeginInvokeメソッドを使用します。
Private Sub DataShow()
Select Case no
Case 0
myNow = "today"
prevButton.IsEnabled = False
nextButton.IsEnabled = True
Case 1
myNow = "tomorrow"
Case 2
myNow = "dayaftertomorrow"
nextButton.IsEnabled = False
prevButton.IsEnabled = True
End Select
Dim myDate As String= DateTime.Now.AddDays(no).ToShortDateString
ImageTools.IO.Decoders.AddDecoder(Of GifDecoder)()
Dim myImage As ExtendedImage = New ExtendedImage
Dim myUri As Uri = New Uri("http://weather.livedoor.com/forecast/rss/forecastmap.xml", UriKind.Absolute)
Dim myWebClient As New WebClient
myWebClient.DownloadStringAsync(myUri)
AddHandler myWebClient.DownloadStringCompleted, Sub(resultSender As Object, resultArgs As DownloadStringCompletedEventArgs)
Dim xmldoc As XElement = XElement.Parse(resultArgs.Result)
Dim query = From c In xmldoc.Descendants("city") Where c.Attribute("title").Value.Equals(cityTextBox.Text) Select c
For Each result In query
cityId = result.Attribute("id").Value
myId = Integer.Parse(cityId)
Next
Dim wc As New WebClient
Dim _uri As Uri = New Uri(String.Format("http://weather.livedoor.com/forecast/webservice/rest/v1?city={0}&day={1}", myId, myNow), UriKind.Absolute)
wc.DownloadStringAsync(_uri)
AddHandler wc.DownloadStringCompleted, Sub(myresultSender As Object, myresultArgs As DownloadStringCompletedEventArgs)
Try
Dim doc As XElement = XElement.Parse(myresultArgs.Result)
Dim area As String = doc.Descendants("title").First.Value
areaTextBlock.Text = area & "(" & myDate & ")"
Dim weather As String = doc.Descendants("image").Elements("title").Value
weatherTextBlock.Text = weather
Dim gifUri As String = doc.Descendants("image").Elements("url").Value
myImage.UriSource = New Uri(gifUri, UriKind.Absolute)
Catch
MessageBox.Show("市が不正です。")
no = 0
nextButton.IsEnabled = False
Exit Sub
End Try
End Sub
End Sub
AddHandler myImage.LoadingCompleted, Sub(loadSender As Object, loadArgs As EventArgs)
Dispatcher.BeginInvoke(Sub()
Image1.Source = myImage.ToBitmap
End Sub)
End Sub
End Sub
[>>]ボタンがタップされた時の処理
メンバ変数noの値が2の場合はnoの値は2とします。それ以外の場合は、メンバ変数noの値を1ずつ増加させます。[>>]ボタンの使用を可能とします。お天気情報を表示するDataShowプロシージャを実行します。
Private Sub nextButton_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles nextButton.Click
If no = 2 Then
no = 2
Else
no = no + 1
nextButton.IsEnabled = True
End If
DataShow()
End Sub
[<<]ボタンがタップされた時の処理
メンバ変数noが0の場合はnoの値は0とします。それ以外の場合は、メンバ変数noの値を1ずつ減少します。[<<]ボタンの使用を可能とします。お天気情報を表示するDataShowプロシージャを実行します。
Private Sub prevButton_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles prevButton.Click
If no = 0 Then
no = 0
Else
no = no - 1
prevButton.IsEnabled = True
End If
DataShow()
End Sub
End Class
「お天気情報WebAPIを使ってGIF画像を表示する」のサンプルプログラム
連載バックナンバー
Think ITメルマガ会員登録受付中
Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。




