関心のあるポイントの地図への表示

注意

MapControl とマップ サービスには、MapServiceToken と呼ばれるマップ認証キーが必要です。 マップ認証キーを取得して設定する方法について詳しくは、「マップ認証キーの要求」をご覧ください。

プッシュピン、画像、図形、XAML UI 要素を使って、関心のあるポイント (POI) を地図に追加します。 POI は、地図上の特定のポイントであり、関心のあるものを表します。 たとえば、企業、市区町村、友人の所在地を示すことができます。

アプリで POI を表示する方法について詳しくは、GitHub の Windows-universal-samples リポジトリからユニバーサル Windows プラットフォーム (UWP) の地図サンプルをダウンロードしてください。

地図にプッシュピン、画像、および図形を表示するには、MapIconMapBillboardMapPolygonMapPolyline の各オブジェクトを、MapElementsLayer オブジェクトの MapElements コレクションに追加します。 次に、そのレイヤー オブジェクトをマップ コントロールの Layers コレクションに追加します。

注意

以前のリリースでは、このガイドで、マップの要素を MapElements コレクションに追加する方法を示していました。 引き続き同じアプローチを使うこともできますが、その場合は新しいマップ レイヤー モデルの利点が活かされません。 詳しくは、このガイドの「レイヤーの使用」をご覧ください。

ButtonHyperlinkButtonTextBlock などの XAML ユーザー インターフェイス要素を地図に表示することもできます。そのためには、それらの要素を MapItemsControl に追加するか、MapControlChildren として追加します。

地図に配置する要素の数が多い場合、地図にタイル画像をオーバーレイすることを検討します。 地図に道路情報を表示するには、「ルートとルート案内の表示」をご覧ください。

プッシュピンの追加

MapIcon クラスを使って、プッシュピンなどの画像をオプションのテキストと共に地図に表示します。 既定の画像をそのまま使うか、Image プロパティを使ってカスタム画像を指定できます。 次の画像はそれぞれ、Title プロパティに値を指定しない、短いタイトル、長いタイトル、非常に長いタイトルを指定した場合の MapIcon の既定の画像です。

さまざまな長さのタイトルを含むサンプルの MapIcon。

次の例では、シアトル市の地図を表示して、既定の画像とオプションのタイトルを使って MapIcon を追加し、スペース ニードルの場所を示しています。 また、アイコンを地図の中央に配置し、拡大しています。 マップ コントロールを使用する方法に関する一般的な情報については、「2D、3D、Streetside ビューでの地図の表示」をご覧ください。

public void AddSpaceNeedleIcon()
{
    var MyLandmarks = new List<MapElement>();

    BasicGeoposition snPosition = new BasicGeoposition { Latitude = 47.620, Longitude = -122.349 };
    Geopoint snPoint = new Geopoint(snPosition);

    var spaceNeedleIcon = new MapIcon
    {
        Location = snPoint,
        NormalizedAnchorPoint = new Point(0.5, 1.0),
        ZIndex = 0,
        Title = "Space Needle"
    };

    MyLandmarks.Add(spaceNeedleIcon);

    var LandmarksLayer = new MapElementsLayer
    {
        ZIndex = 1,
        MapElements = MyLandmarks
    };

    myMap.Layers.Add(LandmarksLayer);

    myMap.Center = snPoint;
    myMap.ZoomLevel = 14;

}

この例では、次の POI (中央の既定の画像) が地図に表示されます。

MapIcon を使った地図

次のコード行では、プロジェクトの Assets フォルダーに保存されているカスタム イメージを使って MapIcon が表示されます。 MapIconImage プロパティでは、RandomAccessStreamReference 型の値が想定されています。 この型では、Windows.Storage.Streams 名前空間用に using ステートメントが必要になります。

注意

複数の地図アイコンに同じ画像を使う場合は、パフォーマンスが最大限に高まるように、ページ レベルまたはアプリ レベルで RandomAccessStreamReference を宣言します。

    MapIcon1.Image =
        RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/customicon.png"));

