地震の震源地を表示する

2012年1月10日(火)
PROJECT KySS

ページがアクティブになった時の処理

1Mapのズームを6に設定します。
2API へのリクエストは、下記のような URL で指定します。(REST)
3Dim myUri As Uri = New Uri("http://nmz.mogken.com/api?c=10&f=xml", UriKind.Absolute)
4  cには表示する最大データ件数、ここでは10個を指定しています。fには返されるデータ形式を指定します。ここではxmlを指定しています。jsonを指定することも可能です。このURLで返されるXMLのデータ構造は図4のようになります。

図4:返されるXMLの構造(クリックで拡大)
01新しいWebClientのインスタンスmyWebClientオブジェクトを生成します。DownloadStringAsyncメソッドで、Uri として指定したリソースをダウンロードします。
02各文字列変数を初期化しておきます。変数myDateに-で連結した現在の、年、月、日の値を格納します。月と日は01、02のような型にするため、Tostring(“00”)と指定しています。
03AddHandler ステートメントでダウンロードが完了した DownloadStringCompleted イベントに、イベント ハンドラを追加します。イベント ハンドラ内では、ダウンロードされた文字列としての結果 XML(resultArgs.Result) をXElement.Parseメソッドで文字列として読み込みます。
04図4の構造の、XMLの内容テキストを取得していきます。
05Descendants メソッドで、子孫要素であるすべての <item> 要素のコレクションに対して、各要素を変数 result に格納しながら、各変数に<epicenter_location_name>要素の値(震源地)、<detection_date>要素の値(発生日時)、<epicenter_coor_lat>要素の値(震源地の緯度)、<epicenter_coor_long>要素の値(震源地の経度)、< magnitude>要素の値(マグニチュード)、<intensity>要素の値(震度)を格納していきます。
06地図を移動させるには、MapのCenterプロパティに、GeoCoordinateメソッドにダブル型の緯度と経度を指定します。緯度は、変数myLatitudeの値、経度はmyLongitudeの値をダブル型に変換して指定しています。
07PushPinクラスの新しいインスタンスmyPinオブジェクトを生成します。
08発生日時がmyDate変数の値、すなはち、本日であった場合は、ピンの背景色を赤色に指定します。それ以外は黄色になります。ピンの文字色は青色を指定します。ピンのLocationプロパティに、GeoCoordinateメソッドを使って緯度と経度を指定します。Contentプロパティには地震発生日時を指定します。Tagプロパティに1ずつ増加する変数noの値を文字列に変換して指定します。この値は図4の選択された<item>要素のインデックス番号として使用します。緯度と経度とContentの指定されたmyPinオブジェクトをAddメソッドでMapに追加します。これで指定した位置にピンが立ちます。
09AddHandlerステートメントで、ピンがホールドされた時に実行される、myPin_Holdイベントハンドラを追加します。
10新しいMeuItemクラスのインスタンスmyMenuItemオブジェクトを作成します。Headerプロパティに「地震の詳細を表示」と指定します。menuItem型として宣言しておいたメンバ変数menuItemListオブジェクトにAddメソッドでmyMenuItemオブジェクトを追加します。ContextMenuのItemsSourceプロパティに、menuItemListオブジェクトを指定します。ContetMenuに表示されるMenuItemをタップした時にmyMenuItem_Clickイベントハンドラを実行します。
11  Protected Overrides Sub OnNavigatedTo(e As System.Windows.Navigation.NavigationEventArgs)
12    Map1.ZoomLevel = 6
13    Dim myUri As Uri = New Uri("http://nmz.mogken.com/api?c=10&f=xml", UriKind.Absolute)
14  
15    Dim myWebClient As New WebClient
16    myWebClient.DownloadStringAsync(myUri)
17  
18    Dim detectionDate As String = String.Empty
19    Dim myLocation As String = String.Empty
20    Dim myLatitude As String = String.Empty
21    Dim myLongitude As String = String.Empty
22    Dim myMagnitude As String = String.Empty
23    Dim myIntensity As String = String.Empty
24  
25    Dim nowYear As Integer = Date.Now.Year
26    Dim nowMonth As Integer = Date.Now.Month
27    Dim nowDay As Integer = Date.Now.Day
28  
29    Dim myDate As String = nowYear.ToString & "-" & nowMonth.ToString("00") & "-" & nowDay.ToString("00")
30  
31    no = 0
32    AddHandler myWebClient.DownloadStringCompleted, Sub(resultSender As Object, resultArgs As DownloadStringCompletedEventArgs)
33              xmldoc = XElement.Parse(resultArgs.Result)
34              For Each result In From c In xmldoc.Elements("item") Select c
35                  myLocation = result.Element("epicenter_location_name").Value
36                  detectionDate = result.Element("detection_date").Value
37                  myLatitude = result.Element("epicenter_coor_lat").Value
38                  myLongitude = result.Element("epicenter_coor_long").Value
39                  myMagnitude = result.Element("magnitude").Value
40                  myIntensity = result.Element("intensity").Value
41                  Map1.Center = New GeoCoordinate(Double.Parse(myLatitude), Double.Parse(myLongitude))
42                  Dim myPin As New Pushpin
43                  If detectionDate.Contains(myDate) = True Then
44                      myPin.Background = New SolidColorBrush(Colors.Red)
45                  Else
46                      myPin.Background = New SolidColorBrush(Colors.Yellow)
47                  End If
48                    myPin.Foreground = New SolidColorBrush(Colors.Blue)
49                    myPin.Location = New GeoCoordinate(Double.Parse(myLatitude), Double.Parse(myLongitude))
50                    myPin.Content = "地震発生日時=" & detectionDate
51                    myPin.Tag = no.ToString
52                    no = no + 1
53                    Map1.Children.Add(myPin)
54                     
55                    AddHandler myPin.Hold, AddressOf myPin_Hold
56              Next
57              Dim myMenuItem As New MenuItem
58              myMenuItem.Header = "地震の詳細を表示"
59              menuItemList.Add(myMenuItem)
60                ContextMenu1.ItemsSource = menuItemList
61                AddHandler myMenuItem.Click, AddressOf myMenuItem_Click
62                    End Sub
63    MyBase.OnNavigatedTo(e)
64  End Sub

