地図上に目的地を表示する
重要
Bing Maps for Enterprise サービスの提供終了
Windows.Services.Maps 名前空間の UWP MapControlおよびマップ サービスは、Bing Maps に依存します。 Bing Maps for Enterprise は非推奨となり、廃止されます。その時点で、MapControl とサービスはデータを受信しなくなります。
詳細については、 Bing Maps デベロッパー センター および Bing Maps のドキュメントを参照してください。
Note
MapControl とマップ サービスには、MapServiceToken と呼ばれるマップ認証キーが必要です。 マップ認証キーを取得して設定する方法について詳しくは、「マップ認証キーの要求」をご覧ください。
プッシュピン、画像、図形、XAML UI 要素を使用して、マップに目的地 (POI) を追加します。 POI は、関心のあるものを表すマップ上の特定のポイントです。 たとえば、ビジネス、都市、友人の場所などです。
地図にプッシュピン、画像、および図形を表示するには、MapIcon、MapBillboard、MapPolygon、MapPolyline の各オブジェクトを、MapElementsLayer オブジェクトの MapElements コレクションに追加します。 次に、そのレイヤー オブジェクトをマップ コントロールの Layers コレクションに追加します。
Note
以前のリリースでは、このガイドでは、map 要素を MapElements コレクションに追加する方法について説明しました。 この方法は引き続き使用できますが、新しいマップ レイヤー モデルの利点の一部を見逃すことになります。 詳細については、このガイドの「 レイヤーを使用した作業 」セクションを参照してください。
Button、HyperlinkButton、TextBlock などの XAML ユーザー インターフェイス要素をマップ上に表示するにはMapItemsControlまたは MapControl のChildrenとして追加します。
マップ上に配置する要素が多数ある場合は、マップ上にタイル画像を オーバーレイすることを検討してください。 地図上に道路を表示するには、「 ルートとルート案内を表示する」を参照してください。
プッシュピンを追加する
MapIcon クラスを使用して、オプションのテキストを含むプッシュピンなどの画像をマップに表示します。 既定のイメージをそのまま使用することも、 Image プロパティを使用してカスタム イメージを指定することもできます。 次の図は、 MapIcon Title プロパティに値が指定されていない、短いタイトル、長いタイトル、非常に長いタイトルの既定の画像を表示しています。
次の例では、シアトル市のマップを示し、既定の画像とスペース ニードルの場所を示す省略可能なタイトルを含む 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 を表示します。
次のコード行には、プロジェクトの Assets フォルダーに保存されたカスタム イメージを含む MapIcon が表示されます。 MapIcon の Image プロパティには、randomAccessStreamReference型の値が必要です。 この型には、Windows.Storage.Streams 名前空間の使用ステートメントが必要です。
Note
複数のマップ アイコンに同じイメージを使用する場合は、 RandomAccessStreamReference ページまたはアプリ レベルで宣言し、最適なパフォーマンスを実現します。
MapIcon1.Image =
RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/customicon.png"));
MapIcon クラスを使用する場合は、次の点に注意してください。
- Image プロパティは、2048 ピクセル×2048 ピクセルの最大イメージ サイズをサポートします。
- 既定では、マップ アイコンの画像が表示されるとは限りません。 マップ上の他の要素またはラベルが隠れている場合は、非表示になる場合があります。 表示を維持するには、マップ アイコンの CollisionBehaviorDesired プロパティを MapElementCollisionBehavior.RemainVisible に設定します。
- MapIcon の省略可能なTitleは表示されません。 テキストが表示されない場合は、MapControl の ZoomLevel プロパティの値を小さくして縮小します。
- マップ上の特定の場所 (プッシュピンや矢印など) を指す MapIcon イメージを表示する場合は、 NormalizedAnchorPoint プロパティの値をイメージ上のポインターのおおよその位置に設定することを検討してください。 NormalizedAnchorPointの値を画像の左上隅を表す既定値 (0, 0) のままにすると、マップの ZoomLevel が変更され、画像が別の場所を指し示したままになる可能性があります。
- AltitudeとAltitudeReferenceSystemを明示的に設定しない場合は、MapIconがサーフェイスに配置されます。
3D プッシュピンを追加する
3 次元オブジェクトをマップに追加できます。 MapModel3D クラスを使用して、3D 製造形式 (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 とは少し異なり、通常は小さく、ユーザーがマップを拡大したり縮小したりした場合と同じサイズのままです。
次のコードは、上の図に示した 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);
}
このコードには、画像、参照カメラ、および NormalizedAnchorPoint プロパティの 3 つの部分があります。
Image
この例では、プロジェクトの Assets フォルダーに保存されているカスタム イメージを示します。 MapBillboard の Image プロパティには、RandomAccessStreamReference 型の値が必要です。 この型には、Windows.Storage.Streams 名前空間の使用ステートメントが必要です。
Note
複数のマップ アイコンに同じイメージを使用する場合は、 RandomAccessStreamReference ページまたはアプリ レベルで宣言し、最適なパフォーマンスを実現します。
参照カメラ
MapBillboardイメージはマップのZoomLevelの変化に応じて拡大縮小されるため、そのZoomLevelイメージが通常の 1 倍のスケールで表示される場所を定義することが重要です。 この位置は、 MapBillboard の参照カメラで定義され、設定するには、 MapCamera オブジェクトを MapBillboard のコンストラクターに渡す必要があります。
Geopointで目的の位置を定義し、そのGeopointを使用してMapCamera オブジェクトを作成できます。 ただし、この例では、マップ コントロールの ActualCamera プロパティによって返される MapCamera オブジェクトを使用しています。 これはマップの内部カメラです。 そのカメラの現在の位置は、参照カメラの位置になります。 MapBillboard イメージが 1 倍のスケールで表示される位置。
アプリでユーザーがマップを縮小できる場合、マップの内部カメラは高度で上昇し、1x スケールの画像は参照カメラの位置で固定されたままであるため、画像のサイズが小さくなります。
NormalizedAnchorPoint
NormalizedAnchorPointは、MapBillboardのLocation プロパティに固定されているイメージのポイントです。 ポイント 0.5,1 は画像の下部中央です。 MapBillboard の Location プロパティをマップコントロールの中央に設定しているため画像の下部中央はマップ コントロールの中央に固定されます。 イメージをポイントの中央に直接表示する場合は、 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 UI 要素を直接追加する方法を示します。 コンテンツを表示する他の XAML 要素と同様に、 Children は MapControl の既定のコンテンツ プロパティであり、XAML マークアップで明示的に指定する必要はありません。
この例では、 MapControl の暗黙的な子として 2 つの XAML コントロールを表示する方法を示します。 これらのコントロールは、マップ上のデータ バインド位置に表示されます。
<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);
}
}
レイヤーの操作
このガイドの例では、 MapElementsLayer コレクションに要素を追加します。 次に、そのコレクションをマップ コントロールの 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}"/>