Windows Phone 8.1

Windows Phone 8.1 で地図を扱う

Keith Pijanowski

コード サンプルのダウンロード

Windows Phone は世代が代わるたびにマップ機能が強化されています。Windows Phone 8.1 も例外ではなく、Visual Studio 2013 Update 3 で導入された新しいマップ コントロールを備えています。特定の場所を中心に表示するシンプルな地図だけが必要なら、新しいマップコントロールとほんの数行のコードで地図を表示できます。ただし、複雑なシナリオ (ユーザーの操作に応答する、コントロールの外観をカスタマイズする、ルートを計算するなど) に対応するのであれば、新しいマップ コントロールとマップ サービス API を使うことになります。

今回は、Windows Phone 8.1 の新しいマップ コントロールとマップ サービス API を取り上げます。まず、基本的な地図表示機能を紹介します。次に、より高度な機能に進み、特定の住所から地図上の位置を求めてピンを刺す方法を示します。また、XAML のコントロールをマップ コントロールの上に重ねて表示する方法や、マップ コントロール上の特定の場所に対応する GPS 上の位置 (と住所) を求める方法についても説明します。この方法を理解すれば、ユーザーが関心のある場所をタッチしたときに、GPS 上の位置と住所を割り出せるようになります。最後に、車と徒歩によるルートをそれぞれ計算する方法を示します。

今回の内容を理解するうえで参考になるのが、2014 年 9 月号の Tony Champion の「Geofencing 機能を備えた位置認識アプリの作成」です。ジオフェンスとは特定の GPS 上の位置を中心に指定される領域で、この領域を Windows に登録できます。ジオフェンスを登録すると、デバイスがその領域に出入りする際に、アプリが通知を受け取ることができます。Geofencing も Windows Phone 8.1 の新機能です。Geofencing 機能を利用するアプリをビルドする場合は、マップ コントロールを使用して、ユーザーがジオフェンスを指定でき、登録済みのジオフェンスを表示できるようにすることをお勧めします。

本稿執筆時点では、モバイルおよびタブレット プラットフォームの種類ごとにマップ コントロールが異なります。

  • Windows Phone Silverlight 8.0/8.1 アプリの場合: Microsoft.Phone.Maps.Controls.Map
  • Windows Store 8.x アプリの場合: Bing.Maps.Map
  • Windows Phone 8.1 ランタイム アプリの場合: Windows.UI.Xaml.Controls.Maps

ここでは、Windows Phone 8.1 ランタイム用に作成するアプリに使用できる新しいマップ コントロールとマップ サービスに注目します。

作業の開始

アプリを認証する Windows Phone アプリは、マップ コントロールまたは Windows.Services.Maps 名前空間のマップ サービスを使用するたびに、毎回認証を受ける必要があります。アプリが認証を受けるには、マップ サービスのアプリケーション ID (ApplicationID) と、マップ サービスの認証トークン (AuthenticationToken)が必要です。どちらも、Windows Phone デベロッパー センターの開発者ダッシュボードから取得できます。ApplicationID と AuthenticationToken を取得する詳細な手順については、MSDN ライブラリの記事 (bit.ly/1y78M2F、英語) を参照してください。

これらを取得したら、ApplicationID をアプリの Package.appxmanifest ファイル内で指定します。その手順も、先ほどの MSDN ライブラリの記事に記載されています。マップ サービスの認証トークンは、コード内で使用します。これについては、後ほど説明します。

機能 今回のサンプルの多くは、ユーザーの現在位置を使用します。また、マップ コントロールにはインターネット接続が必要になる可能性があります。したがって、アプリのマニフェスト ファイルでインターネット機能と位置情報機能を宣言します (図 1 参照)。ただし、マップ サービスは、オフラインで操作できるように、地図がダウンロードされていればインターネット接続なしでも機能します。地図のダウンロードの詳細については、「オフライン地図のダウンロードおよび更新方法 (XAML)」(bit.ly/1nXBOrS、英語) を参照してください。

インターネット機能と位置情報機能の宣言
図 1 インターネット機能と位置情報機能の宣言

