Windows Phone 8.1

Windows Phone 8.1 マップ コントロールにアプリ データを追加する

Keith Pijanowski

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

11 月号の Windows Phone 8.1 の地図機能についてのコラムでは、Windows Phone 8.1 のマップ コントロールとマップ サービス API を紹介しました。そこでは、マップ コントロールを使って Windows Phone アプリに地図機能を追加し、画像を追加して特定の場所を示す方法、指定された住所の地理座標を計算する (ジオコーディング) 方法、指定された地理座標の住所を特定する (逆ジオコーディング) 方法、車と徒歩によるルートを提供する方法などを取り上げしました。

今回は、XAML を使用してコントロールをマップ コントロールに追加し、追加したコントロールにアプリ データをバインドすることで、マップ コントロールにアプリ データを読み込む方法を説明します。アプリをオフラインで使用する場合は、マップ コントロールもオフラインで使用できるように、コントロールの基になるデータもダウンロードします。その結果、アプリのオフライン機能でもマップ コントロールを利用できるようになります。また、マップ コントロールをオフラインにして、オフラインのデータを最新状態に保つ方法についても説明します。

XAML を使用してマップ コントロールにコントロールを追加する

前回は、地図上の特定の場所を円で囲むため、コードを使用して楕円コントロールを地図に追加しました。これは、完全に制御が必要な場合は有効なアプローチです。ただし、創造性を発揮して、地図に各種コントロールを注釈として付ける場合は、コードの使用はスマートではありません。XAML を使って地図にコントロールを追加する方が効率的です。また、データ バインドを使用して地図内の複数の場所にマッピングする場合は、XAML を使う方がはるかに簡単です。

最初に、XAML を使ってコントロールを追加する方法と、追加したコントロールにアプリ データをバインドする方法を示します。次に、データ バインドについてさらに踏み込み、場所のコレクションをマップ コントロールにバインドする方法を説明します。

XAML の基本コントロールの追加: アプリ データを地図に追加するために、マップ コントロールにコントロールを追加する方法は 2 とおりあります。1 つはマップ コントロールに子コントロールを追加する方法、もう 1 つは MapItemsControl にコントロールを含める方法です。

図 1 は、マップ コントロールに子コントロールを追加する方法を示しています。Children プロパティはマップ コントロールの既定のコンテンツ プロパティなので、XAML マークアップで明示的に指定する必要はありません。図 2 は、MapItemControl にコントロールを含めるもう 1 つの方法を示しています。

図 1 マップ コントロールに子コントロールを追加する

<Maps:MapControl
  x:Name="myMapControl" Grid.Row="1"
  MapServiceToken="{StaticResource MapServiceTokenString}" >
  <!-- Progress bar which is used while the page is loading. -->
  <ProgressBar Name="pbProgressBar" IsIndeterminate="True" Height="560"
    Width="350" />
  <TextBlock Name="tbMessage" Text="{Binding Message}"
    Maps:MapControl.Location="{Binding Location}"  
    Maps:MapControl.NormalizedAnchorPoint="1.0,1.0"
    FontSize="15" Foreground="Black" FontWeight="SemiBold"
    Padding="4,4,4,4"
    Visibility="Collapsed"
    />
  <Image Name="imgMyLocation" Source="Assets/PinkPushPin.png"
    Maps:MapControl.Location="{Binding Location}"
    Maps:MapControl.NormalizedAnchorPoint="0.25, 0.9"
    Height="30" Width="30"
    Visibility="Collapsed" />
</Maps:MapControl>

図 2 MapItemControl にコントロールを含める

<Maps:MapControl
  x:Name="myMapControl"
  MapServiceToken="{StaticResource MapServiceTokenString}">
  <Maps:MapItemsControl>
    <TextBlock Name="tbAddress" Text="{Binding Message}"
      Maps:MapControl.Location="{Binding Location}"
      Maps:MapControl.NormalizedAnchorPoint="1.0,1.0"
      Visibility="Collapsed" />
    <Image Name="imgMyLocation" Source="Assets/PinkPushPin.png"
      Maps:MapControl.Location="{Binding Location}"
      Maps:MapControl.NormalizedAnchorPoint="0.25, 0.9"
      Height="30" Width="30"
      Visibility="Collapsed"/>
  </Maps:MapItemsControl>
</Maps:MapControl>

