2D、3D、Streetside ビューでの地図の表示

重要

Bing Maps for Enterprise サービスの提供終了

Windows.Services.Maps 名前空間の UWP MapControlおよびマップ サービスは、Bing Maps に依存します。 Bing Maps for Enterprise は非推奨となり、廃止されます。その時点で、MapControl とサービスはデータを受信しなくなります。

詳細については、 Bing Maps デベロッパー センター および Bing Maps のドキュメントを参照してください。 マップは、マップ placecard と呼ばれる簡易非表示ウィンドウまたはフル機能のマップ コントロールで表示できます。

map サンプルをダウンロードしてこのガイドで説明されている機能をいくつか試してください。

プレースカードにマップを表示する

ユーザーがタッチする UI 要素またはアプリの領域の上、下、または横に、軽量のポップアップ ウィンドウ内にマップを表示できます。 マップには、アプリ内の情報に関連する都市または住所を表示できます。

このプレースカードにはシアトルの都市が表示されます。

シアトルの市区町村を示す placecard

シアトルをボタンの下のプレースカードに表示するコードを次に示します。

private void Seattle_Click(object sender, RoutedEventArgs e)
{
    Geopoint seattlePoint = new Geopoint
        (new BasicGeoposition { Latitude = 47.6062, Longitude = -122.3321 });

    PlaceInfo spaceNeedlePlace = PlaceInfo.Create(seattlePoint);

    FrameworkElement targetElement = (FrameworkElement)sender;

    GeneralTransform generalTransform =
        targetElement.TransformToVisual((FrameworkElement)targetElement.Parent);

    Rect rectangle = generalTransform.TransformBounds(new Rect(new Point
        (targetElement.Margin.Left, targetElement.Margin.Top), targetElement.RenderSize));

    spaceNeedlePlace.Show(rectangle, Windows.UI.Popups.Placement.Below);
}

このプレースカードは、シアトルのスペースニードルの位置を示しています。

スペースニードルの位置を示すプレースカード

スペースニードルをボタンの下のプレースカードに表示するコードを次に示します。

private void SpaceNeedle_Click(object sender, RoutedEventArgs e)
{
    Geopoint spaceNeedlePoint = new Geopoint
        (new BasicGeoposition { Latitude = 47.6205, Longitude = -122.3493 });

    PlaceInfoCreateOptions options = new PlaceInfoCreateOptions();

    options.DisplayAddress = "400 Broad St, Seattle, WA 98109";
    options.DisplayName = "Seattle Space Needle";

    PlaceInfo spaceNeedlePlace =  PlaceInfo.Create(spaceNeedlePoint, options);

    FrameworkElement targetElement = (FrameworkElement)sender;

    GeneralTransform generalTransform =
        targetElement.TransformToVisual((FrameworkElement)targetElement.Parent);

    Rect rectangle = generalTransform.TransformBounds(new Rect(new Point
        (targetElement.Margin.Left, targetElement.Margin.Top), targetElement.RenderSize));

    spaceNeedlePlace.Show(rectangle, Windows.UI.Popups.Placement.Below);
}

コントロールにマップを表示する

マップ コントロールを使用して、豊富でカスタマイズ可能なマップ データをアプリに表示します。 マップ コントロールでは、道路地図、航空写真、3D、ビュー、ルート案内、検索結果、トラフィックを表示できます。 マップでは、ユーザーの位置、ルート案内、目的地を表示できます。 マップには、航空写真の 3D ビュー、ストリートサイドビュー、交通、交通機関、地元企業を表示することもできます。

ユーザーがアプリ固有または一般的な地理情報を表示できるようにするアプリ内のマップが必要な場合は、マップ コントロールを使用します。 アプリにマップ コントロールがあるということは、ユーザーがその情報を取得するためにアプリの外部に移動する必要がないことを意味します。

Note

