自分の現在位置を取得して表示するサンプルプログラム
次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト2のコードを記述します。
ロジックコードを記述する
リスト1 (MainWindow.xaml.vb)
Option Strict On
コンピュータの地理的位置にアクセスできるようにするクラスの含まれる、Windows.Devices.Geolocation名前空間をインポートします。
Imports Windows.Devices.Geolocation
Bing Mapsに関するクラスの含まれる、Bing.Maps名前空間をインポートします。
Imports Bing.Maps
UIに関するクラスの含まれるWindows.UI名前空間をインポートします。PushPinの色を設定する場合等に必要です。
Imports Windows.UI
アプリケーションウインドウやウインドウ対話を作成し管理するサポートと、ウインドウ上の入力イベントを処理するクラスの含まれる、Windows.UI.Core名前空間をインポートします。
Imports Windows.UI.Core
最新のHTTPアプリケーション用のプログラミング インターフェイスを提供するクラスの含まれる、System.Net.Http名前空間をインポートします。
Imports System.Net.Http
コンテキストメニューおよびメッセージダイアログのサポートを提供するクラスの含まれる、Windows.UI.Popups名前空間をインポートします。
Imports Windows.UI.Popups Public NotInheritable Class MainPage Inherits Page
現在の地理的位置にアクセスするクラスである、Geolocatorクラスのメンバ変数myGeolocatorを宣言します。
Dim myGeolocator As Geolocator Dim myLatitude As String Dim myLongitude As String
Windowsランタイムコアイベントメッセージディスパッチャを提供するクラスである、CoreDispatcherクラスのメンバ変数、myCoreDispacherを宣言します。
Dim myCoreDispacher As CoreDispatcher
「Yahooで取得したアプリケーションID」で、定数メンバ変数AppIDを初期化します。
ConstAppID As String = "Yahooで取得したアプリケーションID"
ページがアクティブになった時の処理
myGeolocatorオブジェクトが作成されていない場合は、新しいGeolocatorクラスのインスタンスmyGeolocatorオブジェクトを作成します。
場所認識の精度レベルを表す、DesiredAccuracy プロパティにはDefaultを指定しておきます。Default以外にHighがありますが、パフォーマンスが低下する恐れがありますので、Defaultを指定しています。
Window.Current.CoreWindow.Dispatcherで、現在アクティブになっている、ウインドウの内部コアオブジェクトのイベントディスパッチャを取得して、myCoreDispacherで参照します。
AddHandlerステートメントで、場所が更新された時のPositionChangedイベント時のイベントハンドラ、myGeolocator_PositionChangedを追加します。
同じく、AddHandlerステートメントで、更新された場所を提供するGeolocatorの機能が変更された時に発生する、StatusChanged時のイベントハンドラ、myGeolocator_StatusChangedを追加します。
Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs) If myGeolocator Is Nothing = True Then myGeolocator = New Geolocator myGeolocator.DesiredAccuracy = PositionAccuracy.Default myCoreDispacher = Window.Current.CoreWindow.Dispatcher End If AddHandlermyGeolocator.PositionChanged, AddressOfmyGeolocator_PositionChanged AddHandlermyGeolocator.StatusChanged, AddressOfmyGeolocator_StatusChanged End Sub
場所が変更された時の処理
myCoreDispacher.RunAsyncメソッドで、イベントディスパッチャを実行し、ディスパッチされたイベントの結果を非同期に返します。ディスパッチャの優先順位は標準のNormalを指定しています。
緯度と経度のデータや都市の住所データを含めることができるGeoPositionクラス型の変数psoを宣言し、PositionChangedイベントに関連付けられた場所データを取得します。
Clearメソッドで、地図内を一度クリアしておきます。
新しいPushpinクラスのインスタンスmyPinオブジェクトを作成します。ピンの背景色をCrimsonに指定します。
地理的位置に関連付けされた緯度と経度で初期化された、新しいLocationクラスのインスタンスmyLocationオブジェクトを作成します。Locationクラスは、地図上の場所の標高と座標値を含むクラスです。
MapLayerクラスのSetPositionメソッドで、マップレイヤー内にピンの位置を設定します。myMapにAddメソッドでピンを追加します。SetViewメソッドで、指定された中心部に位置、ズーム レベル、方位、およびピッチにマップビューを設定します。この場合myLocationの位置に16レベルでズームインします。
現在位置の住所を取得するWeb APIのURLを設定します。latに現在の緯度、lonには現在の経度、appidにはYahooのキーを指定し、変数myUriに格納しておきます。
新しいHttpClientクラスのインスタンスmyHttpClientオブジェクトを作成します。HttpClientクラスには、URIで識別されるリソースにHTTP要求を送信し、そのリソースからHTTP応答を受信するための基本クラスが含まれています。
GetStringAsyncメソッドでmyUriの結果を、文字列として返し、変数resultAddressに格納します。GetStringAsyncメソッドは、指定URIにGET要求を送信し、非同期操作で応答本体を文字列として返すメソッドです。
返される文字列はXML形式になっています。このXMLのルート要素には、名前空間や不要な属性が定義されていて、内容を取得する際の邪魔(-_-;)になりますので、Replace関数で、ルート要素(
XElement.Parseメソッドで置換された結果のXMLが格納されている、resultAddressを文字列として読み込みます。
読み込んだXMLから
要素の内容を取得して、変数myAddressに格納しておきます。新しいStackPanelのインスタンスmyStackPanelオブジェクトを作成します。Marginプロパティに5を指定して余白を設けます。背景色をNavyに指定します。このStackPanelオブジェクトのインスタンスを、非表示としておきます。
新しいTextBlockのインスタンスmyTextBlockオブジェクトを作成します。文字色をRedに指定します。文字サイズに24を指定し、パディングに10を指定します。Textプロパティに住所を格納している変数myAddressと文字列「辺り」を連結して指定します。
myStackPanelオブジェクトにAddメソッドで住所の設定された、myTextBlockを追加します。
MapLayerクラスのSetPositionメソッドで、マップレイヤー内にmyStackPanelオブジェクトの位置を設定します。MapLayerクラスは、地図上の要素の位置を保持しているマップレイヤーを表すクラスです。
myMapにAddメソッドでmyStackPanelオブジェクトを追加します。myStackPanelは最初の状態では非表示になっているのでわかりませんが、ピンの位置にStackPanelオブジェクトが表示されることになります。
AddHandlerステートメントでピンをタップした時のイベントハンドラを追加します。イベントハンドラ内では、myStackPanelオブジェクトを表示状態にします。
AddHandlerステートメントでmyStackPanelをタップした時のイベントハンドラを追加します。イベントハンドラ内では、myStackPanelオブジェクトを非表示状態にします。
非同期処理で行われるためメソッドの先頭にAsyncを追加します。
Private Async Sub myGeolocator_PositionChanged(sender As Geolocator, args As PositionChangedEventArgs) Await myCoreDispacher.RunAsync(CoreDispatcherPriority.Normal, Async Sub() Dim pos As Geoposition = args.Position myMap.Children.Clear() Dim myPin As New Pushpin myPin.Background = New SolidColorBrush(Colors.Crimson) Dim myLocation = New Location(CDbl(pos.Coordinate.Latitude), CDbl(pos.Coordinate.Longitude)) MapLayer.SetPosition(myPin, myLocation) myMap.Children.Add(myPin) myMap.SetView(myLocation, 16) Dim myUri As String = String.Format("http://reverse.search.olp.yahooapis.jp/OpenLocalPlatform/V1/reverseGeoCoder?lat={0}&lon={1}&appid={2}", pos.Coordinate.Latitude, pos.Coordinate.Longitude, AppID) Dim myHttpClient As New HttpClient Dim resultAddress = Await myHttpClient.GetStringAsync(myUri) resultAddress = resultAddress.Replace("<YDF firstResultPosition=" &ChrW(34) & "1" &ChrW(34) & " totalResultsAvailable=" &ChrW(34) & "1" &ChrW(34) & " totalResultsReturned=" &ChrW(34) & "1" &ChrW(34) & " xmlns=" &ChrW(34) & "http://olp.yahooapis.jp/ydf/1.0" &ChrW(34) & ">", "<YDF>") Dim httpDoc As XElement = XElement.Parse(resultAddress) Dim myAddress = httpDoc.Descendants("Address").Value Dim myStackPanel As New StackPanel myStackPanel.Margin = New Thickness(5) myStackPanel.Background = New SolidColorBrush(Colors.Navy) myStackPanel.Visibility = Xaml.Visibility.Collapsed Dim myTextBlock As New TextBlock myTextBlock.Foreground = New SolidColorBrush(Colors.Red) myTextBlock.FontSize = 24 myTextBlock.Padding = New Thickness(10) myTextBlock.Text = myAddress& " 辺り" myStackPanel.Children.Add(myTextBlock) MapLayer.SetPosition(myStackPanel, New Location(CDbl(pos.Coordinate.Latitude), CDbl(pos.Coordinate.Longitude))) myMap.Children.Add(myStackPanel) AddHandlermyPin.Tapped, Sub() myStackPanel.Visibility = Xaml.Visibility.Visible End Sub AddHandlermyStackPanel.Tapped, Sub() myStackPanel.Visibility = Xaml.Visibility.Collapsed End Sub End Sub) End Sub
Geolocatorの機能が変更された時に発生する処理
Geolocatorオブジェクトの更新後の状態を、変数positionStatusで参照します。
Select Case文で条件分岐を行います。場所データを提供するGeolocatorオブジェクトがDisabledであった場合、つまり、場所プロバイダーが無効であった場合は、RunAsyncメソッドでディスパッチされたイベントの結果を非同期に返します。ディスパッチャの優先順位は標準のNormalを指定しています。
この場合は、「位置情報を取得できません。GPSおよび位置情報取得可能なPCでお試しください。」というメッセージボックスを表示させ、処理を抜けます。
非同期で行われるためメソッドの先頭にAsyncを追加します。
Private Async Sub myGeolocator_StatusChanged(sender As Geolocator, args As StatusChangedEventArgs) Dim positionStatus = args.Status Select Case positionStatus Case Windows.Devices.Geolocation.PositionStatus.Disabled Await myCoreDispacher.RunAsync(CoreDispatcherPriority.Normal, Async Sub() Dim message As New MessageDialog("位置情報を取得できません。GPSおよび位置情報取得可能なPCでお試しください。") Await message.ShowAsync Exit Sub End Sub) End Select End Sub End Class
アイコンの作成
ソリューションエクスプローラーのAssetsフォルダ内には、4つのpngファイルが入っています(表1)。
表1:Assetsフォルダ内に入っているpngファイルの種類
ファイル名 | サイズ |
---|---|
Logo.png | 150×150 |
SmallLogo.png | 30×30 |
SplashScreen.png | 620×300 |
StoreLogo.png | 50×50 |
表1の画像はデフォルトでは、□に×の画像になっています。ストアの審査では、このままの画像では審査に受かりませんので、4種類のアイコンを作る必要があります。このサンプルは実際にストアで審査の通ったアプリですので、Assetsフォルダ内には筆者の作成したアイコンが収められていますので、見てみてください。SplashScreen.pngはアプリを起動した際に、一瞬最初に表示される画像です。スタート画面にピン止めされる画像はデフォルトでは150×150のLogo.pngが使用されます。これを長方形の画像にしたい場合は、310×150サイズのpng画像を作成し、WideLogo.png(任意の名前でOK)としてAssetsフォルダに追加しておきます。
次にpackage.appxmanifestをダブルクリックして開きます。「アプリケーションUI」タブ内の「タイトルイメージとロゴ」というパネルに画像が表示されています(図16)。
図16から、「ワイドロゴ」を選択して310×150pxの横にある[…]ボタンをクリックして、Assetsフォルダ内のWideLogo.pngを指定します。初めて指定した場合は、画像が表示されずに赤丸の×が表示されます。
Assetsフォルダ内を見てみると、WideLogo.pngに-100といった不要なファイルが追加されていますので、これを削除してください。すると図17のように無事ワイドロゴが表示されます。実行すると、スタート画面にはこの長方形のワイドロゴがピン止めされます。
今回はここまでです。ありがとうございました。
筆者からのお知らせ
筆者はWindowsストアでアプリを公開しています。チャームの検索からWindowsストアを選択して、検索欄に、kuniyasuまたはYakushijiKuniyasuと入力すると、公開されているアプリの一覧が表示されます。上記はどちらも私のアカウントですので、興味のある方は是非ダウンロードして使ってみてください。
自分の現在位置を取得して表示するプログラム
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- 現在位置の近くにある宿を検索するサンプルプログラム
- 現在位置近くの病院を素早く検索するサンプルプログラム
- 近くにある病院の場所をキャラクターが音声で教えてくれるアプリを作る
- 場所と写真を記録するプログラムを作って思い出のシーンを保存しよう
- 写真と現在位置を入れた画像日記アプリを作る
- Bing Maps上に地震の震源地を表示するプログラムを作る
- APIを使って土地の公示価格を調べるプログラムを作る
- フリーハンドで書いた住所を認識してBing Map上に表示する
- Bing Maps上の好きな場所をマークして情報を表示するプログラムを作る
- Yahoo!ローカルサーチAPIを使って地図上にランドマークを表示させるプログラムを作る