MapIcon クラスを使うときは、次の考慮事項を念頭に置いてください。

  • Image プロパティがサポートしている最大画像サイズは 2048 × 2048 ピクセルです。
  • 既定では、地図アイコンの画像は必ず表示されるとは限りません。 このクラスが地図上の他の要素やラベルを覆い隠す場合には、このクラスは非表示になることがあります。 地図アイコンを表示したままにするには、このアイコンの CollisionBehaviorDesired プロパティを MapElementCollisionBehavior.RemainVisible に設定します。
  • MapIcon のオプションの Title は、必ず表示されるとは限りません。 テキストが表示されない場合は、MapControlZoomLevel プロパティの値を減らして、地図を縮小してください。
  • 地図上の特定の場所を指す MapIcon 画像 (たとえば、プッシュピンや矢印など) を表示する場合は、NormalizedAnchorPoint プロパティの値を画像上にあるポインターのおおよその位置に設定することを検討してください。 NormalizedAnchorPoint の値を、画像の左上隅を示す既定値 (0, 0) のままにした場合、地図の ZoomLevel を変更すると、画像が別の場所を示した状態になる可能性があります。
  • AltitudeAltitudeReferenceSystem を明示的に設定しない場合、MapIcon はサーフェスに配置されます。

3D プッシュピンの追加

3 次元オブジェクトをマップに追加できます。 MapModel3D クラスを使って、3D Manufacturing Format (3MF) ファイルから 3D オブジェクトをインポートします。

次の画像では、3D のコーヒー カップを使って、付近の喫茶店の場所を示しています。

地図上のマグ

次のコードでは、3MF ファイルのインポートを使って、地図にコーヒー カップを追加します。 シンプルにするために、このコードでは地図の中央に画像を追加していますが、実際のコードでは通常、特定の場所に画像を追加することになります。

public async void Add3DMapModel()
{
    var mugStreamReference = RandomAccessStreamReference.CreateFromUri
        (new Uri("ms-appx:///Assets/mug.3mf"));

    var myModel = await MapModel3D.CreateFrom3MFAsync(mugStreamReference,
        MapModel3DShadingOption.Smooth);

    myMap.Layers.Add(new MapElementsLayer
    {
       ZIndex = 1,
       MapElements = new List<MapElement>
       {
          new MapElement3D
          {
              Location = myMap.Center,
              Model = myModel,
          },
       },
    });
}

イメージの追加

レストランやランドマークの画像など、地図の場所に関連する大きい画像を表示します。 ユーザーが地図を縮小すると、画像のサイズも比例的に縮小され、より広い範囲の地図を表示できるようになります。 これは特定の場所をマークする MapIcon とは少し異なります。MapIcon は小さいのが通常で、ユーザーが地図の拡大や縮小を行ってもサイズは変わりません。

MapBillboard 画像

次のコードは、上記の画像に表示されている MapBillboard を示しています。

public void AddLandmarkPhoto()
{
    // Create MapBillboard.

    RandomAccessStreamReference mapBillboardStreamReference =
        RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/billboard.jpg"));

    var mapBillboard = new MapBillboard(myMap.ActualCamera)
    {
        Location = myMap.Center,
        NormalizedAnchorPoint = new Point(0.5, 1.0),
        Image = mapBillboardStreamReference
    };

    // Add MapBillboard to a layer on the map control.

    var MyLandmarkPhotos = new List<MapElement>();

    MyLandmarkPhotos.Add(mapBillboard);

    var LandmarksPhotoLayer = new MapElementsLayer
    {
        ZIndex = 1,
        MapElements = MyLandmarkPhotos
    };

    myMap.Layers.Add(LandmarksPhotoLayer);
}

このコードには、少し詳しく説明するに値する部分が 3 つあります。画像、リファレンス カメラ、および NormalizedAnchorPoint のことです。

Image

この例は、プロジェクトの Assets フォルダーに保存されたカスタム画像を示しています。 MapBillboardImage プロパティでは、RandomAccessStreamReference 型の値が想定されています。 この型では、Windows.Storage.Streams 名前空間用に using ステートメントが必要になります。

