入力された住所の位置をBing Mapsに表示する
2011年12月16日(金)

次に、MainPage.xamlを展開して表示される、MainPage.xaml.vbをダブルクリックしてリスト3のコードを記述します。
ロジックコードを記述する
リスト3 (MainPage.xaml.vb)
Option Strict On
Imports System.Xml.Linq
Partial Public Class MainPage
Inherits PhoneApplicationPage
' コンストラクター
Public Sub New()
InitializeComponent()
End Sub
定数変数AppIDを宣言し、値に「Bing Maps Account Centerより取得したApplicationID」を指定します。
Const AppID As String= " Bing Maps Account Centerより取得したApplicationID "
XML要素を表すXElementクラス型のメンバ変数xmldocを宣言します。
Dim xmldoc As XElement
Dim prefName As String = String.Empty
ページが読み込まれた時の処理
XElement.LoadメソッドでXML文書ファイル(pref.xml)を読み込みます。文字列型の新しいリストである、prefListオブジェクトを作成します。
Descendants メソッドで、子孫要素であるすべての <都道府県> 要素のコレクションに対して、各要素を変数 result に格納しながら、リストであるprefListオブジェクトにAddメソッドで、<都道府県>要素の値を追加していきます。ListBoxである、prefListBoxのItemsSourceプロパティにprefListオブジェクトを指定します。ListBox内に都道府県の一覧が表示されます。
Private Sub MainPage_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
xmldoc = XElement.Load("pref.xml")
Dim prefList As New List(Of String)
For Each result In From c In xmldoc.Descendants("都道府県") Select c
prefList.Add(result.Value)
Next
prefListBox.ItemsSource = prefList
End Sub
[実行]ボタンがタップされた時の処理
API へのリクエストは、adminDistrict、locality、addressLine、keyなどの条件を下記のような URL で指定します(REST)。
adminDistrictには「都道府県」、localityには「市区町村」、addressLineには「番地」、keyには「Bing Maps Account Centerより取得したApplicationID」を指定します。最後のoには結果レスポンスされるデータの形式を指定します。ここではxmlを指定しています。JSONを指定することもできます。「市区町村」、「番地」に指定する値は、UrlEncodeで文字列をエンコードしています。「都道府県」はListBoxから選択された時点でエンコードしています。
Dim myUri As String = String.Format("http://dev.virtualearth.net/REST/v1/Locations?countryRegion=JP&adminDistrict={0}&locality={1}&addressLine={2}&key={3}&c=ja-jp&o=xml", prefName, HttpUtility.UrlEncode(cityTextBox.Text), HttpUtility.UrlEncode(numberTextBox.Text), AppID)
例えば、京都府京都市伏見区桃山町丹後9番地と入力して返されるXMLは、図8のようなXMLです。
| 図8:返された結果XML(クリックで拡大) |
新しいWebClientのインスタンスmyWebClientオブジェクトを生成します。DownloadStringAsyncメソッドで、Uri として指定したリソースをダウンロードします。
AddHandler ステートメントでダウンロードが完了した DownloadStringCompleted イベントに、イベント ハンドラーを追加します。イベント ハンドラー内では、ダウンロードされた文字列としての結果 XML(resultArgs.Result) を変数readXmldocに格納します。図8を見るとわかりますが、いろいろな名前空間が付属しています。このままではXMLの内容を取り出すことができません。そこで、Replace関数を使って、不要な名前空間を空白にしてしまいます。不要な名前空間の無くなったreadXmldocをXElement.Parseメソッドで文字列として読み込みます。
<Location>要素の子要素<Name>の値を変数addressNameに格納します。
<Point>要素の子要素<Latitude>(緯度)の値をmyLatitude変数に格納します。
<Point>要素の子要素<Longitude>(経度)の値をmyLongitudeに格納します。
これらの値を引数にして、MapPage.xamlに遷移します。
Private Sub Button1_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
Dim myUri As String = String.Format("http://dev.virtualearth.net/REST/v1/Locations?countryRegion=JP&adminDistrict={0}&locality={1}&addressLine={2}&key={3}&c=ja-jp&o=xml", prefName, HttpUtility.UrlEncode(cityTextBox.Text), HttpUtility.UrlEncode(numberTextBox.Text), AppID)
Dim myWebClient As New WebClient
myWebClient.DownloadStringAsync(New Uri(myUri, UriKind.Absolute))
AddHandler myWebClient.DownloadStringCompleted, Sub(resultSender As Object, resultArgs As DownloadStringCompletedEventArgs)
Dim readXmldoc As String = resultArgs.Result
readXmldoc = readXmldoc.Replace("xmlns:xsi=" & ChrW(34) & "http://www.w3.org/2001/XMLSchema-instance" & ChrW(34) & " xmlns:xsd=" & ChrW(34) & "http://www.w3.org/2001/XMLSchema" & ChrW(34) & " xmlns=" & ChrW(34) & "http://schemas.microsoft.com/search/local/ws/rest/v1" & ChrW(34), "")
Dim doc As XElement = XElement.Parse(readXmldoc)
Dim addressName As String = HttpUtility.UrlEncode(doc.Descendants("Location").Elements("Name").Value)
Dim myLatitude As String = HttpUtility.UrlEncode(doc.Descendants("Point").Elements("Latitude").Value)
Dim myLongitude As String = HttpUtility.UrlEncode(doc.Descendants("Point").Elements("Longitude").Value)
NavigationService.Navigate(New Uri(String.Format("/MapPage.xaml?latitude={0}&longitude={1}&name={2}", myLatitude, myLongitude, addressName), UriKind.Relative))
End Sub
End Sub
ListBox(prefListBox)から任意の都道府県名が選択された時の処理
ListBoxから項目が選択された時は、選択された都道府県名をエンコードして、メンバ変数prefNameに格納します。都道府県名が選択されていない時は、メッセージを表示します。
Private Sub prefListBox_SelectionChanged(sender As Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles prefListBox.SelectionChanged
If prefListBox.SelectedIndex >= 0 Then
prefName = HttpUtility.UrlEncode(prefListBox.SelectedItem.ToString)
Else
MessageBox.Show("都道府県を選択してください。")
End If
End Sub
End Class
MapPage.xamlを展開して表示される、MapPage.xaml.vbをダブルクリックしてリスト4のコードを記述します。
ロジックコードを記述する
リスト4 (MapPage.xaml.vb)
Option Strict On
位置情報に関するクラスの含まれる、System.Device.Location名前空間をインポートします。
Imports System.Device.Location
Windows Phoneのための、Bing Maps Silverlight Controlのパブリッククラスを含む、Microsoft.Phone.Controls.Maps名前空間をインポートします。
Imports Microsoft.Phone.Controls.Maps
Partial Public Class MapPage
Inherits PhoneApplicationPage
Public Sub New()
InitializeComponent()
End Sub
ページがアクティブになった時の処理
Mainpage.xamlから渡された文字データを受け取ります。文字データはNavigationContextのQueryStringにDictionary として提供されます。各変数に受け取ったデータを格納します。
地図を移動させるには、MapのCenterプロパティに、GeoCoordinateメソッドにダブル型の緯度と経度(引数で渡した値)を指定します。緯度は、myParam("latitude")で取得し、経度はmyParam("longitude")で取得します。これらの値を格納した、myLatitude、myLongitudeの値をDouble型に変換して指定します。
PushPinクラスの新しいインスタンスmyPinオブジェクトを生成します。Locationプロパティに、GeoCoordinateメソッドを使って緯度と経度を指定します。ContentプロパティにはmyParam(“name”)の値を格納した、myAddress変数を指定します。ピン上に住所が表示されます。緯度と経度とContentの指定されたmyPinオブジェクトをAddメソッドでMapに追加します。これで指定した位置にピンが立ちます。
Protected Overrides Sub OnNavigatedTo(e As System.Windows.Navigation.NavigationEventArgs)
Dim myParam As IDictionary(Of String, String) = NavigationContext.QueryString
Dim myLatitude = myParam("latitude")
Dim myLongitude = myParam("longitude")
Dim myAddress = myParam("name")
Map1.Center = New GeoCoordinate(CDbl(myLatitude), CDbl(myLongitude))
Dim myPin As New Pushpin
myPin.Location = New GeoCoordinate(Double.Parse(myLatitude), Double.Parse(myLongitude))
myPin.Content = myAddress
Map1.Children.Add(myPin)
MyBase.OnNavigatedTo(e)
End Sub
ページが読み込まれた時の処理
ZoomLevelプロパティに10を指定します。ZoomLevelプロパティを指定しないと地図が表示されませんので注意してください。
Private Sub MapPage_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
Map1.ZoomLevel = 10
End Sub
[航空写真]がタップされた時の処理
ボタンの文字で条件分岐を行います。
ボタンの文字が「航空写真」の時タップされれば、地図は航空写真モードで表示されます。ボタンの文字は「道路表示」に変わります。
ボタンの文字が「道路表示」の時タップされれば、地図は道路表示モードで表示されます。ボタンの文字は「航空写真」に変わります。
Private Sub Button1_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
Select Case Button1.Content.ToString
Case "航空写真"
Map1.Mode = New AerialMode
Button1.Content = "道路表示"
Case "道路表示"
Map1.Mode = New RoadMode
Button1.Content = "航空写真"
End Select
End Sub
End Class
「入力された住所の位置をBing Mapsに表示する」サンプルプログラム
連載バックナンバー
Think ITメルマガ会員登録受付中
Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。