図 2 の MapItemControl の手法を使用する場合は、分離コード内ではコントロールにアクセスできないことに注意してください。コントロール名は IntelliSense によって有効な変数として認識されますが、実行時にはこれらの変数は常に Null になり、参照すると NullReferenceException が返されます。MapItemControl は、通常、オブジェクトのコレクションをマップ コントロールにバインドするために使用します (後ほど説明します)。したがって、オブジェクトのコレクションにバインドしない場合は、図 1 のようにマップ コントロールに子コントロールを追加する方法をお勧めします。

データ バインド: 図 1 のコードでは、データ バインドを使って、Image コントロールと TextBloack の両方の Location プロパティを設定しています。TextBlock の Text プロパティでも、データ バインドを使用しています。簡単に復習すると、Location プロパティは Geopoint 型の添付プロパティです。このプロパティは、コントロールを配置する地図上の位置を指定するために使用します。NormalizedAnchorPoint 添付プロパティを使うと、コントロールの位置を微調整できます。たとえば、NormalizedAnchorPoint プロパティを使って、任意の場所の中心や左上隅にコントロールを配置できます。どちらのプロパティも、前回 (msdn.microsoft.com/magazine/dn818495) 詳しく説明しました。

データ バインドによって、基になるオブジェクトから XAML コントロールに値を取得できるようになります。図 1 の XAML コントロールに必要な値の保持には、次のクラスによって作成されたオブジェクトを使用します。

public class LocationEntity
{
  public Geopoint Location { get; set; }
  public string Message { get; set; }
}

図 3 は、図 1 のコントロールを保持するページの OnNavigatedTo イベント全体を示しています (アプリのページまたはビューにかなりの準備が必要な場合は、ビュー モデルの作成にこのコードを含めて、非同期に実行することを検討します)。このコードは、短いメッセージを付けて、LocationEntity クラスのインスタンスにデバイスの現在位置を設定します。LocationEntity オブジェクトを、マップ コントロールの DataContext プロパティに設定しているのがわかります。

図 3 データ バインドに必要なオブジェクトを作成する OnNavigatedTo イベント

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
  // Call the navigation helper base function.
  this.navigationHelper.OnNavigatedTo(e);
  // Get the user's current location so that it can be
  // used as the center point of the map control.
  Geolocator geolocator = new Geolocator();
  // Set the desired accuracy.
  geolocator.DesiredAccuracyInMeters = 200;
  // The maximum acceptable age of cached location data.
  TimeSpan maxAge = new TimeSpan(0, 2, 0);
  // Timeout used for the call to GetGeopositionAsync.
  TimeSpan timeout = new TimeSpan(0, 0, 5);
  Geoposition geoposition = null;
  try
  {
    geoposition = await geolocator.GetGeopositionAsync(maxAge, timeout);
  }
  catch (Exception)
  {
    // Add exception logic.
  }
  // Set up the LocationEntity object.
  LocationEntity locationEntity = new LocationEntity();
  locationEntity.Location = geoposition.Coordinate.Point;
  locationEntity.Message = "You are here";
  // Specify the location that will be at the center of the map.
  myMapControl.Center = locationEntity.Location;
  // Set the map controls data context so data binding will work.
  myMapControl.DataContext = locationEntity;
  // Zoom level.
  myMapControl.ZoomLevel = 15;
  // The map control has done most of its work. Make the controls visible.
  imgMyLocation.Visibility = Windows.UI.Xaml.Visibility.Visible;
  tbMessage.Visibility = Windows.UI.Xaml.Visibility.Visible;
  // Collapse the progress bar.
  pbProgressBar.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}

いくつかのヒント

図 3 のコードでは、OnNavigatedTo イベントによって時間のかかる作業が実行されます。具体的には、このイベントによって Geolocator オブジェクトの GetGeopositionAsync 関数が呼び出されます。この関数はデバイスの現在位置を取得します。この処理を予め実行しておかないと、地図上に Image コントロールと TextBlock コントロールを適切に配置できません。このような状況では、XAML によって地図に追加される子コントロールは、地図上に配置できるようになるまで地図の左上隅に表示されます。これは感心しないユーザー エクスペリエンス (UX) です。これを修正するには、XAML 内では追加するコントロールを Collapsed に設定します。追加されたコントロールは、コントロールの位置が計算され、コントロールがバインドされるオブジェクトの用意ができた時点で表示します (図 1図 3 のコードの最後の数行を参照)。

