Windows Phoneアプリケーション開発入門

第22回Bing Mapsで遊んでみよう!(3)

はじめに

11月8日にWindows Phone 7がアメリカ、カナダで発売となりました。シンガポールでの先行発売時に手に入れることのできなかった、日本のWindows Phoneファン達にも届き始めているようです。

そのほか、Windows Phone 7関係のニュースとしては、Silverlight for Windows Phone Toolkitの11月度リリースが行われました。今回のリリースの目玉はコントロールの追加です。新しく追加されたコントロールを紹介しましょう。

AutoCompleteBox

テキストを一文字入力するたびに検索結果の候補を絞り込むインクリメンタルサーチ機能を提供するコントロールです。

図1 インクリメンタルサーチ機能
図1 インクリメンタルサーチ機能
LongListSelector

インデックスの項目を選択してジャンプする機能を持ったインデックス付きリスト表現を行うコントロールです。

図2 インデックスで分割されたリストとジャンプ機能
図2 インデックスで分割されたリストとジャンプ機能
ListPicker

複数の項目から一つを選択する場合などに使用できるコントロールです。

図3 色をピックアップするリストの例
図3 色をピックアップするリストの例
Page Transitions

Roll、Rotate、Slide、Swivel、Turnstileの基本的な5パターンの画面遷移アニメーションを提供します。

図4 TurnstileとRollアニメーション
図4 TurnstileとRollアニメーション

「Silverlight for Windows Phone Toolkit - Nov 2010」は、こちらからダウンロード可能です。

地図上に線を引く

マップ上に線を引く場合は、Microsoft.Phone.Controls.Maps名前空間のMapPolylineクラスを利用します。メモリとパフォーマンスの許す限り線を引くことができます。

ただ、線を引き始める位置と終わりの位置は、緯度経度の位置情報で指定するため、複雑な線を引くのには向いていません。

  var polyline = new Microsoft.Phone.Controls.Maps.MapPolyline()
  {
      Locations = new LocationCollection(),
      Stroke = new SolidColorBrush(Colors.Red),
      StrokeThickness = 5
  };
  polyline.Locations.Add(startLocation);
  polyline.Locations.Add(endLocation);
  map1.Children.Add(polyline);
図5 地図上に線を引いてみた例
図5 地図上に線を引いてみた例

GPSのロギングを行う

前回位置情報を取得したのと同じく、GeoCoordinateWatcherクラスを使用します。正確さよりもパフォーマンスを優先させるために、GeoPositionAccuracy.Defaultを設定します。

GeoCoordinateWatcher watcher;

private void btnLocation_Click(object sender, EventArgs e)
{
    // GeoCoordinateWatcherの初期化を行う
    watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
    // 10m移動したら反応
    watcher.MovementThreshold = 10;
    
    // 位置が変更された(PositionChanged)イベントをイベントハンドラに追加する
    watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
    
    // データの取得を開始する
    watcher.Start();
}

前回の位置情報を記憶しておき、現在の位置情報との間に線を引きます。

GeoCoordinate backCoordinate;

// PositionChangedイベントハンドラから呼ばれるカスタムメソッド
void MyPositionChanged(GeoPosition<GeoCoordinate> e)
{
    // データを取得した位置を中心にする
    map1.Center = e.Location;
    
    // 現在地にピンを立てる
    var pin = new Microsoft.Phone.Controls.Maps.Pushpin()
    {
        Background = new SolidColorBrush(Colors.DarkGray),
        Location = e.Location
    };
    map1.Children.Add(pin);
    
    if (backCoordinate != null)
    {
        // 線を引く
        var polyline = new Microsoft.Phone.Controls.Maps.MapPolyline()
        {
            Locations = new LocationCollection(),
            Stroke = new SolidColorBrush(Colors.Red),
            StrokeThickness = 5
        };
        polyline.Locations.Add(backCoordinate);
        polyline.Locations.Add(e.Location);
        map1.Children.Add(polyline);
    }
    
    // 今回の位置情報を記録しておく
    backCoordinate = e.Location;
}

阪急十三駅からJR塚本駅まで移動したときのログを元に、データをシミュレータで再生させてみました。実機で上記のコードを実行すると、このような表示になると思います(GPSデバイスの精度次第で、もう少し細かい表示になるかもしれません⁠⁠。

図6 きちんと歩いたログが表示されています
図6 きちんと歩いたログが表示されています

Windows Mobile 6でGPSの位置情報を取得する

おまけにWindows Mobile 6で位置情報を取得する方法についてご紹介したいと思います。Windows Phone 7のように優れたロケーションサービスがなく、実質Over Skyでないと測地ができません。

Windows Mobile 6では、マネージコードからGPSを扱うためのクラスは標準では用意されていません。そこでWindows Mobile 6 SDKに付属しているGPS Intermediate Driverをラップしたライブラリを使用します。

ソリューションエクスプローラーから以下のプロジェクトを追加します。Visual Studio 2008を使ってWindows Mobile 6アプリケーションを開発されている方は、変換ウィザードが表示されると思いますので、変換を行ってください。

%ProgramFiles%\Windows Mobile 6 SDK\Samples\PocketPC\CS\GPS

位置情報を取得する

Windows Mobile 6アプリケーションプロジェクトから、Microsoft.WindowsMobile.Samples.Locationプロジェクトを参照しておきましょう。位置情報を取するコードを以下に示します。

GPSクラスのインスタンスを生成して、GPSデバイスのポートを開いて測地を開始します。デバイスのステータスが「GPSサービス有効」になるまで待ち、位置情報を取得しています。

このGPSクラスは内部的にCOMポートをポーティングして、GPSデバイスから吐き出された測地情報を処理し、イベントとして登録したハンドラを呼び出します。ここではイベントハンドラは登録せず、

private void button_Click(object sender, EventArgs e)
{
    Microsoft.WindowsMobile.Samples.Location.Gps gps 
        = new Microsoft.WindowsMobile.Samples.Location.Gps();
    try
    {
        // 測位を開始するためにGPSデバイスのポートを開きます
        gps.Open();
        while (gps.GetDeviceState().DeviceState != GpsServiceState.On)
        {
            // 位置情報を取得できるようになるまでウェイト
            System.Threading.Thread.Sleep(1000);
        }
        
        // 位置情報を取得
        Microsoft.WindowsMobile.Samples.Location.GpsPosition pos 
          = gps.GetPosition();
    }
    finally
    {
        // 測位を終了するためにGPSデバイスのポートを閉じます
        gps.Close();
    }
}

SDKのサンプルコードとはいえ、GPSを使った位置測地がマネージコードから扱えますので、ネイティブコードを意識しざるを得ない.NET Compact Frameworkでも簡単にGPSロガー的なアプリが作れます。

さいごに

Windows Mobile 6とWindows Phone 7で、GPSを使ったアプリケーションのTipsを紹介しました。デバイスを活用したアプリケーションは実機を使うのが一番ですね。

Microsoftは積極的にローカライズを進めていると発表しているので、2011年度には日本でも発売されるだろうと予想しています。Windows Phone 7が一般のユーザーにいかに受け入れられるかは判りませんが、2011年末には世界で3,000万台販売見込みとの予測も立てられています。この先どうなるか楽しみで仕方がありません。

以上で今回は終わりです。ありがとうございました。

おすすめ記事

記事・ニュース一覧