注意

複数の地図アイコンに同じ画像を使う場合は、パフォーマンスが最大限に高まるように、ページ レベルまたはアプリ レベルで RandomAccessStreamReference を宣言します。

リファレンス カメラ

MapBillboard 画像は地図の ZoomLevel の変更に合わせて拡大および縮小するため、その ZoomLevel が標準の 1x 倍率のときに画像がどこに表示されるかを定義することが重要になります。 その位置は MapBillboard のリファレンス カメラで定義されます。リファレンス カメラを設定するには、MapCamera オブジェクトを MapBillboard のコンストラクターに渡す必要があります。

Geopoint で目的の位置を定義し、その Geopoint を使用することで、MapCamera オブジェクトを作成できます。 ただし、この例で使用している MapCamera オブジェクトは、単純にマップ コントロールの ActualCamera プロパティから返されたものです。 これは地図の内部カメラです。 このカメラの現在の位置がリファレンス カメラの位置となり、1x 倍率ではこの位置に MapBillboard 画像が表示されます。

アプリでユーザーが地図を縮小できるようにしている場合、画像のサイズも縮小されます。これは、1x 倍率の画像はリファレンス カメラの位置で固定されたままになりますが、地図の内部カメラは高度が上がるためです。

NormalizedAnchorPoint

NormalizedAnchorPoint は、MapBillboardLocation プロパティに固定される画像のポイントです。 ポイント 0.5,1 は画像の下部中央になります。 MapBillboardLocation プロパティをマップ コントロールの中央に設定しているので、画像の下部中央がマップ コントロールの中央に固定されることになります。 ポイントが中心になるように画像を表示するには、NormalizedAnchorPoint を 0.5,0.5 に設定します。

図形を追加する

マルチポイント図形を地図に表示するには、MapPolygon クラスを使います。 次の例は、UWP の地図サンプルから抜粋したもので、地図に赤色のボックス (境界線は青色) を表示します。

public void HighlightArea()
{
    // Create MapPolygon.

    double centerLatitude = myMap.Center.Position.Latitude;
    double centerLongitude = myMap.Center.Position.Longitude;

    var mapPolygon = new MapPolygon
    {
        Path = new Geopath(new List<BasicGeoposition> {
                    new BasicGeoposition() {Latitude=centerLatitude+0.0005, Longitude=centerLongitude-0.001 },
                    new BasicGeoposition() {Latitude=centerLatitude-0.0005, Longitude=centerLongitude-0.001 },
                    new BasicGeoposition() {Latitude=centerLatitude-0.0005, Longitude=centerLongitude+0.001 },
                    new BasicGeoposition() {Latitude=centerLatitude+0.0005, Longitude=centerLongitude+0.001 },
                }),
        ZIndex = 1,
        FillColor = Colors.Red,
        StrokeColor = Colors.Blue,
        StrokeThickness = 3,
        StrokeDashed = false,
    };

    // Add MapPolygon to a layer on the map control.
    var MyHighlights = new List<MapElement>();

    MyHighlights.Add(mapPolygon);

    var HighlightsLayer = new MapElementsLayer
    {
        ZIndex = 1,
        MapElements = MyHighlights
    };

    myMap.Layers.Add(HighlightsLayer);
}

線を追加する

MapPolyline クラスを使って、線を地図に表示します。 次の例は、UWP の地図サンプルから抜粋したもので、地図に破線を表示します。

public void DrawLineOnMap()
{
    // Create Polyline.

    double centerLatitude = myMap.Center.Position.Latitude;
    double centerLongitude = myMap.Center.Position.Longitude;
    var mapPolyline = new MapPolyline
    {
        Path = new Geopath(new List<BasicGeoposition> {
                    new BasicGeoposition() {Latitude=centerLatitude-0.0005, Longitude=centerLongitude-0.001 },
                    new BasicGeoposition() {Latitude=centerLatitude+0.0005, Longitude=centerLongitude+0.001 },
                }),
        StrokeColor = Colors.Black,
        StrokeThickness = 3,
        StrokeDashed = true,
    };

   // Add Polyline to a layer on the map control.

   var MyLines = new List<MapElement>();

   MyLines.Add(mapPolyline);

   var LinesLayer = new MapElementsLayer
   {
       ZIndex = 1,
       MapElements = MyLines
   };

   myMap.Layers.Add(LinesLayer);

}