Geolocator オブジェクトの DesiredAccuracyInMeters プロパティの使用を検討します。このプロパティを 100 m 以下に設定すると、取得可能で最も正確なデータが取得されます。デバイスに GPS 機能が搭載されている場合は、GPS を使用してデバイスの現在位置が特定されます。この値が 100 m を超えると、Geolocator オブジェクトは処理を電力効率が最も高い方法に切り替え、Wi-Fi 信号など、GPS ではないデータを使用します。この 100 m というしきい値は、デバイスが進化するにつれて変わる可能性があるため、このプロパティは基になるしきい値ではなく、アプリのニーズを基に設定します。しきい値を基準にすると、動作が変わる要因になります。最後に、DesiredAccuracyInMeters プロパティは、Geolocator の DesiredAccuracy プロパティに設定されている値よりも優先されます。

GetGeopositionAsync のオーバーロードを使用することも検討します。maximumAge パラメーターと timeout パラメーターを受け取るオーバーロードです。maximumAge パラメーターは TimeSpan 型で、キャッシュされた場所データの有効期限を指定します。timeout パラメーターも TimeSpan 型で、このパラメーターに指定された時間よりも現在位置の取得に時間がかかると判断された場合、GetGeopositionAsync 関数によって例外がスローされます。

上記の 2 つのヒントによって、おそらくパフォーマンスが大幅に向上します。ただし、インターネット接続の状態が悪い地域や、メモリが少なく CPU の性能が劣るデバイスでは、依然としてマップ コントロールとマップ サービス API の処理に時間がかかり、ユーザーの操作性に遅延が生じます。このような場合、マップ コントロールの Center プロパティに特定の位置が設定されるまで、マップ コントロールには現在のズーム レベルで地球の地図が表示されます。これも感心しない UX です。ユーザーには、作業が進行中であることを示す視覚的なインジケーターを何か用意すべきです。図 1 の XAML では、進行状況バーをマップ コントロールの子コントロールとして追加、表示しています。必要な時間が正確にはわからないため、この進行状況バーは不確定なバーとして準備します。地図の Center プロパティが計算され、マップ コントロールに設定されると、進行状況バーを非表示にします。不確定な進行状況バーを使用する場合のベスト プラクティスは、常にページの最上部に配置することだとされています。ほとんどのシナリオでは、そのとおりだと思いますが、マップ コントロールを使用するときは、地図の中心を横切る形で進行状況バーを表示する方が個人的には好みです。ユーザーの視線はマップ コントロールに集まりがちなので、ページの最上部にある進行状況バーは見落とされる可能性があります。マップ コントロールを横切る形で表示すると、マップ コントロールで処理が進行中であることがユーザーにわかります。

コレクションのデータ バインド

マップ コントロールへのコレクションのバインドは、ListBox、ListView、GridView など、コレクションを表示するコントロールにコレクションをバインドするのと同様です。マップ コントロールへのバインドを説明するため、次のクラスを例に考えてみましょう。

public class Team
{
  public string TeamName { get; set; }
  public Uri ImageSource { get; set; }
  public string Division { get; set; }
  public string StadiumName { get; set; }
  public Geopoint StadiumLocation { get; set; }
  public Point NAP { get; set; }
}

このクラスのインスタンスは、プロのスポーツ チームについての基本情報を保持するために使用できます。プロパティの 1 つに、チームの本拠地として使用されるスタジアムの場所を保持する Geopoint プロパティがあることがわかります。

図 4 の XAML は、Team オブジェクトのコレクションをマップ コントロールにバインドし、各チーム本拠地のスタジアムの場所を小さなアイコンで示すように、マップ コントロールを設定します。

図 4 コレクションをバインドするようにマップ コントロールを設定

<Maps:MapControl
  x:Name="myMapControl" Grid.Row="1"
  MapServiceToken="{StaticResource MapServiceTokenString}" >
  <Maps:MapItemsControl x:Name="MapItems" >
    <Maps:MapItemsControl.ItemTemplate>
      <DataTemplate>
        <Image Source="{Binding ImageSource}"
          Maps:MapControl.Location="{Binding StadiumLocation}"
          Maps:MapControl.NormalizedAnchorPoint="{Binding NAP}"
          Height="15" Width="15"
          />
      </DataTemplate>
    </Maps:MapItemsControl.ItemTemplate>
  </Maps:MapItemsControl>