ピンがホールドされた時の処理

1ContextMenuを表示します。
2PushPinのTagプロパティに指定した値を、数値に変換して変数indexに格納します。
3  Private Sub myPin_Hold(sender As Object, e As System.Windows.Input.GestureEventArgs)
4    ContextMenu1.IsOpen = True
5    index = Integer.Parse(DirectCast(sender, Pushpin).Tag.ToString)
6  End Sub

ピンをホールドした時に表示されるメニューをタップした時の処理

01MenuItemのHeaderプロパティの値で条件分岐を行います。
02Headerの値が「地震の詳細を表示」であった場合は、選択されたピンのindexに該当する<item>要素の、< epicenter_location_name>(震源地)の値、<detection_date>(発生日時)の値、<intensity>(震度)の値、<magnitude>(マグニチュード)の値、を変数に格納し、この変数を引数にDetailsPage.xamlに遷移します。
03  Private Sub myMenuItem_Click(sender As Object, e As EventArgs)
04    Dim selectHeader = DirectCast(sender, MenuItem).Header
05    Select Case selectHeader.ToString
06      Case "地震の詳細を表示"
07        Dim location As String = xmldoc.Elements("item")(index).Element("epicenter_location_name").Value '震源地
08        Dim quakeDate As String = xmldoc.Elements("item")(index).Element("detection_date").Value '発生日時
09        Dim intnsity As String = xmldoc.Elements("item")(index).Element("intensity").Value '震度
10        Dim magnitude As String = xmldoc.Elements("item")(index).Element("magnitude").Value 'マグニチュード
11        NavigationService.Navigate(New Uri(String.Format("/DetailsPage.xaml?myDate={0}&myPlace={1}&myMagnitude={2}&myIntnisity={3}", quakeDate, location, magnitude, intnsity), UriKind.Relative))
12      Case Else
13        Exit Sub
14    End Select
15  End Sub
16 
17End Class

DetailsPage.xamlを展開して表示される、DetailsPage.xaml.vbをダブルクリックしてリスト4のコードを記述します。

ロジックコードを記述する

リスト4 (DetailsPage.xaml.vb)

1Option Strict On
2 
3Partial Public Class DetailsPage
4  Inherits PhoneApplicationPage
5  
6  Public Sub New()
7    InitializeComponent()
8  End Sub

ページがアクティブになった時の処理

01Mainpage.xamlから渡された文字データを受け取ります。文字データはNavigationContextのQueryStringにDictionary として提供されます。
02各TextBoxに、受け取った文字データを表示します。
03  Protected Overrides Sub OnNavigatedTo(e As System.Windows.Navigation.NavigationEventArgs)
04    Dim myParam As IDictionary(Of String, String) = NavigationContext.QueryString
05    PageTitle.Text = myParam("myPlace")
06    dateTextBlock.Text = myParam("myDate")
07    locationTextBlock.Text = myParam("myPlace")
08    magnitudeTextBlock.Text = myParam("myMagnitude")
09    intensityTextBlock.Text = myParam("myIntnisity")
10    MyBase.OnNavigatedTo(e)
11  End Sub
12End Class
  • 「地震の震源地を表示する」サンプルプログラム

四国のSOHO。薬師寺国安(VBプログラマ)と、薬師寺聖(デザイナ、エンジニア)によるコラボレーション・ユニット。1997年6月、Dynamic HTMLとDirectAnimationの普及を目的として結成。共同開発やユニット名義での執筆活動を行う。XMLおよび.NETに関する著書や連載多数。最新刊は「Silverlight実践プログラミング」両名とも、Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。http://www.PROJECTKySS.NET/

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています