駅マスタ検索APIとBingMaps

2011年10月21日(金)
PROJECT KySS

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

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

リスト3 (MainPage.xaml.vb)

Option Strict On
Imports System.Xml.Linq
Imports System.Net

Windows Phoneのための、シェルAPIにアクセスを提供するクラスの含まれる、Microsoft.Phone.Shell名前空間をインポートします。
Imports Microsoft.Phone.Shell
StationInfoクラス内で、文字列型の「name」、「Latitude(緯度)」、「Longitude(経度)」プロパティを定義しています。
Public Class StationInfo
  Property name As String
  Property Latitude As String
  Property Longitude As String
End Class

Partial Public Class MainPage
  Inherits PhoneApplicationPage
  
  ' Constructor
  Public Sub New()
    InitializeComponent()
  End Sub

定数変数AppIDを宣言し、値に「リクルートより取得したAPIキー」を指定します。
  Const AppID As String = "リクルートより取得したAPIキー"

Integer型のSharedメンバ変数を宣言します。
  Shared no As Integer = 0

[OK]ボタンがクリックされた時の処理

API へのリクエストは、keyや検索キーワード(name)などの条件を下記のような URL で指定します。(REST)

Dim myUri As String = String.Format("http://api.doko.jp/v1/getStation.do?key={0}&name={1}", AppID, TextBox1.Text)

新しいWebClientのインスタンスmyWebClientオブジェクトを生成します。DownloadStringAsyncメソッドで、Uri として指定したリソースをダウンロードします。
AddHandler ステートメントでダウンロードが完了した DownloadStringCompleted イベントに、イベント ハンドラーを追加します。イベント ハンドラー内では、ダウンロードされた文字列としての結果 XML を、Parse メソッドで読み込みます。Descendants メソッドで、子孫要素であるすべての <landmark> 要素のコレクションに対して、各要素を変数 result に格納しながら、StationbInfo クラスの「name」、「Latitude」、「Longitude」プロパティに、<name>、< lat_jgd>、< lon_jgd> 要素の値を指定し、StationInfo クラスの新しいリストとして作成した、myStationInfo オブジェクトに追加していきます。
「駅マスタ検索API」のレスポンスフィールドについては、下記URLから「3:駅マスタ検索API」を参照してください。

http://webservice.recruit.co.jp/doko/reference.html
フィールドは「世界測地系Degree」のlat_jgd(Latitude)とlon_jgd(Longitude)を取得します。「日本測地系Degree」を取得すると位置がずれてしまいますので注意してください。

ListBox(resultListBox) の ItemSource プロパティに myStationInfo オブジェクトを指定すると、検索された駅名の一覧が ListBox 内に表示されます。
  Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
    Dim myUri As String = String.Format("http://api.doko.jp/v1/getStation.do?key={0}&name={1}", AppID, TextBox1.Text)
    Dim myWebClient As New WebClient
    myWebClient.DownloadStringAsync(New Uri(myUri, UriKind.Absolute))
 
    AddHandler myWebClient.DownloadStringCompleted, Sub(resultSender As Object, resultArgs As DownloadStringCompletedEventArgs)
      Dim xmldoc As XElement = XElement.Parse(resultArgs.Result)
      Dim myStationInfo As New List(Of StationInfo)
        For Each result In From c In xmldoc.Descendants("landmark") Select c
          With myStationInfo
            .Add(New StationInfo With {.name = result.Element("name").Value,
                                   .Latitude = result.Element("lat_jgd").Value,
                                  .Longitude = result.Element("lon_jgd").Value})
          End With
        Next
          resultListBox.ItemsSource = myStationInfo
    End Sub
  End Sub

ListBoxより項目が選択された時の処理

Shared変数noを1ずつ増加させます。
ListBox(resultListBox) より選択された項目を StationInfo クラスにキャストし、「name」プロパティの値を取得し、変数myNameに格納しておきます。
ListBox(resultListBox) より選択された項目を StationInfo クラスにキャストし、「Latitude」プロパティの値を取得し、変数myLatitudeに格納しておきます。
ListBox(resultListBox) より選択された項目を StationInfo クラスにキャストし、「Longitude」プロパティの値を取得し、変数my Longitudeに格納しておきます。