地図を表示する

シンプルな地図を表示する 他のコントロールと同様、マップ コントロールも簡単にページに追加できます。Visual Studio ツールボックスからマップ コントロールをページにドラッグするか、以下の XAML を入力します。

<Maps:MapControl
  x:Name="myMapControl"
  MapServiceToken="Place your token here."
  Height="200" Width="300"
  HorizontalAlignment="Center"
  Margin="0,0,0,12"
  />

MapServiceToken プロパティに注目してください。このプロパティには、Windows Phone デベロッパー センターの開発者ダッシュボードでアプリに割り当てたマップ サービスの認証トークンの値を設定します。また、他のコントロールと同様、マップ コントロールも位置を調整できます。マップ コントロールを、画面全体に表示する必要はありません。特定の場所にズームインした小さな地図でも、場所固有の情報を含むページでは効果的なビジュアル要素になります。一方、ズームアウトした地図 (または、ユーザーがズームアウトした地図) は、表示領域を広めに取るようにします。できれば、ページ全体を使用します。

上記の XAML をアプリに挿入して実行すると、何の変哲もない結果になります。このコントロールには、完全にズームアウトした地図が表示されます。そこで、マップ コントロールを使用する次の作業として、特定の場所を地図の中心に据え、ズームレベルを指定します。

以下は、最初にユーザーの現在位置を計算し、次にその位置を地図の Center プロパティに設定するコードです。また、このコードでは、ズーム レベルを 15 に設定しています。ズーム レベルの最小値は 1 です。設定が 1 の場合、地図は完全にズーム アウトされ、マップ コントロール内に地球の半分が表示されます。ズーム レベルの最大値は 20 で、マップ コントロールは特定の住所にズーム インして表示されます。

Geolocator geolocator = new Geolocator();
Geoposition geoposition = null;
try
{
  geoposition = await geolocator.GetGeopositionAsync();
}
catch (Exception ex)
{
  // Handle errors like unauthorized access to location
  // services or no Internet access.
}
myMapControl.Center = geoposition.Coordinate.Point;
myMapControl.ZoomLevel = 15;

マップ コントロールに画像を追加する マップ上の特定の場所に印を付ける場合は、タイトルを付けて画像をマップ コントロールに追加できます。図 2 のコードは、プロジェクトの Assets フォルダーの画像をマップ コントロールに追加して、デバイスの現在位置を示しています。

図 2 マップ コントロールへのカスタム画像の追加

Geolocator geolocator = new Geolocator();
Geoposition geoposition = null;
try
{
  geoposition = await geolocator.GetGeopositionAsync();
}
catch (Exception ex)
{
  // Handle errors like unauthorized access to location services or no Internet access.
}
MapIcon mapIcon = new MapIcon();
mapIcon.Image = RandomAccessStreamReference.CreateFromUri(
  new Uri("ms-appx:///Assets/PinkPushPin.png"));
mapIcon.NormalizedAnchorPoint = new Point(0.25, 0.9);
mapIcon.Location = geoposition.Coordinate.Point;
mapIcon.Title = "You are here";
myMapControl.MapElements.Add(mapIcon);

マップ コントロールに画像を追加するには、まず、MapIcon オブジェクトを作成し、そのオブジェクトの Location プロパティに、地図上の目的の場所を表す Geopoint を設定します。図 2 のコードは、ユーザーの現在位置を使用しています。Title プロパティは、マップ コントロールに追加する画像の上に表示するテキストです。

画像を指定するには、RandomAccessStreamReference.CreateFromUri メソッドを使って、MapIcon の Image プロパティを設定します。これは、Windows.Storage.Streams 名前空間の静的メソッドです。画像は約 50 x 50 ピクセルにします。それよりも大きいと、縮小されます。

