Mostrar puntos de interés en un mapa
Importante
Retirada del servicio Bing Maps for Enterprise
Los servicios MapControl y map de UWP del espacio de nombres Windows.Services.Maps se basan en Mapas de Bing. Bing Maps for Enterprise está en desuso y se retirará, momento en el que los servicios y MapControl ya no recibirán datos.
Para obtener más información, consulte la documentación del Centro para desarrolladores de Mapas de Bing y Mapas de Bing.
Nota:
MapControl y servicios de mapas requieren una clave de autenticación de mapas denominada MapServiceToken. Para obtener más información sobre cómo obtener y establecer una clave de autenticación de mapas, consulta Solicitar una clave de autenticación de mapas.
Agregue puntos de interés (POI) a un mapa mediante marcadores, imágenes, formas y elementos de interfaz de usuario XAML. Una POI es un punto específico en el mapa que representa algo de interés. Por ejemplo, la ubicación de un negocio, una ciudad o un amigo.
Para mostrar marcadores, imágenes y formas en el mapa, agregue objetos MapIcon, MapBillboard, MapPolygon y MapPolyline a una colección MapElements de un objeto MapElementsLayer. A continuación, agregue ese objeto de capa a la colección Layers de un control de mapa.
Nota:
En versiones anteriores, esta guía le mostró cómo agregar elementos de mapa a la colección MapElements. Aunque todavía puede usar este enfoque, perderá algunas de las ventajas del nuevo modelo de capa de mapa. Para más información, consulte la sección Trabajar con capas de esta guía.
También puedes mostrar elementos de interfaz de usuario XAML como Button, HyperlinkButton o TextBlock en el mapa agregándolos a MapItemsControl o como Elementos secundarios de MapControl.
Si tiene un gran número de elementos para colocar en el mapa, considere la posibilidad de superponer imágenes en mosaico en el mapa. Para mostrar carreteras en el mapa, consulta Mostrar rutas e instrucciones
Agregar un marcadores
Muestra una imagen de este tipo de marcadores, con texto opcional, en el mapa mediante la clase MapIcon. Puede aceptar la imagen predeterminada o proporcionar una imagen personalizada mediante la propiedad Image. En la imagen siguiente se muestra la imagen predeterminada de un MapIcon sin ningún valor especificado para la propiedad Title, con un título corto, con un título largo y con un título muy largo.
En el ejemplo siguiente se muestra un mapa de la ciudad de Seattle y se agrega un MapIcon con la imagen predeterminada y un título opcional para indicar la ubicación de Space Needle. También centra el mapa sobre el icono y se acerca. Para obtener información general sobre el uso del control de mapa, consulta Mostrar mapas con vistas 2D, 3D y 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;
}
En este ejemplo se muestra el siguiente PUNTO de interés en el mapa (la imagen predeterminada en el centro).
La siguiente línea de código muestra MapIcon con una imagen personalizada guardada en la carpeta Assets del proyecto. La propiedad Image de MapIcon espera un valor de tipo RandomAccessStreamReference. Este tipo requiere una instrucción using para el espacio de nombres Windows.Storage.Streams .
Nota:
Si usa la misma imagen para varios iconos de mapa, declare RandomAccessStreamReference en el nivel de página o aplicación para obtener el mejor rendimiento.
MapIcon1.Image =
RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/customicon.png"));
Tenga en cuenta estas consideraciones al trabajar con la clase MapIcon:
- La propiedad Image admite un tamaño máximo de imagen de 2048×2048 píxeles.
- De forma predeterminada, no se garantiza que se muestre la imagen del icono de mapa. Puede ocultarse cuando oculta otros elementos o etiquetas en el mapa. Para mantenerlo visible, establezca la propiedad CollisionBehaviorDesired del icono de mapa en MapElementCollisionBehavior.RemainVisible.
- No se garantiza que se muestre el título opcional de MapIcon. Si no ve el texto, reduzca el valor de la propiedad ZoomLevel de MapControl.
- Cuando se muestra una imagen de MapIcon que apunta a una ubicación específica en el mapa (por ejemplo, una chincheta o una flecha), considere la posibilidad de establecer el valor de la propiedad NormalizedAnchorPoint en la ubicación aproximada del puntero en la imagen. Si deja el valor de NormalizedAnchorPoint en su valor predeterminado de (0, 0), que representa la esquina superior izquierda de la imagen, los cambios en el ZoomLevel del mapa pueden dejar la imagen apuntando a una ubicación diferente.
- Si no establece explícitamente una Altitud y AltitudReferenceSystem, el MapIcon se colocará en la superficie.
Agregar un marcadores 3D
Puedes agregar objetos tridimensionales a un mapa. Utilice la clase MapModel3D para importar un objeto 3D desde un archivo 3D Manufacturing Format (3MF).
Esta imagen usa tazas de café 3D para marcar las ubicaciones de las cafeterías en un vecindario.
El código siguiente agrega una taza de café al mapa mediante la importación de un archivo 3MF. Para simplificar las cosas, este código agrega la imagen al centro del mapa, pero es probable que el código agregue la imagen a una ubicación específica.
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,
},
},
});
}
Agregar una image
Mostrar imágenes grandes relacionadas con ubicaciones de mapa, como una imagen de un restaurante o un punto de referencia. A medida que los usuarios se alejan, la imagen se reducirá proporcionalmente para permitir que el usuario vea más del mapa. Esto es un poco diferente de un MapIcon que marca una ubicación específica, suele ser pequeña y sigue siendo el mismo tamaño que los usuarios acercan y se alejan de un mapa.
El código siguiente muestra el MapBillboard presentado en la imagen anterior.
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);
}
Hay tres partes de este código que merece la pena examinar un poco más: la imagen, la cámara de referencia y la propiedad NormalizedAnchorPoint.
Imagen
En este ejemplo se muestra una imagen personalizada guardada en la carpeta Assets del proyecto. La propiedad Image de MapBillboard espera un valor de tipo RandomAccessStreamReference. Este tipo requiere una instrucción using para el espacio de nombres Windows.Storage.Streams .
Nota:
Si usa la misma imagen para varios iconos de mapa, declare RandomAccessStreamReference en el nivel de página o aplicación para obtener el mejor rendimiento.
Cámara de referencia
Dado que una imagen de MapBillboard se escala y se reduce horizontalmente a medida que cambia zoomLevel del mapa, es importante definir dónde aparece en ese ZoomLevel la imagen en una escala normal de 1x. Esa posición se define en la cámara de referencia de MapBillboard y, para establecerla, tendrás que pasar un objeto MapCamera al constructor del MapBillboard.
Puede definir la posición que desee en un punto geográfico y, a continuación, usar ese punto geográfico para crear un objeto MapCamera. Sin embargo, en este ejemplo, solo usamos el objeto MapCamera devuelto por la propiedad ActualCamera del control de mapa. Esta es la cámara interna del mapa. La posición actual de esa cámara se convierte en la posición de la cámara de referencia; la posición en la que aparece la imagen de MapBillboard en una escala x.
Si la aplicación ofrece a los usuarios la capacidad de alejar el mapa, la imagen disminuye en tamaño porque la cámara interna de mapas aumenta en altitud mientras que la imagen a escala 1x permanece fija en la posición de la cámara de referencia.
NormalizedAnchorPoint
NormalizedAnchorPoint es el punto de la imagen que está anclada a la propiedad Location de MapBillboard. El punto 0,5,1 es el centro inferior de la imagen. Dado que hemos establecido la propiedad Location del MapBillboard en el centro del control del mapa, el centro inferior de la imagen se anclará en el centro del control de mapas. Si desea que la imagen aparezca centrada directamente sobre un punto, establezca NormalizedAnchorPoint en 0,5,0,5.
Adición de una forma
Muestra una forma de varios puntos en el mapa mediante la clase MapPolygon. En el ejemplo siguiente, del ejemplo de mapa de UWP, se muestra un cuadro rojo con borde azul en el 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);
}
Agregar una línea
Muestra una línea en el mapa mediante la clase MapPolyline. En el ejemplo siguiente, del ejemplo de mapa de UWP, se muestra una línea discontinua en el 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);
}
Agregar XAML
Mostrar elementos de interfaz de usuario personalizados en el mapa mediante XAML. Coloque XAML en el mapa especificando la ubicación y el punto de anclaje normalizado del XAML.
- Establezca la ubicación en el mapa donde se coloca el XAML llamando a SetLocation.
- Establezca la ubicación relativa en el XAML que corresponde a la ubicación especificada llamando a SetNormalizedAnchorPoint.
En el ejemplo siguiente se muestra un mapa de la ciudad de Seattle y se agrega un control borde XAML para indicar la ubicación de Space Needle. También centra el mapa sobre el área y se acerca. Para obtener información general sobre el uso del control de mapa, consulta Mostrar mapas con vistas 2D, 3D y 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));
}
En este ejemplo se muestra un borde azul en el mapa.
En los ejemplos siguientes se muestra cómo agregar elementos de interfaz de usuario XAML directamente en el marcado XAML de la página mediante el enlace de datos. Al igual que con otros elementos XAML que muestran contenido, Children es la propiedad de contenido predeterminada de MapControl y no tiene que especificarse explícitamente en el marcado XAML.
En este ejemplo se muestra cómo mostrar dos controles XAML como elementos secundarios implícitos de MapControl. Estos controles aparecen en el mapa en las ubicaciones enlazadas a datos.
<maps:MapControl>
<TextBox Text="Seattle" maps:MapControl.Location="{x:Bind SeattleLocation}"/>
<TextBox Text="Bellevue" maps:MapControl.Location="{x:Bind BellevueLocation}"/>
</maps:MapControl>
Establezca estas ubicaciones mediante una propiedad en el archivo de código subyacente.
public Geopoint SeattleLocation { get; set; }
public Geopoint BellevueLocation { get; set; }
En este ejemplo se muestra cómo mostrar dos controles XAML contenidos dentro de mapItemsControl. Estos controles aparecen en el mapa en las ubicaciones enlazadas a datos.
<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>
En este ejemplo se muestra una colección de elementos XAML enlazados a 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>
La ItemsSource
propiedad del ejemplo anterior está enlazada a una propiedad de tipo IList en el archivo de código subyacente.
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);
}
}
Trabajar con capas
En los ejemplos de esta guía se agregan elementos a una colección MapElementsLayer . A continuación, muestran cómo agregar esa colección a la propiedad Layers del control de mapa. En versiones anteriores, en esta guía se muestra cómo agregar elementos de mapa a la colección MapElements de la siguiente manera:
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);
Aunque todavía puede usar este enfoque, perderá algunas de las ventajas del nuevo modelo de capa de mapa. Al agrupar los elementos en capas, puede manipular cada capa independientemente entre sí. Por ejemplo, cada capa tiene su propio conjunto de eventos para que puedas responder a un evento en un nivel específico y realizar una acción específica para dicho evento.
Además, puedes enlazar XAML directamente a MapLayer. Esto es algo que no se puede hacer mediante la colección MapElements .
Una manera de hacerlo es usar una clase de modelo de vista, código subyacente a una página XAML y una página XAML.
Ver clase 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);
}
Código subyacente de una página XAML
Conecte la clase de modelo de vista a la página de código subyacente.
public LandmarksViewModel ViewModel { get; set; }
public myMapPage()
{
this.InitializeComponent();
this.ViewModel = new LandmarksViewModel();
}
Página XAML
En la página XAML, enlaza a la propiedad de la clase de modelo de vista que devuelve la capa.
<maps:MapControl
x:Name="myMap" TransitFeaturesVisible="False" Loaded="MyMap_Loaded" Grid.Row="2"
MapServiceToken="Your token" Layers="{x:Bind ViewModel.LandmarkLayer}"/>