StandardTileDataクラスの「Title」に変数myNameの値を、「BackgroundImage」にはソリューションエクスプローラー内のImageフォルダ内の画像を、「Count」、プロパティには、Sharedメンバ変数noの値をそれぞれ指定します。
StandardTileDataクラスは、タイル用のデータが、スタートに固定されるクラスです。
StandardTileDataクラスの各プロパティについては、下記URIの「Properties」を参照してください(英語)。
http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.standardtiledata_members(v=vs.92).aspx

任意のタイルがクリックされた時、「name」、「Latitude」、「Longitude」を引数にBingMapPagePage.xamlに遷移するようUriを定義しておきます。
Createメソッドで新しいセカンダリタイルを作成します。Createメソッドの書式は下記の通りです。

ShellTile.Create(作成されるタイルのURI。URIは、独自の起動パラメーターを含めることが可能(System.Uri),作成されたタイルのテキストとイメージの情報(Microsoft.Phone.Shell.ShellTileData))

Try~Catch~End Tryステートメントで例外処理を行っておいてください。この処理を怠るとエミュレーターのBack(←)ボタンで戻った場合エラーが表示されます。
  Private Sub resultListBox_SelectionChanged(sender As Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles resultListBox.SelectionChanged
    Try
      no = no + 1
      Dim myName As String = DirectCast(resultListBox.SelectedItem, StationInfo).name
      Dim myLatitude As String = DirectCast(resultListBox.SelectedItem, StationInfo).Latitude
      Dim myLongitude As String = DirectCast(resultListBox.SelectedItem, StationInfo).Longitude
 
      Dim myTileData As StandardTileData = New StandardTileData With {.Title = myName, .BackgroundImage = New Uri("Image/RedBorderBlack.png", UriKind.Relative), .Count = no}
      Dim myUri As Uri = New Uri(String.Format("/BingMapPage.xaml?name={0}&Latitude={1}&Longitude={2}", myName, myLatitude, myLongitude), UriKind.Relative)
      ShellTile.Create(myUri, myTileData)
    Catch
      Exit Sub
    End Try
  End Sub
End Class

次に、BingMapPage.xamlを展開して、BingMapPage.xaml.vbをダブルクリックして、リスト4のコードを記述します。

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

リスト4 (BingMapPage.xaml.vb)

Option Strict On
Imports System.Device.Location
Imports Microsoft.Phone.Controls.Maps
Partial Public Class BingMapPage
  Inherits PhoneApplicationPage

  Public Sub New()
    InitializeComponent()
  End Sub

ページが読み込まれた時の処理

ここで、Mainpage.xamlから渡された文字データを受け取ります。文字データはNavigationContextのQueryStringにDictionary として提供されます。PageTitleというNameを持つTextBlockに駅名を表示します。
地図を移動させるには、MapのCenterプロパティに、GeoCoordinateメソッドにダブル型の緯度と経度(引数で渡した値)を指定します。緯度は、myParam("Latitude")で取得し、経度はmyParam("Longitude")で取得します。
ZoomLevelプロパティに10を指定します。ZoomLevelプロパティを指定しないと地図が表示されませんので注意してください。
  PushPinクラスの新しいインスタンスmyPinオブジェクトを生成します。Locationプロパティに、GeoCoordinateメソッドを使って緯度と経度を指定します。ContentプロパティにはmyParam(“name”)の値を指定します。ピン上に駅名が表示されます。緯度と経度とContentの指定されたmyPinオブジェクトをAddメソッドでMapに追加します。これでピンが指定した位置に立ちます。
  Private Sub BingMapPage_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
    Dim myParam As IDictionary(Of String, String) = NavigationContext.QueryString
    PageTitle.Text = myParam("name")
    Map1.Center = New GeoCoordinate(Double.Parse(myParam("Latitude")), Double.Parse(myParam("Longitude")))
    Map1.ZoomLevel = 10
 
    Dim myPin As New Pushpin
    myPin.Location = New GeoCoordinate(Double.Parse(myParam("Latitude")), Double.Parse(myParam("Longitude")))
    myPin.Content = myParam("name")
    Map1.Children.Add(myPin)
  End Sub
End Class
  • 「駅マスタ検索APIとBingMaps」サンプルプログラム

四国の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メルマガ会員のサービス内容を見る

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