特定の位置を示すことが画像の目的である場合、ベスト プラクティスの 1 つは、MapIcon の NormalizedAnchorPoint プロパティを使用することです。このプロパティを使うと、指定した Geopoint に配置する画像内の位置を指定できます。画像がピンの場合、これをピンの先端にし、矢印の画像の場合は、矢印の先端にします。NormalizedAnchorPoint プロパティの既定値は、画像の左上隅を表す (0, 0) を値として作成された Point オブジェクトです。画像の右下隅を示す値は (1,1) です。図 3 に、サンプルの座標を付けてこの座標系を示します。

NormalizedAnchorPoint プロパティに使用する座標系
図 3 NormalizedAnchorPoint プロパティに使用する座標系

マップ アイコンとして使用する画像にポインターが含まれている場合、NormalizedAnchorPoint プロパティを正しく設定しないと、マップ アイコンが地図上の正しくない位置を指すことになります。画像が単に点や小さな円の場合は、画像の中心を表す (0.5,0.5) を値に使用するようにします。

画像を指定しないと、MapControl の既定の画像が表示されます (図 4 参照)。

既定のマップ アイコン
図 4 既定のマップ アイコン

既定の MapIcon 画像は、画像の下部中央にポインターがあります。したがって、NormalizedAnchorPoint プロパティは (0.5, 1.0) に設定する必要があります。

もう 1 つこのコードで注目すべき点は、MapIcon オブジェクトをマップ コントロールの MapElements コレクションに追加していることです。このため、必要に応じて、複数の MapIcon を地図に追加できます。

マップ アイコンとタイトルが表示される保証はありません。地図上の他の要素やラベルの邪魔になる場合は、表示されない可能性があります。特に、地図がズームアウトし (ズーム レベルが低くなり)、マップ コントロール内に表示する情報が増えた場合は非表示になることがあります。

図 2 のコードは、フェンウェイ・パークで野球の試合を観戦していると想定して、図 5 の地図を表示しています。

マサチューセッツ州ボストンにあるフェンウェイ・パークを示すマップ コントロール
図 5 マサチューセッツ州ボストンにあるフェンウェイ・パークを示すマップ コントロール

マップ コントロールにコントロールを追加する マップ コントロールに XAML コントロールを追加する手順は、画像を追加する手順と似ています。次のコードは楕円を作成し、サイズを指定することで円に変え、この円をマップ コントロールに追加して、円の中心を地理座標に設定しています。

// Create a circle
Windows.UI.Xaml.Shapes.Ellipse fence = 
  new Windows.UI.Xaml.Shapes.Ellipse();
fence.Width = 30;
fence.Height = 30;
fence.Stroke = new SolidColorBrush(Colors.DarkOrange);
fence.StrokeThickness = 2;
MapControl.SetLocation(fence, geoposition.Coordinate.Point);
MapControl.SetNormalizedAnchorPoint(fence, new Point(0.5, 0.5));
myMapControl.Children.Add(fence);

楕円オブジェクトに地理座標をアタッチするには、マップ コントロールの静的関数 SetLocation を使う必要があります。同様に、NormalizedAnchorPoint プロパティをアタッチするには SetNormalizedAnchorPoint を使います。

UIElement または MapItemsControl を継承するすべてのコントロールは、この手法を使ってマップ コントロールに追加できます。

位置を求める

マップ コントロールの心臓部は BasicGeoposition オブジェクトです。このオブジェクトは、緯度、経度、高度の 3 つの数値だけで地球上のあらゆる位置を表します。この方法は、効率的に地球を区分できるだけでなく、正確でもあります。すべての場所は、の緯度、経度、高度の一意の組み合わせで表せます。2 つとして、同じ組み合わせになることはありません。

残念ながら、アプリは人間を相手にし、人間は数値だけで場所を表されることを好みません。したがって、地球は大陸、各大陸内の国々、各国内の地域 (都道府県など)、各地域内の市町村、各市町村内の番地などの区分に細分化されます。大陸名や国名、郵便番号は一意ですが、地域には同じ名前の複数の市町村が含まれる場合があります。さらに、市町村には、同じ名前の複数の通りやビルなどがある場合があります。つまり、同じ住所でも、複数の場所が誤って参照される可能性があります。特に、住所表記が不完全な (市町村名や郵便番号、番地が抜けている) 場合は、場所の混同が起きる可能性が高くなります。