XAML の追加

XAML を使って、カスタム UI 要素を地図に表示します。 XAML を地図に配置するには、XAML の位置と正規化されたアンカー ポイントを指定します。

  • SetLocation を呼び出して、XAML を地図に配置する位置を設定します。
  • SetNormalizedAnchorPoint を呼び出して、指定した位置に対応する XAML 上の相対位置を設定します。

次の例では、シアトル市の地図を表示して、XAML の Border コントロールを追加し、スペース ニードルの場所を示しています。 また、そのエリアを地図の中央に配置し、拡大しています。 マップ コントロールを使用する方法に関する一般的な情報については、「2D、3D、Streetside ビューでの地図の表示」をご覧ください。

private void displayXAMLButton_Click(object sender, RoutedEventArgs e)
{
   // Specify a known location.
   BasicGeoposition snPosition = new BasicGeoposition { Latitude = 47.620, Longitude = -122.349 };
   Geopoint snPoint = new Geopoint(snPosition);

   // Create a XAML border.
   Border border = new Border
   {
      Height = 100,
      Width = 100,
      BorderBrush = new SolidColorBrush(Windows.UI.Colors.Blue),
      BorderThickness = new Thickness(5),
   };

   // Center the map over the POI.
   MapControl1.Center = snPoint;
   MapControl1.ZoomLevel = 14;

   // Add XAML to the map.
   MapControl1.Children.Add(border);
   MapControl.SetLocation(border, snPoint);
   MapControl.SetNormalizedAnchorPoint(border, new Point(0.5, 0.5));
}

この例では、地図に青色の境界線が表示されます。

地図上の関心がある場所に表示された xaml のスクリーンショット

次の例では、データ バインディングを使って、ページの XAML マークアップで XAML UI 要素を直接追加する方法を示しています。 コンテンツを表示する他の XAML 要素と同様に、ChildrenMapControl の既定のコンテンツ プロパティであり、XAML マークアップで明示的に指定する必要はありません。

次の例では、2 つの XAML コントロールを MapControl の暗黙的な子として表示する方法を示しています。 これらのコントロールは、地図上のデータがバインドされた場所に表示されます。

<maps:MapControl>
    <TextBox Text="Seattle" maps:MapControl.Location="{x:Bind SeattleLocation}"/>
    <TextBox Text="Bellevue" maps:MapControl.Location="{x:Bind BellevueLocation}"/>
</maps:MapControl>

これらの場所を設定するには、分離コード ファイルでプロパティを使います。

public Geopoint SeattleLocation { get; set; }
public Geopoint BellevueLocation { get; set; }

次の例は、MapItemsControl に含まれる 2 つの XAML コントロールを表示する方法を示しています。これらのコントロールは、地図上のデータがバインドされた場所に表示されます。

<maps:MapControl>
  <maps:MapItemsControl>
    <TextBox Text="Seattle" maps:MapControl.Location="{x:Bind SeattleLocation}"/>
    <TextBox Text="Bellevue" maps:MapControl.Location="{x:Bind BellevueLocation}"/>
  </maps:MapItemsControl>
</maps:MapControl>

次の例では、MapItemsControl にバインドされている XAML 要素のコレクションが表示されます。

<maps:MapControl x:Name="MapControl" MapTapped="MapTapped" MapDoubleTapped="MapTapped" MapHolding="MapTapped">
  <maps:MapItemsControl ItemsSource="{x:Bind LandmarkOverlays}">
      <maps:MapItemsControl.ItemTemplate>
          <DataTemplate>
              <StackPanel Background="Black" Tapped ="Overlay_Tapped">
                  <TextBlock maps:MapControl.Location="{Binding Location}" Text="{Binding Title}"
                    maps:MapControl.NormalizedAnchorPoint="0.5,0.5" FontSize="20" Margin="5"/>
              </StackPanel>
          </DataTemplate>
      </maps:MapItemsControl.ItemTemplate>
  </maps:MapItemsControl>