</Maps:MapControl>

他のコントロールでのコレクションのバインドを使い慣れていれば、図 4 はおなじみの内容です。Image コントロールは、DataTemplate に含まれています。Location プロパティに添付されている Image コントロールは、Team オブジェクトの StadiumLocation プロパティにバインドされます。この Image コントロールには、NormalizedAnchorPoint 添付プロパティもあります。このプロパティは、スタジアムの中央に画像を配置するプロパティにバインドされます。

マップ コントロールをコレクションにバインドするときは、NormalizedAnchorPoint プロパティをハードコーディングすることはできません。基になるオブジェクトの値にバインドする必要があります。このプロパティを次のように設定しようとするとどうなるでしょう。

Maps:MapControl.NormalizedAnchorPoint="0.5,0.5"

XAML エディターは、この構文を適切に処理できず、値は設定されません。マイクロソフトはこの問題を認識しています。

図 5 は、NFL の各チームのスタジアムの場所を表示したマップ コントロールを示しています (このスクリーンショットは、本稿付属のコード サンプルのものです。コード サンプルには、コレクションのインスタンスを作成するコードや、ページ内にうまく収まるようにコントロールを適切にフォーマットするコードなど、わかりやすさを優先してここには記載していないコードもすべて含めています)。

NFL (全米プロフットボール リーグ) のスタジアム
図 5 NFL (全米プロフットボール リーグ) のスタジアム

スケール コントロール

指定された距離を表すように、コントロールのサイズを調整できます。たとえば、地図にスケール (縮尺) を表示するとします。スケールは、ユーザーに視覚的な手がかりを提供し、地図上のオブジェクト間の距離を推測できるようにします。また、マップ コントロールを使用してジオフェンスを表すには、マップ コントロールに楕円を追加する方法が効果的です。楕円を追加したら、楕円を円に成形し、円 (たとえば、ジオフェンスのアラート範囲に相当する円) の半径のサイズを調整します。

Windows Phone 8.1 のコントロールは、幅と高さをピクセル単位で指定して、サイズを決めます。したがって、コントロールのスケールを調整して特定の距離を表すには、マップ コントロールの 1 ピクセルが表す距離を特定します。以下は、マップ コントロールの 1 ピクセルが表す距離を特定する計算式です。

const double BING_MAP_CONSTANT = 156543.04;
double MetersPerPixel =
  BING_MAP_CONSTANT * Math.Cos(latitude) / Math.Pow(2, zoomLevel);

使用している緯度は、マップ コントロールの Center プロパティから取得します。単位は度数ではなく、ラジアンにする必要があります。緯度は通常、度数で表現されるため、度数の値に Pi/180 を掛けて (Math.PI/180) ラジアンに変換します。ズーム レベルは、マップ コントロールの zoomLevel から取得し、1 ~ 20 の範囲の値になります。Windows Phone 8.1 では、この値を double 型で表します。

この計算式の数学的微分の詳細については、ここでは説明しませんが、少しコメントをしておいた方がよいでしょう。

一見すると、この計算は正しくないように思えます。なぜ、緯度が関係するのでしょう。地図のスケールは、単純にズーム レベルの機能の 1 つではないでしょうか。実際には、緯度が大きく関与します。地図のスケールを特定するには、ズーム レベルだけでは不十分です。マップ コントロールのバックエンドである Bing 地図はメルカトル投影法を採用しています。メルカトル投影法は、球体 (この場合は地球) の表面の詳細情報を四角形の表面に投影するための手法です。この投影法では、四角形の領域いっぱいに球の表面を展開するため、赤道から遠い地域ほど引き伸ばす (拡大する) 必要があります。メルカトル投影法の理解するため、簡単な実験をしてみましょう。みかんの皮をむきます。むいた皮はすべて残しておきます。みかんの皮をすべてむいたら、元のように皮をつなぎ合わせて平面に並べて、隙間なく四角形に収まるようにします。これは、無理ですね。むいた皮を四角い形になるようにするは、みかんの "赤道" に相当する位置から離れた部分の皮を拡大するしかありません。隙間なく四角形を埋めるには、"極" に近付けば近付くほど拡大が必要になります。この拡大によって、極付近の場所と赤道付近の場所のスケールに差が生じます。どの程度拡大する必要があるかは、赤道からの距離によって決まります。つまり、緯度に依存します。カナダのケベックと米フロリダ州キー・ウェストの 2 都市を例に、メルカトル投影法で地球を投影する場合の拡大について考えてみましょう。マップ コントロールを使ってケベックを最大限 (ズーム レベル 20) 拡大すると、100 ピクセルは約 10.2 m (33.5 フィート) になります。一方、キー・ウェストでは同じズーム レベルの場合、100 ピクセルが約 13.6 m (44.5 フィート) になります。ケベックの方がキー・ウェストよりも、3.4 m (11 フィート) 詳細なスケーリングが得られます。寒い地域にお住まいの皆さんにとって、心ばかりの慰めになるでしょうか。メルカトル投影法の詳細については、MSDN ライブラリの記事「スケールと解像度」(bit.ly/1xIqEwC、英語) を参照してください。