したがって、アプリが、デバイスから直接取得できるユーザーの現在位置以外の位置情報も表示する場合は、緯度、経度、高度の値と、前述の住所表記間での変換が必要になります。住所を地理情報に変換する処理をジオコーディングといい、地理情報を人間が理解できる住所に変換する処理を逆ジオコーディングといいます。

住所を地理情報に変換する (ジオコーディング) 住所のジオコーディングには、マップ サービス API (Windows.Services.Maps 名前空間に含まれるクラスのコレクション) を使用します。これらの API 使用するには、MapService クラスの ServiceToken 静的プロパティに認証トークンを設定する必要があります。次のコードは、その方法を示しています (ここからは、このコード行がアプリの OnLaunched イベント内にあることを前提に話を進めます)。

MapService.ServiceToken = "Place your token here";

認証トークンを設定したら、MapLocationFinder クラスにある FindLocationsAsync 静的関数を使用します。FindLocationsAsync 関数は次のように使用します。

Geolocator geolocator = new Geolocator();
Geoposition currentPosition = await geolocator.GetGeopositionAsync();

MapLocationFinderResult result = await MapLocationFinder.FindLocationsAsync(
  address, currentPosition.Coordinate.Point, 5);

FindLocationsAsync 関数の最初のパラメーターは、住所を表す文字列です。この関数には、どんな文字列でも渡すことができます。FindLocationsAsync が通信するバックエンドのマップ サービスによって、対応する位置が検索されます。2 つ目のパラメーターは参照ポイントと呼ばれ、マップ サービスが検索を開始する地理的な場所を表します。このパラメーターは、ヒントと呼ばれることもあります。適切に使うと、返される位置の関連性と計算速度を大幅に向上できます。たとえば、ユーザーがローカル検索を実行することがわかっている場合は、ユーザーの現在位置を参照ポイントとして渡します。ただし、ユーザーが休暇の計画を立てていることがわかっている場合は、ホテルの位置を渡します。最後のパラメーターは、返される位置情報の最大数です。

FindLocationsAsync 関数の戻り値は、MapLocationFinderResult 型のオブジェクトです。これは、検索が成功したかどうかを示します。検索が成功した場合、MapLocationFinderResult オブジェクトには MapLocation オブジェクトのコレクションが保持されます。図 6 のコードは、検索が成功したかどうかを確認し、成功している場合は、コレクションを ListView コントロールに格納して、条件に一致したすべての位置情報をユーザーに表示します。MapLocation オブジェクトには、人間が理解できる住所情報と、MapControl によって使われる地理情報が保持されています。図 6 のコードを簡単に変換して、マップ コントロール上にピンを表示することもできます。

図 6 位置検索の結果の取得

if (result.Status == MapLocationFinderStatus.Success)
{
  List<string> locations = new List<string>();
  foreach (MapLocation mapLocation in result.Locations)
  {
    // create a display string of the map location
    string display = mapLocation.Address.StreetNumber + " " +
      mapLocation.Address.Street + Environment.NewLine +
      mapLocation.Address.Town + ", " +
      mapLocation.Address.RegionCode + "  " +
      mapLocation.Address.PostCode + Environment.NewLine +
      mapLocation.Address.CountryCode;
    // Add the display string to the location list.
    locations.Add(display);
  }
  // Bind the location list to the ListView control.
  lvLocations.ItemsSource = locations;
}
else
{
  // Tell the user to try again.
}

地理的な位置情報を住所に変換する (逆ジオコーディング) 他にマップ アプリで提供できる便利な機能として、マップ コントロール上でタッチされた領域から人間が理解できる住所を求める機能があります。この機能をコーディングするには、まず、ユーザーがタッチしたコントロールの位置を取得する手段が必要です。これは、マップ コントロールの MapTapped イベントを使って実現できます。マップ コントロールには マップ コントロールの XAML 子要素がタップされると発生する Tapped イベントもあります。マップ コントロールを直接タップすると、必ず MapTapped イベントが発生します。図 7 のコードは、タップされた位置の住所を TextBlock コントロールに表示する MapTapped イベントの実装を表しています。