ユーザーがアプリの外部に出ることを気にしない場合は、Windows マップ アプリを使用してその情報を提供することを検討してください。 アプリは、Windows マップ アプリを起動して、特定のマップ、ルート案内、検索結果を表示できます。 詳しくは、「Windows マップ アプリの起動」をご覧ください。

アプリにマップ コントロールを追加する

MapControlを追加して、XAML ページにマップを表示します。 MapControlを使用するには、XAML ページまたはコードでWindows.UI.Xaml.Controls.Maps 名前空間を宣言する必要があります。 ツールボックスからコントロールをドラッグすると、この名前空間宣言が自動的に追加されます。 MapControlを XAML ページに手動で追加する場合は、ページの上部に名前空間宣言を手動で追加する必要があります。

次の例では、基本的なマップ コントロールを表示し、タッチ入力を受け入れるだけでなく、ズーム コントロールと傾きコントロールを表示するようにマップを構成します。

<Page
    x:Class="MapsAndLocation1.DisplayMaps"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MapsAndLocation1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:Maps="using:Windows.UI.Xaml.Controls.Maps"
    mc:Ignorable="d">

 <Grid x:Name="pageGrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Maps:MapControl
       x:Name="MapControl1"            
       ZoomInteractionMode="GestureAndControl"
       TiltInteractionMode="GestureAndControl"   
       MapServiceToken="EnterYourAuthenticationKeyHere"/>

 </Grid>
</Page>

コードにマップ コントロールを追加する場合は、コード ファイルの先頭で名前空間を手動で宣言する必要があります。

using Windows.UI.Xaml.Controls.Maps;
...

// Add the MapControl and the specify maps authentication key.
MapControl MapControl2 = new MapControl();
MapControl2.ZoomInteractionMode = MapInteractionMode.GestureAndControl;
MapControl2.TiltInteractionMode = MapInteractionMode.GestureAndControl;
MapControl2.MapServiceToken = "EnterYourAuthenticationKeyHere";
pageGrid.Children.Add(MapControl2);

マップ認証キーを取得して設定する

MapControlマップ サービスを使用するには、マップ認証キーを MapServiceToken プロパティの値として指定する必要があります。 前の例では、 EnterYourAuthenticationKeyHere を、 Bing Maps デベロッパー センターから取得したキーに置き換えます。 テキスト Warning: MapServiceToken が指定されていません マップ認証キーを指定するまで、コントロールの下に引き続き表示されます。 マップ認証キーを取得して設定する方法について詳しくは、「マップ認証キーの要求」をご覧ください。

マップの場所を設定する

マップを目的の任意の場所にポイントするか、ユーザーの現在の場所を使用します。

マップの開始位置を設定する

コードで MapControlCenter プロパティを指定するか、XAML マークアップでプロパティをバインドして、マップに表示する場所を設定します。 次の例では、シアトル市を中心にマップを表示します。

Note

文字列を Geopoint に変換できないため、データ バインディングを使用しない限り、XAML マークアップで Center プロパティの値を指定することはできません。 (この制限は、 にも適用されます。MapControl.Location 添付プロパティ)。

protected override void OnNavigatedTo(NavigationEventArgs e)
{
   // Specify a known location.
   BasicGeoposition cityPosition = new BasicGeoposition() { Latitude = 47.604, Longitude = -122.329 };
   Geopoint cityCenter = new Geopoint(cityPosition);

   // Set the map location.
   MapControl1.Center = cityCenter;
   MapControl1.ZoomLevel = 12;
   MapControl1.LandmarksVisible = true;
}

マップ コントロールの例。

マップの現在の場所を設定する

アプリがユーザーの場所にアクセスするには、アプリで RequestAccessAsync メソッドを呼び出す必要があります。 このときに、アプリをフォアグラウンドで実行し、RequestAccessAsync を UI スレッドから呼び出す必要があります。 位置情報に対するアクセス許可をユーザーがアプリに与えるまで、アプリは位置情報にアクセスできません。