</maps:MapControl>

上記の例の プロパティは ItemsSource 、分離コード ファイルの IList 型のプロパティにバインドされています。

public sealed partial class Scenario1 : Page
{
    public IList LandmarkOverlays { get; set; }

    public MyClassConstructor()
    {
         SetLandMarkLocations();
         this.InitializeComponent();   
    }

    private void SetLandMarkLocations()
    {
        LandmarkOverlays = new List<MapElement>();

        var pikePlaceIcon = new MapIcon
        {
            Location = new Geopoint(new BasicGeoposition
            { Latitude = 47.610, Longitude = -122.342 }),
            Title = "Pike Place Market"
        };

        LandmarkOverlays.Add(pikePlaceIcon);

        var SeattleSpaceNeedleIcon = new MapIcon
        {
            Location = new Geopoint(new BasicGeoposition
            { Latitude = 47.6205, Longitude = -122.3493 }),
            Title = "Seattle Space Needle"
        };

        LandmarkOverlays.Add(SeattleSpaceNeedleIcon);
    }
}

レイヤーの使用

このガイドの例では、要素を MapElementLayers コレクションに追加しています。 その後、そのコレクションをマップ コントロールの Layers プロパティに追加する方法が示されています。 以前のリリースでは、このガイドで、次のようにマップの要素を MapElements コレクションに追加する方法を示していました。

var pikePlaceIcon = new MapIcon
{
    Location = new Geopoint(new BasicGeoposition
    { Latitude = 47.610, Longitude = -122.342 }),
    NormalizedAnchorPoint = new Point(0.5, 1.0),
    ZIndex = 0,
    Title = "Pike Place Market"
};

myMap.MapElements.Add(pikePlaceIcon);

引き続き同じアプローチを使うこともできますが、その場合は新しいマップ レイヤー モデルの利点が活かされません。 要素をレイヤーにグループ化すると、各レイヤーを互いに独立して操作できます。 たとえば、各レイヤーには独自のイベント セットがあるため、特定のレイヤーのイベントに応答し、そのイベントに固有の操作を実行することができます。

また、XAML を直接 MapLayer にバインドすることもできます。 これは、MapElements コレクションを使う場合にはできないことです。

これを実現するには、1 つの方法として、ビュー モデル クラス、XAML ページの分離コード、および XAML ページを使います。

ビュー モデル クラス

public class LandmarksViewModel
{
    public ObservableCollection<MapLayer> LandmarkLayer
        { get; } = new ObservableCollection<MapLayer>();

    public LandmarksViewModel()
    {
        var MyElements = new List<MapElement>();

        var pikePlaceIcon = new MapIcon
        {
            Location = new Geopoint(new BasicGeoposition
            { Latitude = 47.610, Longitude = -122.342 }),
            Title = "Pike Place Market"
        };

        MyElements.Add(pikePlaceIcon);

        var LandmarksLayer = new MapElementsLayer
        {
            ZIndex = 1,
            MapElements = MyElements
        };

        LandmarkLayer.Add(LandmarksLayer);         
    }

XAML ページの分離コード

ビュー モデル クラスを分離コード ページに結び付けます。

public LandmarksViewModel ViewModel { get; set; }

public myMapPage()
{
    this.InitializeComponent();
    this.ViewModel = new LandmarksViewModel();
}

XAML ページ

XAML ページで、レイヤーを返すビュー モデル クラスのプロパティにバインドします。

<maps:MapControl
    x:Name="myMap" TransitFeaturesVisible="False" Loaded="MyMap_Loaded" Grid.Row="2"
    MapServiceToken="Your token" Layers="{x:Bind ViewModel.LandmarkLayer}"/>