図 7 マップ コントロール上でタップされた位置の住所の検索

private async void myMapControl_MapTapped(MapControl sender, 
  MapInputEventArgs args)
{
  // Find the address of the tapped location.
  MapLocationFinderResult result =
    await MapLocationFinder.FindLocationsAtAsync(args.Location);
  if (result.Status == MapLocationFinderStatus.Success)
  {
    if (result.Locations.Count > 0)
    {
      string display = result.Locations[0].Address.StreetNumber + " " +
        result.Locations[0].Address.Street;
      tbAddress.Text = display;
    }
  }
}

この MapTapped イベントの実装で、詳しく説明しておいた方がよい点がいくつかあります。1 つ目は、タップされた位置に関連付けられている Geopoint が args.Location を介して渡される点です。FindLocationsAtAsync 関数はこの Geopoint を使うことで、人間が理解できる住所を取得できます。この関数は、マップ サービス API (Windows.Services.Maps 名前空間) に含まれる MapLocationFinder クラスの静的関数です。この関数は、Status プロパティと MapLocation オブジェクトのコレクションを保持している MapLocationFinderResult オブジェクトを返します。MapLocation オブジェクトのコレクションを戻り値として受け取ることができますが、通常は、MapLocation オブジェクトは 1 つだけになります。ただし、複数の住所 (番地など) が関連付けられている高層ビルは世界のどこかしらにあります。ユーザーが広大な領域や湖の中心をクリックしても、値が返されます。付近に番地や町レベルの実際の住所がない場合、MapLocation オブジェクトは、地域 (都道府県)、国、郵便番号のみを保持します。

ルート

マップ サービスでは、指定された出発地から目的地までのルートを計算できます。マップ コントロール自体もルートを表示でき、このルートは自動車ルートとしても徒歩ルートとしても計算できます。

自動車ルート 名前が示すように、自動車ルートは何かしらの乗り物を運転して移動することを前提としたルートで、一方通行を逆走しないなど、すべての交通規則に従う必要があります。図 8 のコードは、ニューヨークのグランド セントラル駅からセントラル パークまでの自動車ルートを計算しています。

図 8 自動車ルートの計算

// Start at Grand Central Station.
BasicGeoposition startLocation = new BasicGeoposition();
startLocation.Latitude = 40.7517;
startLocation.Longitude = -073.9766;
Geopoint startPoint = new Geopoint(startLocation);
// End at Central Park.
BasicGeoposition endLocation = new BasicGeoposition();
endLocation.Latitude = 40.7669;
endLocation.Longitude = -073.9790;
Geopoint endPoint = new Geopoint(endLocation);
// Get the route between the points.
MapRouteFinderResult routeResult =
await MapRouteFinder.GetDrivingRouteAsync(
  startPoint,
  endPoint,
  MapRouteOptimization.Time,
  MapRouteRestrictions.None,
  290);

このコードはいたって簡単です。MapRouteFinder.GetDrivingRouteAsync 静的関数に出発地、目的地、最適化パラメーター (後述)、制限を指定するパラメーター (こちらも後述) を渡します。5 番目と最後のパラメーターは、コンパスの度数 (0 度が北、180 度が南など) で表した現在のユーザーの方向を指定する省略可能な針路です。これは、運転中にルートを計算する場合に便利です。針路パラメーターを使用すると、ルートはユーザーが現在移動している方向を基に計算されます。ルートの最初の数区間には、ユーザーをできる限り最適なルートに誘導する最適経路が含まれます。これは、一方通行の道を逆走する可能性がある都市部で特に便利です。図 8 のコードは針路を 135 に変更して、違反のない道が含まれるようにルートを計算して、ルート案内を変更しています。

MapRouteFinder.GetDrivingRouteAsync 関数の結果が返されたら、検証する必要があります。ルートが正常に取得されている場合は、道案内の指示として表示します。ルートは、マップ コントロール内に視覚的に表示することもできます。図 9 のコードは、グランド セントラル駅からセントラル パークまでの道案内の指示を表示しています。