この計算で確認しておきたい最後の点は、Bing 地図の定数です。Bing 地図の定数は、地球の半径と、指定されたズーム レベルのマップ ビューを決定するためにマイクロソフトが使用している計算式を基にしています。単位は m/px (1 ピクセルあたりのメートル数) です。

図 6 は、マップ コントロールに追加する TextBlock と Rectangle を示しています。この 2 つを距離スケールとして使用します。図 7 は、ZoomLevelChanged イベントと、距離スケールの作成に必要なロジックを示しています (本稿付属のコード サンプルでは RegionInfo.CurrentRegion.IsMetric プロパティをチェックして、メートル法の方がわかりやすいユーザーのために、メートル単位で値を表示します)。最後の 図 8 は、コード サンプルのスクリーンショットにより、マップ コントロールに追加された距離スケールを示しています。

図 6 距離スケールとして使用する TextBlock と Rectangle の XAML

<Maps:MapControl
  x:Name="myMapControl" Grid.Row="1"
  MapServiceToken="{StaticResource MapServiceTokenString}"
  ZoomLevelChanged="myMapControl_ZoomLevelChanged">
  <!-- Distance scale, which is located at the lower left of the Map control. -->
  <TextBlock Name="tbScale" Text="Scale Text" FontSize="15" Foreground="Black"
    Margin="24,530,24,6" Opacity="0.6" />
  <Rectangle Name="recScale" Fill="Purple" Width="100" Height="6"
    Margin="24,548,24,24" Opacity="0.6" />
</Maps:MapControl>

図 7 ZoomLevelChanged イベント

private void myMapControl_ZoomLevelChanged(MapControl sender, object args)
{
  // Get the Map control's current zoom level.
  double zoomLevel = sender.ZoomLevel;
  // Use the latitude from the center point of the Map control.
  double latitude = sender.Center.Position.Latitude;
  // The following formula for map resolution needs latitude in radians.
  latitude = latitude * (Math.PI / 180);
  // This constant is based on the diameter of the Earth and the
  // equations Microsoft uses to determine the map shown for the
  // Map control's zoom level.
  const double BING_MAP_CONSTANT = 156543.04;
  // Calculate the number of meters represented by a single pixel.
  double MetersPerPixel =
    BING_MAP_CONSTANT * Math.Cos(latitude) / Math.Pow(2, zoomLevel);
  // Aditional units.
  double KilometersPerPixel = MetersPerPixel / 1000;
  double FeetPerPixel = MetersPerPixel * 3.28;
  double MilesPerPixel = FeetPerPixel / 5280;
  // Determine the distance represented by the rectangle control.
  double scaleDistance = recScale.Width * MilesPerPixel;
  tbScale.Text = scaleDistance.ToString() + " miles";
}

米フロリダ州キー・ウェストのサンセットピアを表示するマップ コントロールに追加された距離スケール
図 8 米フロリダ州キー・ウェストのサンセットピアを表示するマップ コントロールに追加された距離スケール

オフラインで使用する地図のダウンロード

地図はオフラインで使用するためにダウンロードできます。これは、高速道路を運転中で次の都市部に到達するまでかなり距離がある、森林の奥深くをハイキングしているなど、デバイスがまったくインターネットに接続できないときに、地図機能を提供する必要があるアプリに便利です。