Geolocator クラスの GetGeopositionAsync メソッドを使用して、デバイスの現在の場所を取得します (場所が使用可能な場合)。 対応する Geopoint を取得するには、地位置のジオ座標の Point プロパティを使用します。 詳細については、「 現在の場所を取得する」を参照してください。

// Set your current location.
var accessStatus = await Geolocator.RequestAccessAsync();
switch (accessStatus)
{
   case GeolocationAccessStatus.Allowed:

      // Get the current location.
      Geolocator geolocator = new Geolocator();
      Geoposition pos = await geolocator.GetGeopositionAsync();
      Geopoint myLocation = pos.Coordinate.Point;

      // Set the map location.
      MapControl1.Center = myLocation;
      MapControl1.ZoomLevel = 12;
      MapControl1.LandmarksVisible = true;
      break;

   case GeolocationAccessStatus.Denied:
      // Handle the case  if access to location is denied.
      break;

   case GeolocationAccessStatus.Unspecified:
      // Handle the case if  an unspecified error occurs.
      break;
}

デバイスの位置をマップに表示する場合は、グラフィックスを表示し、位置データの精度に基づいてズーム レベルを設定することを検討してください。 詳細については、「場所に対応するアプリの Guidelinesを参照してください。

マップの場所を変更する

2D マップに表示される場所を変更するには、 TrySetViewAsync メソッドのいずれかのオーバーロードを呼び出します。 このメソッドを使用して、 CenterZoomLevelHeading、および Pitch の新しい値を指定します。 MapAnimationKind 列挙体から定数を指定することで、ビューが変更されたときに使用する省略可能なアニメーションを指定することもできます。

3D マップの場所を変更するには、代わりに TrySetSceneAsync メソッドを使用します。 詳細については、「 航空写真 3D ビューを表示する」を参照してください。

TrySetViewBoundsAsync メソッドを呼び出してGeoboundingBoxの内容をマップに表示します。 たとえば、ルートまたはルートの一部をマップに表示するには、このメソッドを使用します。 詳細については、「 マップ上のルートとルート案内を表示するを参照してください。

マップの外観を変更する

マップの外観をカスタマイズするには、マップ コントロールの StyleSheet プロパティを既存の MapStyleSheet オブジェクトのいずれかに設定します。

myMap.StyleSheet = MapStyleSheet.RoadDark();

濃色のスタイル マップ

JSON を使用してカスタム スタイルを定義し、その JSON を使用して MapStyleSheet オブジェクトを作成することもできます。

スタイル シート JSON は、マップ スタイル シート エディター アプリケーションを使用して対話形式で作成できます。