図 9 ルートの区間および最適経路のループ処理

if (routeResult.Status == MapRouteFinderStatus.Success)
{
  // Use the route to initialize a MapRouteView.
  MapRouteView viewOfRoute = new MapRouteView(routeResult.Route);
  viewOfRoute.RouteColor = Colors.Blue;
  viewOfRoute.OutlineColor = Colors.Blue;
  // Add the new MapRouteView to the Routes collection
  // of the MapControl.
  MapwithDrivingRoute.Routes.Add(viewOfRoute);
  // Fit the MapControl to the route.
  await MapwithDrivingRoute.TrySetViewBoundsAsync(
    routeResult.Route.BoundingBox,
    null,
    Windows.UI.Xaml.Controls.Maps.MapAnimationKind.Bow);
}

MapRoute オブジェクトには、ルートの所要時間と、メートル単位での距離を示す概要情報が保持されます。MapRoute オブジェクトは、MapRouteLeg オブジェクトと MapRouteManeuver オブジェクトを使って、ルート情報を整理します。MapRoute には 1 つ以上の MapRouteLeg オブジェクトがあり、各 MapRouteLeg には 1 つ以上の MapRouteManeuver オブジェクトがあります。ユーザーに表示する情報は、MapRouteManeuver オブジェクトに保持されています。MapRouteManeuver オブジェクトには、道案内の指示と、出口の情報 (該当する場合)、最適経路の距離、最適経路の通知 (該当する場合) が保持されています。Kind プロパティもとても便利です。サンプルの値には、左折、右折などがあります。このプロパティを使って、各最適経路に画像を関連付けることができます。Kind プロパティに設定できる値の全リストについては、bit.ly/1nXOyi7 (英語) を参照してください。図 10 は、アプリで表示したルート案内のようすを示しています。

自動車ルートのルート案内
図 10 自動車ルートのルート案内

ルートは、マップ コントロール内にグラフィカルに表示することもできます (図 11 参照)。

図 11 マップ コントロールでのルートの視覚的な表示

// Display summary info about the route.
tbTurnByTurn.Inlines.Add(new Run()
{
  Text = "Total estimated time (minutes) = "
    + routeResult.Route.EstimatedDuration.TotalMinutes.ToString("F1")
});
tbTurnByTurn.Inlines.Add(new LineBreak());
tbTurnByTurn.Inlines.Add(new Run()
{
  Text = "Total length (kilometers) = "
    + (routeResult.Route.LengthInMeters / 1000).ToString("F1")
});
tbTurnByTurn.Inlines.Add(new LineBreak());
// Display the directions.
tbTurnByTurn.Inlines.Add(new Run()
{
  Text = "DIRECTIONS"
});
tbTurnByTurn.Inlines.Add(new LineBreak());
// Loop through the legs and maneuvers.
int legCount = 0;
foreach (MapRouteLeg leg in routeResult.Route.Legs)
{
  foreach (MapRouteManeuver maneuver in leg.Maneuvers)
  {
    tbTurnByTurn.Inlines.Add(new Run()
    {
      Text = maneuver.InstructionText
    });
    tbTurnByTurn.Inlines.Add(new LineBreak());
  }
}

マップ コントロールにルートを表示するには、まず MapRouteView クラスを使ってルートのビューを作成します。ビューを作成したら、マップ コントロールの Routes コレクションに追加します。最後に、マップ コントロールの TrySetViewBoundsAsync 関数によって、マップ コントロールのサイズを調整し、ルート全体が表示されるようにします。この関数には、マップ コントロールがルート全体を表示するために再描画される際に、視覚効果を適用するアニメーション パラメーターもあります。図 12 は、これをアプリで表示したようすを示しています。

マップ コントロールに表示した自動車ルート
図 12 マップ コントロールに表示した自動車ルート

ルートの最適化 自動車ルートは、時間、距離、交通量に関して最適化できます。MapRouteOptimization 列挙型は、ルート計算の最適化に使われるこれらの値を提供します (図 13 参照)。

