Exibir pontos de interesse em um mapa
Importante
Desativação do serviço Bing Mapas para Empresas
O UWP MapControl e os serviços de mapas do namespace Windows.Services.Maps dependem do Bing Mapas. O Bing Mapas para Empresas está obsoleto e será descontinuado. Nesse momento, o MapControl e os serviços não receberão mais dados.
Para obter mais informações, consulte a Central de Desenvolvedores do Bing Mapas e a documentação do Bing Mapas.
Observação
O MapControl e os serviços de mapa exigem uma chave de autenticação de mapas chamada MapServiceToken. Para saber mais sobre como obter e definir uma chave de autenticação de mapas, consulte Solicitar uma chave de autenticação de mapas.
Adicione pontos de interesse (POI) a um mapa usando pinos, imagens, formas e elementos de interface do usuário XAML. Um POI é um ponto específico no mapa que representa algo de interesse. Por exemplo, a localização de uma empresa, cidade ou amigo.
Exiba pinos, imagens e formas no mapa adicionando objetos MapIcon, MapBillboard, MapPolygon e MapPolyline a uma coleção MapElements de um objeto MapElementsLayer. Em seguida, adicione esse objeto de camada à coleção Layers de um controle de mapa.
Observação
Nas versões anteriores, este guia mostrou como adicionar elementos de mapa à coleção MapElements . Embora você ainda possa usar essa abordagem, perderá algumas das vantagens do novo modelo de camada de mapa. Para saber mais, consulte a seção Trabalhando com camadas deste guia.
Você também pode exibir elementos da interface do usuário XAML, como um Button, um HyperlinkButton ou um TextBlock no mapa, adicionando-os ao MapItemsControl ou como filhos do MapControl.
Se você tiver um grande número de elementos para colocar no mapa, considere sobrepor imagens lado a lado no mapa. Para exibir estradas no mapa, consulte Exibir rotas e direções
Adicionar um alfinete
Exiba uma imagem como um pino, com texto opcional, no mapa usando a classe MapIcon. Você pode aceitar a imagem padrão ou fornecer uma imagem personalizada usando a propriedade Image. A imagem a seguir exibe a imagem padrão de um MapIcon sem nenhum valor especificado para a propriedade Title, com um título curto, com um título longo e com um título muito longo.
O exemplo a seguir mostra um mapa da cidade de Seattle e adiciona um MapIcon com a imagem padrão e um título opcional para indicar a localização do Space Needle. Ele também centraliza o mapa sobre o ícone e aumenta o zoom. Para obter informações gerais sobre como usar o controle de mapa, consulte Exibir mapas com modos de exibição 2D, 3D e 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;
}
Este exemplo exibe o seguinte POI no mapa (a imagem padrão no centro).
A linha de código a seguir exibe o MapIcon com uma imagem personalizada salva na pasta Ativos do projeto. A propriedade Image do MapIcon espera um valor do tipo RandomAccessStreamReference. Esse tipo requer uma instrução using para o namespace Windows.Storage.Streams .
Observação
Se você usar a mesma imagem para vários ícones de mapa, declare o RandomAccessStreamReference no nível da página ou do aplicativo para obter o melhor desempenho.
MapIcon1.Image =
RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/customicon.png"));
Lembre-se destas considerações ao trabalhar com a classe MapIcon:
- A propriedade Image dá suporte a um tamanho máximo de imagem de 2048×2048 pixels.
- Por padrão, não há garantia de que a imagem do ícone do mapa seja exibida. Ele pode estar oculto quando obscurece outros elementos ou rótulos no mapa. Para mantê-lo visível, defina a propriedade CollisionBehaviorDesired do ícone do mapa como MapElementCollisionBehavior.RemainVisible.
- Não há garantia de que o título opcional do MapIcon seja mostrado. Se você não vir o texto, reduza diminuindo o valor da propriedade ZoomLevel do MapControl.
- Ao exibir uma imagem MapIcon que aponta para um local específico no mapa - por exemplo, um alfinete ou uma seta - considere definir o valor da propriedade NormalizedAnchorPoint como o local aproximado do ponteiro na imagem. Se você deixar o valor de NormalizedAnchorPoint em seu valor padrão de (0, 0), que representa o canto superior esquerdo da imagem, as alterações no ZoomLevel do mapa poderão deixar a imagem apontando para um local diferente.
- Se você não definir explicitamente um Altitude e AltitudeReferenceSystem, o MapIcon será colocado na superfície.
Adicionar um alfinete 3D
Você pode adicionar objetos tridimensionais a um mapa. Use a classe MapModel3D para importar um objeto 3D de um arquivo 3MF (Formato de Manufatura 3D).
Esta imagem usa xícaras de café 3D para marcar os locais das cafeterias em um bairro.
O código a seguir adiciona uma xícara de café ao mapa usando a importação de um arquivo 3MF. Para simplificar, esse código adiciona a imagem ao centro do mapa, mas seu código provavelmente adicionaria a imagem a um local específico.
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,
},
},
});
}
Adicionar uma imagem
Exiba imagens grandes relacionadas a locais no mapa, como uma foto de um restaurante ou um ponto de referência. À medida que os usuários diminuem o zoom, a imagem diminui proporcionalmente em tamanho para permitir que o usuário visualize mais do mapa. Isso é um pouco diferente de um MapIcon que marca um local específico, geralmente é pequeno e permanece do mesmo tamanho à medida que os usuários aumentam e diminuem o zoom de um mapa.
O código a seguir mostra o MapBillboard apresentado na imagem acima.
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);
}
Há três partes desse código que vale a pena examinar um pouco mais de perto: a imagem, a câmera de referência e a propriedade NormalizedAnchorPoint.
Imagem
Este exemplo mostra uma imagem personalizada salva na pasta Ativos do projeto. A propriedade Image do MapBillboard espera um valor do tipo RandomAccessStreamReference. Esse tipo requer uma instrução using para o namespace Windows.Storage.Streams .
Observação
Se você usar a mesma imagem para vários ícones de mapa, declare o RandomAccessStreamReference no nível da página ou do aplicativo para obter o melhor desempenho.
Câmera de referência
Como uma imagem do MapBillboard aumenta e diminui à medida que o ZoomLevel do mapa muda, é importante definir onde nesse ZoomLevel a imagem aparece em uma escala normal de 1x. Essa posição é definida na câmera de referência do MapBillboard e, para defini-la, você terá que passar um objeto MapCamera para o construtor do MapBillboard.
Você pode definir a posição desejada em um ponto geográfico e, em seguida, usar esse ponto geográfico para criar um objeto MapCamera. No entanto, neste exemplo, estamos apenas usando o objeto MapCamera retornado pela propriedade ActualCamera do controle de mapa. Esta é a câmera interna do mapa. A posição atual dessa câmera se torna a posição de referência da câmera; a posição em que a imagem do MapBillboard aparece em escala 1x.
Se o seu aplicativo der aos usuários a capacidade de diminuir o zoom no mapa, a imagem diminuirá de tamanho porque a câmera interna do mapa está subindo de altitude enquanto a imagem na escala 1x permanece fixa na posição da câmera de referência.
Ponto de ancoragem normalizado
O NormalizedAnchorPoint é o ponto da imagem que está ancorado na propriedade Location do MapBillboard. O ponto 0,5,1 é a parte inferior central da imagem. Como definimos a propriedade Location do MapBillboard como o centro do controle do mapa, o centro inferior da imagem será ancorado no centro do controle de mapas. Se você quiser que sua imagem apareça centralizada diretamente sobre um ponto, defina o NormalizedAnchorPoint como 0,5,0.5.
Adicione uma forma
Exiba uma forma de vários pontos no mapa usando a classe MapPolygon. O exemplo a seguir, do exemplo de mapa UWP, exibe uma caixa vermelha com borda azul no mapa.
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);
}
Adicionar uma linha
Exiba uma linha no mapa usando a classe MapPolyline . O exemplo a seguir, do exemplo de mapa UWP, exibe uma linha tracejada no mapa.
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);
}
Adicionar XAML
Exiba elementos de interface do usuário personalizados no mapa usando XAML. Posicione o XAML no mapa especificando o local e o ponto de ancoragem normalizado do XAML.
- Defina o local no mapa em que o XAML é colocado chamando SetLocation.
- Defina o local relativo no XAML que corresponde ao local especificado chamando SetNormalizedAnchorPoint.
O exemplo a seguir mostra um mapa da cidade de Seattle e adiciona um controle de borda XAML para indicar o local do Space Needle. Ele também centraliza o mapa sobre a área e aumenta o zoom. Para obter informações gerais sobre como usar o controle de mapa, consulte Exibir mapas com modos de exibição 2D, 3D e 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));
}
Este exemplo exibe uma borda azul no mapa.
Os exemplos a seguir mostram como adicionar elementos de interface do usuário XAML diretamente na marcação XAML da página usando a associação de dados. Assim como acontece com outros elementos XAML que exibem conteúdo, Children é a propriedade de conteúdo padrão do MapControl e não precisa ser especificada explicitamente na marcação XAML.
Este exemplo mostra como exibir dois controles XAML como filhos implícitos do MapControl. Esses controles aparecem no mapa nos locais associados a dados.
<maps:MapControl>
<TextBox Text="Seattle" maps:MapControl.Location="{x:Bind SeattleLocation}"/>
<TextBox Text="Bellevue" maps:MapControl.Location="{x:Bind BellevueLocation}"/>
</maps:MapControl>
Defina esses locais usando propriedades no arquivo code-behind.
public Geopoint SeattleLocation { get; set; }
public Geopoint BellevueLocation { get; set; }
Este exemplo mostra como exibir dois controles XAML contidos em um MapItemsControl. Esses controles aparecem no mapa nos locais associados a dados.
<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>
Este exemplo exibe uma coleção de elementos XAML associados a um MapItemsControl.
<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>
A ItemsSource
propriedade no exemplo acima está associada a uma propriedade do tipo IList no arquivo code-behind.
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);
}
}
Trabalhando com camadas
Os exemplos neste guia adicionam elementos a uma coleção MapElementsLayer . Em seguida, eles mostram como adicionar essa coleção à propriedade Layers do controle de mapa. Nas versões anteriores, este guia mostrou como adicionar elementos de mapa à coleção MapElements da seguinte maneira:
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);
Embora você ainda possa usar essa abordagem, perderá algumas das vantagens do novo modelo de camada de mapa. Ao agrupar seus elementos em camadas, você pode manipular cada camada independentemente uma da outra. Por exemplo, como cada camada tem seu próprio conjunto de eventos, você pode responder a um evento em uma camada específica e realizar uma ação específica para tal evento.
Além disso, você pode associar XAML diretamente a um MapLayer. Isso é algo que você não pode fazer usando a coleção MapElements .
Uma maneira de fazer isso é usando uma classe de modelo de exibição, code-behind uma página XAML e uma página XAML.
Exibir classe de modelo
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);
}
Code-behind de uma página XAML
Conecte a classe de modelo de exibição à sua página code-behind.
public LandmarksViewModel ViewModel { get; set; }
public myMapPage()
{
this.InitializeComponent();
this.ViewModel = new LandmarksViewModel();
}
Página XAML
Na página XAML, associe-se à propriedade na classe de modelo de exibição que retorna a camada.
<maps:MapControl
x:Name="myMap" TransitFeaturesVisible="False" Loaded="MyMap_Loaded" Grid.Row="2"
MapServiceToken="Your token" Layers="{x:Bind ViewModel.LandmarkLayer}"/>