酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

WindowsストアアプリでGeolocator(GPS/位置情報測位)を使って位置座標を取得する

概要

Windowsストアアプリには、ロケーションサービスが用意されています。

ロケーションサービスは位置情報を扱う仕組みで、GPSデバイス、WiFi、3Gの通信基地局の情報から非常に精度の高い位置情報を取得します。取得した緯度(latitude)と経度(longitude)の位置測位するのに使用したり、現在地の郵便番号を含めて住所等を取得することができます。

名前空間:Windows.Devices.Geolocation
  • System.Object
    • Windows.Devices.Geolocation.Geolocator

Tips

現在の位置情報を1回だけ取得する

Windowsストアアプリには、ロケーションサービスが用意されています。

ロケーションサービスは位置情報を扱う仕組みで、GPSデバイス、WiFi、3Gの通信基地局の情報から非常に精度の高い位置情報を取得します。取得した緯度(latitude)と経度(longitude)の位置測位するのに使用したり、現在地の郵便番号を含めて住所等を取得することができます。

現在地を取得するためには、Windows.Devices.Geolocation名前空間の`Geolocatorクラス`を利用します。usingディレクティブに「Windows.Devices.Geolocation」を追加しておいてください。

using Windows.Devices.Geolocation;

下記のサンプルコードでは、テスト的に配置されたボタンがクリックされた時に、Geolocatorインスタンスの生成をおこない、現在位置の取得をおこないます。

using System;
using System.Diagnostics;
using Windows.Devices.Geolocation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace GeolocatorSample
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private async void Button_Click_1(
            object sender, RoutedEventArgs e)
        {
            GetGeopositionAsync();
        }
    }
}

ボタンが押されると`GetGeopositionAsyncメソッド`を実行します。

private async void GetGeopositionAsync()
{
    var geolocator = new Windows.Devices.Geolocation.Geolocator();
    try
    {
        var timeout = TimeSpan.FromSeconds(30);

        // 現在の位置情報を取得する
        var pos = await geolocator.GetGeopositionAsync(
            TimeSpan.FromMinutes(1), timeout);

        // 現在位置の国名を取得する
        var country = pos.CivicAddress.Country;
    
        // 現在位置の郵便番号を取得する
        var postalCode = pos.CivicAddress.PostalCode;
    
        // 測位した現在地の精度を取得する(単位:メートル)
        var accuracy = pos.Coordinate.Accuracy;
    
        // 現在の経度を取得する
        var position = pos.Coordinate.Point.Position;
        var longitude = position.Longitude;
    
        // 現在の緯度を取得する
        var latitude = position.Latitude;
    
        // 現在の高度を取得する
        var altitude = position.Altitude;

        Debug.WriteLine("country:{0}", country);
        Debug.WriteLine("postalCode:{0}", postalCode);
        Debug.WriteLine("accuracy:{0}", accuracy);
        Debug.WriteLine("longitude:{0}", longitude);
        Debug.WriteLine("latitude:{0}", latitude);
        Debug.WriteLine("altitude:{0}", altitude);
    
        // 出力結果
        // country:JP
        // postalCode:
        // accuracy:350
        // longitude:139.573199
        // latitude:35.658944
        // altitude:0
    }
    catch (System.UnauthorizedAccessException)
    {
        // 失敗:マニフェストで「場所」の機能が有効になっていない
        // ユーザーがランタイムから「場所」をアクセスするのを拒否している
    }
    catch (TaskCanceledException)
    {
        // 失敗:キャンセルされたか、タイムアウトしました
    }
}

### 連続して位置情報を取得する(移動しながら位置情報を更新したい)

カーナビやGPSロガーのように、常に最新の位置情報を取得し表示したり記録したりする場合、または目的地付近に近づいたことをユーザーへ知らせる場合など、連続して位置情報を取得したい場合、PositionChangedイベントを使用します。

画面突入時に呼ばれるOnNavigatedToメソッドにて、Geolocatorオブジェクトを生成し、位置が変わったら発生するPositionChangedイベントにイベントハンドラを関連付けします。

Geolocator geolocator = null;

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    // Geolocatorオブジェクトを生成する
    if (geolocator == null)
    {
        geolocator = new Geolocator();
    }
    // 位置が変わったら発生するPositionChangedイベントに
    // イベントハンドラを関連付ける
    geolocator.PositionChanged += geolocator_PositionChanged;
}

PositionChangedイベントが発生するたびに実行されるgeolocator_PositionChangedメソッドでは、以下のように位置情報を取得します。

void geolocator_PositionChanged(
    Geolocator sender, PositionChangedEventArgs args)
{
    // 位置情報から地理的情報を取得する
    var coordinate = args.Position.Coordinate;

    var position = args.Position.Coordinate.Point.Position;

    // 緯度・経度・精度をログを出力する
    Debug.WriteLine("Latitude(緯度): {0} Longitude(経度): {1} 精度: {2}"
        , position.Latitude, position.Longitude, pos.Coordinate.Accuracy);
}

画面遷移してしまうと位置情報が必要なくなる場合が多いと思います。OnNavigatedFromメソッドでPositionChangedイベントが発生してもgeolocator_PositionChangedが呼ばれないようにします。

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    geolocator.PositionChanged -= geolocator_PositionChanged;
}
「場所」の機能を有効にする

ユーザーが想定していない使われ方を防ぐために、Windowsストアアプリでは使用する機能を明示的に提示して、さらに実行時にユーザーの許諾を取る必要があります。

ユーザーの許諾を取るのこと自体はOS側でやってもらえます。使用する機能を明示的に提示するのは、本記事で紹介するアプリケーション内で位置情報を使用する場合においても同様です。

ソリューション・エクスプローラーのPackage.appxmanifestをダブルクリックします。

f:id:ch3cooh393:20140922135059p:plain

マニュフェストファイルを開くといくつかタブが存在しています。この中から「機能」を選択します。

f:id:ch3cooh393:20140922135118p:plain

場所のチェックを有効にする。

f:id:ch3cooh393:20140922135139p:plain