図 13 MapRouteOptimization 列挙型

Time ルートの各最適経路の距離と速度制限を踏まえて、所要時間が最も短くなるようにルートを最適化します。
Distance 各最適経路の距離を踏まえて、距離が最短になるようにルートを最適化します。
TimeWithTraffic ルートの各最適経路の距離と速度制限、および現在の交通状況を踏まえて、所要時間が最も短くなるようにルートを最適化します。

 

ルートの制限 自動車ルートは「高速道路を利用しない」や「有料道路は利用しない」などの制限を設けて計算することもできます。MapRouteRestrictions 列挙型は、ルート計算の制限に使われるこれらの値を提供します (図 14 参照)。

図 14 MapRouteRestrictions 列挙型

None ルートの計算に制限が適用されません。ルートには、高速道路、トンネル、フェリー有料道路、未舗装の道路を含む最適経路が含まれます。
Highways ルートには、高速道路を利用する最適経路が含まれます。
TollRoads ルートには、有料道路を利用する最適経路が含まれます。
Ferries ルートには、フェリーを利用する必要がある最適経路が含まれます。
Tunnels ルートには、トンネルを通過する最適経路が含まれます。
DirtRoads ルートには、未舗装道路を通る最適経路が含まれます。

 

これらの値は、論理的に組み合わせることができます。たとえば、次のコードは、高速道路と有料道路を利用しない制限を適用します。

MapRouteFinderResult routeResult =
  await MapRouteFinder.GetDrivingRouteAsync(
  startPoint,
  endPoint,
  MapRouteOptimization.Time,
  MapRouteRestrictions.Highways || MapRouteRestrictions.TollRoads);

徒歩ルート 徒歩ルートの計算は、自動車ルートの計算と非常によく似ています。次のコードでは、自動車ルートの例と同じ目的地までの徒歩ルートを計算しています。

// Get the route between the points.
MapRouteFinderResult routeResult =
  await MapRouteFinder.GetWalkingRouteAsync(
  startPoint,
  endPoint);

この計算には、MapRouteFinder.GetWalkingRouteAsync 静的関数を使用します。自動車ルートの計算に使用する関数と異なり、この関数には最適化、制限、または現在の針路を指定するオーバーロードはありません。速度制限や交通状況は徒歩ルートには関係ないため、これらの属性は徒歩ルートの計算には影響しません。また、現在の針路も容易に変更できます。徒歩ルートは、最短距離になるように計算されます。図 15図 16 の画像は、グランド セントラル駅からセントラル パークまでの徒歩ルートです。

徒歩ルートのルート案内
図 15 徒歩ルートのルート案内

マップ コントロール内に表示された徒歩ルート
図 16 マップ コントロール内に表示された徒歩ルート

まとめ

今回は、基本的な地図の表示、画像やコントロールの追加方法など、Windows Phone 8.1 向けの使い方を説明しました。また、基盤となるマップ サービス API を紹介し、ジオコーディングと逆ジオコーディング 、ルート計算についても説明しました。

タイル画像を重ねた表示、データ バインド、オフライン マップの管理など、マップに関するその他のさまざまなトピックも考えてみてください。これらのトピックの詳細は、Windows デベロッパー センター (bit.ly/X7S7ei、英語) にあります。


Keith Pijanowski はソフトウェア業界で 20 年以上の経験があります。新興企業や大企業で、コード作成から事業開発まで、さまざまな職務に携わってきました。現在は、独立系コンサルタントとして個人で事業を営んでいます。ニューヨーク市のエリアに住んでいますが、ニューヨークのスポーツ チームを応援したことはありません。連絡先は keithpij@msn.com または twitter.com/keithpij です。

この記事のレビューに協力してくれたマイクロソフト技術スタッフの Mike O’Malley に心より感謝いたします。
Mike O’Malley は、マイクロソフトのオペレーティング システム部門のシニア プログラム マネージャーです。マイクロソフトで 3 年間、マップ関連の開発者向けエクスペリエンスに取り組んでいて、毎年 Build で位置認識アプリ開発について発表しています。