かなりのストレージ容量が必要になるため、ユーザーの同意なしにプログラムから地図をダウンロードすることはできません。ユーザーは必要な地図の選択とダウンロードの許可のために、システムが提供する UX を使用して、毎回承認する必要があります。これは、Windows.Services.Maps 名前空間に属する MapManager 静的クラスを使用して実現します。このクラスは、地図のダウンロードとアップロードの両方の機能を提供します。以下の ShowDownloadedMapsUI 関数は、組み込みの地図アプリを起動し、図 9 のようなページを表示します。

MapManager.ShowDownloadedMapsUI();

地図をダウンロードするための UI
図 9 地図をダウンロードするための UI

組み込みの地図アプリの名前はマップで、図 9 に表示されているページには、[設定] メニュー オプションの [地図をダウンロード] をタップしてアクセスすることもできます。この関数によって別のアプリ (組み込みのマップ アプリ) に切り替わるため、ユーザーは手動で元のアプリに戻る必要があります。

図 9 のページには、以前ダウンロードしたすべての地図が表示されます。また、デバイスのストレージを解放する必要がある場合や、地図が不要になった場合は、以前ダウンロードした地図を選んで削除するメニュー オプションもあります。

追加ボタン (+) をタップすると、地図の選択ウィザードが起動されます。表示されたページで、ダウンロードする地図を含む大陸を指定します。大陸を選択すると、選択した大陸内のすべての国を表示するページが表示されます。大陸内のすべての国を選択して、大陸全体の地図をダウンロードすることもできますが、大量のストレージ容量が必要です。たとえば、米国のすべての地図をダウンロードする場合 3.4 GB のストレージが必要です。北アメリカと中央アメリカから成る大陸全体をダウンロードするには、さらにかなりの容量が必要です。

複数の地域や州がある大きな国を選択する場合は、特定の地域や州を選択するページが表示されます。[選択] ボタンを使って、複数の地域を選択できます。地域を選択すると、図 10 のようなダウンロード ページに移動します。地域や州がない小さな国を選択した場合も、同じページが表示されます。

地図のダウンロード
図 10 地図のダウンロード

地図をダウンロードする前に、設定アプリのストレージ センサーを選択して、デバイスの空き容量を確認するようユーザーに求めることをお勧めします。ストレージ センサーはデバイスの空き容量のほか、ストレージの解放が必要な場合に備えて、各アプリが使用しているデバイスのストレージ容量も表示します。本稿執筆時点では、デバイス上の使用済みストレージ容量や空き容量をプログラムによって特定できる WinRT API はありません。

地図は、Wi-Fi など、制約のないネットワークに接続している間にダウンロードすることをお勧めします。本稿のコード サンプルからは、現在のネットワーク接続状態をチェックし、従量課金接続を使用している場合にユーザーに警告する方法もわかります。

ダウンロードした地図を更新する

地図は、随時、変更または修正されます。都市に新しい道路ができたり、住所表記が変わったり、地域の境界が変わることもあります。したがって、ダウンロードした地図は、定期的に更新します。MapManager 静的クラスには、ダウンロードした地図を更新するための、ShowMapsUpdateUI という関数があります。

MapManager.ShowMapsUpdateUI();

ShowMapsUpdateUI 関数は、組み込みの地図アプリに切り替える ShowDownloadedMapsUI 関数と似ています。この関数を呼び出すと、ダウンロード済みのすべての地図について、更新が必要かどうかがチェックされます。以前ダウンロードした地図で更新が必要なものがある場合、更新データのサイズを提示し、ダウンロードを取り消すか続行するかをユーザーに確認します。これと同じ機能を、マップ アプリの設定メニュー オプションから利用することもできます。

ShowDownloadedMapsUI を使用して地図のダウンロードを促すアプリの場合は、ベスト プラクティスとして、ShowMapsUpdateUI を使ってダウンロード済みの地図が最新の状態に保たれるようにします。

まとめ

今回は、Windows Phone 8.1 のマップ コントロールにアプリ データを追加する方法を説明しました。説明したのは、地図への XAML コントロールの追加、データ バインド、特定のスケールに合わせたコントロールの描画などです。また、マップ コントロールの基になるデータをオフラインにし、オフラインでの使用を想定しているアプリ内で、マップ コントロールをシームレスに設定する方法についても説明しました。


Keith Pijanowski は、エンジニアで起業家の仕事人間です。ソフトウェア業界で 20 年以上の経験があり、新興企業にも大企業にも勤め、コード作成から事業開発まで、さまざまな業務に携わってきました。連絡先は keithpij@msn.com または twitter.com/keithpij です。

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