myMap.StyleSheet = MapStyleSheet.ParseFromJson(@"
    {
        ""version"": ""1.0"",
        ""settings"": {
            ""landColor"": ""#FFFFFF"",
            ""spaceColor"": ""#000000""
        },
        ""elements"": {
            ""mapElement"": {
                ""labelColor"": ""#000000"",
                ""labelOutlineColor"": ""#FFFFFF""
            },
            ""water"": {
                ""fillColor"": ""#DDDDDD""
            },
            ""area"": {
                ""fillColor"": ""#EEEEEE""
            },
            ""political"": {
                ""borderStrokeColor"": ""#CCCCCC"",
                ""borderOutlineColor"": ""#00000000""
            }
        }
    }
");

カスタム スタイル マップ

完全な JSON エントリ リファレンスについては、「 Map スタイル シートリファレンスを参照してください。

既存のシートから始めて、JSON を使用して、必要な要素をオーバーライドできます。 この例では、既存のスタイルから始まり、JSON を使用して水領域の色のみを変更します。

 MapStyleSheet \customSheet = MapStyleSheet.ParseFromJson(@"
    {
        ""version"": ""1.0"",
        ""elements"": {
            ""water"": {
                ""fillColor"": ""#DDDDDD""
            }
        }
    }
");

MapStyleSheet builtInSheet = MapStyleSheet.RoadDark();

myMap.StyleSheet = MapStyleSheet.Combine(new List<MapStyleSheet> { builtInSheet, customSheet });

スタイル マップを結合する

Note

2 番目のスタイル シートで定義したスタイルは、最初のスタイルよりも優先されます。

向きとパースペクティブを設定する

地図のカメラを拡大、縮小、回転、傾けて、目的の効果に適した角度を取得します。 これらのプロパティを試してください。

  • Center プロパティを設定して、マップのcenterを地理的なポイントに設定します。
  • ZoomLevel プロパティを 1 から 20 の値に設定して、マップのzoom レベルを設定します。
  • マップの 回転 を設定します。 Heading プロパティ (0 または 360 度 = 北、90 = 東、180 = 南、270 = 西) を設定します。
  • DesiredPitch プロパティを 0 ~ 65 度の値に設定して、マップのtiltを設定します。

マップ フィーチャの表示と非表示を切り替える

MapControlの次のプロパティの値を設定して、道路やランドマークなどのマップ フィーチャを表示または非表示にします。

MapControlにプッシュピン、図形、XAML コントロールを表示する方法については、「マップ上のポイントの表示 (POI)」を参照してください

ストリートサイド ビューを表示する

ストリートサイド ビューは、マップ コントロールの上に表示される場所の道路レベルの視点です。

マップ コントロールのストリートサイド ビューの例。

最初にマップ コントロールに表示されたマップとは別に、ストリートサイド ビューの "内側" のエクスペリエンスを考えてみましょう。 たとえば、ストリートサイド ビューで場所を変更しても、ストリートサイド ビューの "下" のマップの場所や外観は変更されません。 (コントロールの右上隅にある X をクリックして) ストリートサイド ビューを閉じた後も、元のマップは変更されません。

ストリートサイド ビューを表示するには

  1. デバイスで Streetside ビューがサポートされているかどうかを確認するために、 IsStreetsideSupportedを確認します。
  2. Streetside ビューがサポートされている場合は、FindNearbyAsync を呼び出して指定した場所の近くにStreetsidePanorama を作成します。
  3. StreetsidePanoramaが null でないかどうかを確認して、近くのパノラマが見つかったかどうかを確認します
  4. 近くのパノラマが見つかった場合は、マップ コントロールの CustomExperience プロパティの StreetsideExperience を作成します。

この例では、前の画像と同様のストリートサイド ビューを表示する方法を示します。

Note

マップ コントロールのサイズが小さすぎる場合は、概観の地図は表示されません。

private async void showStreetsideView()
{
   // Check if Streetside is supported.
   if (MapControl1.IsStreetsideSupported)
   {
      // Find a panorama near Avenue Gustave Eiffel.
      BasicGeoposition cityPosition = new BasicGeoposition() { Latitude = 48.858, Longitude = 2.295};
      Geopoint cityCenter = new Geopoint(cityPosition);
      StreetsidePanorama panoramaNearCity = await StreetsidePanorama.FindNearbyAsync(cityCenter);

      // Set the Streetside view if a panorama exists.
      if (panoramaNearCity != null)
      {
         // Create the Streetside view.
         StreetsideExperience ssView = new StreetsideExperience(panoramaNearCity);
         ssView.OverviewMapVisible = true;
         MapControl1.CustomExperience = ssView;
      }
   }
   else
   {
      // If Streetside is not supported
      ContentDialog viewNotSupportedDialog = new ContentDialog()
      {
         Title = "Streetside is not supported",
         Content ="\nStreetside views are not supported on this device.",
         PrimaryButtonText = "OK"
      };
      await viewNotSupportedDialog.ShowAsync();            
   }
}

航空写真の 3D ビューを表示する

MapScene クラスを使用して、マップの 3D パースペクティブを指定します。 マップ シーンは、マップに表示される 3D ビューを表します。 MapCamera クラスは、このようなビューを表示するカメラの位置を表します。

マップ シーンの場所への MapCamera の場所の図

マップ サーフェイス上の建物やその他のフィーチャを 3D に表示するには、マップ コントロールの Style プロパティを MapStyle.Aerial3DWithRoads に設定します。 これは、 Aerial3DWithRoads スタイルを持つ 3D ビューの例です。

3D マップ ビューの例。

3D ビューを表示するには

  1. デバイスで 3D ビューがサポートされているかどうかを確認するために、 Is3DSupportedを確認します。
  2. 3D ビューがサポートされている場合は、マップ コントロールの Style プロパティを MapStyle.Aerial3DWithRoads に設定します。
  3. CreateFromLocationAndRadiusCreateFromCamera など、多くのCreateFrom メソッドのいずれかを使用して、MapScene オブジェクトを作成
  4. TrySetSceneAsync を呼び出して 3D ビューを表示します。 MapAnimationKind 列挙体から定数を指定することで、ビューが変更されたときに使用する省略可能なアニメーションを指定することもできます。

この例では、3D ビューを表示する方法を示します。

private async void display3DLocation()
{
   if (MapControl1.Is3DSupported)
   {
      // Set the aerial 3D view.
      MapControl1.Style = MapStyle.Aerial3DWithRoads;

      // Specify the location.
      BasicGeoposition hwGeoposition = new BasicGeoposition() { Latitude = 43.773251, Longitude = 11.255474};
      Geopoint hwPoint = new Geopoint(hwGeoposition);

      // Create the map scene.
      MapScene hwScene = MapScene.CreateFromLocationAndRadius(hwPoint,
                                                                           80, /* show this many meters around */
                                                                           0, /* looking at it to the North*/
                                                                           60 /* degrees pitch */);
      // Set the 3D view with animation.
      await MapControl1.TrySetSceneAsync(hwScene,MapAnimationKind.Bow);
   }
   else
   {
      // If 3D views are not supported, display dialog.
      ContentDialog viewNotSupportedDialog = new ContentDialog()
      {
         Title = "3D is not supported",
         Content = "\n3D views are not supported on this device.",
         PrimaryButtonText = "OK"
      };
      await viewNotSupportedDialog.ShowAsync();
   }
}

場所に関する情報を取得する

マップ上の場所に関する情報を取得するには、 MapControl の次のメソッドを呼び出します。

  • TryGetLocationFromOffset メソッド - マップ コントロールのビューポート内の指定したポイントに対応する地理的な位置情報を取得します。
  • GetOffsetFromLocation メソッド - 指定した地理的位置に対応するマップ コントロールのビューポート内のポイントを取得します。
  • IsLocationInView メソッド - 指定した地理的位置がマップ コントロールのビューポートに現在表示されているかどうかを確認します。
  • FindMapElementsAtOffset メソッド - マップ コントロールのビューポート内の指定したポイントにあるマップ上の要素を取得します。

相互作用と変更を処理する

MapControl の次のイベントを処理して、マップ上のユーザー入力ジェスチャを処理します。 MapInputEventArgsLocation プロパティと Position プロパティの値を確認して、マップ上の地理的位置と、ジェスチャが発生したビューポート内の物理的な位置に関する情報を取得します。

コントロールの LoadingStatusChanged イベントを処理して、マップが読み込まれているか完全に読み込まれているかを判断します。

ユーザーまたはアプリがマップの設定を変更したときに発生する変更を処理するには、 MapControl の次のイベントを処理します。

ベスト プラクティスの推奨事項

  • 十分な画面領域 (または画面全体) を使用してマップを表示し、ユーザーが地理的な情報を表示するために過度にパンやズームを行う必要がないようにします。

  • マップが静的な情報ビューの表示にのみ使用される場合は、より小さなマップを使用する方が適切な場合があります。 より小さい静的マップを使用する場合は、そのサイズを使いやすさに基づきます。十分な画面の不動産を節約するのに十分な小ささですが、読みやすい状態を維持するのに十分な大きさです。

  • map 要素を使用してマップ シーンに関心のあるポイントを埋め込みます;追加の情報は、マップ シーンをオーバーレイする一時的な UI として表示できます。