Compartir a través de


Mapa

Examinar ejemplo. Examinar el ejemplo

El control .NET Multi-platform App UI (.NET MAUI) Map es una vista multiplataforma para mostrar y anotar mapas. El Map control usa el control de mapa nativo en cada plataforma y lo proporciona el paquete NuGet Microsoft.Maui.Controls.Maps.

Importante

El Map control no se admite en Windows debido a la falta de un control de mapa en WinUI. Sin embargo, el paquete NuGet CommunityToolkit.Maui.Maps proporciona acceso a Mapas de Bing a través de en WebView Windows. Para obtener más información, consulte Introducción.

Configuración

El Map control utiliza el control de mapa nativo en cada plataforma. Esto proporciona una experiencia de mapas rápida y familiar para los usuarios, pero significa que se necesitan algunos pasos de configuración para cumplir los requisitos de api de cada plataforma.

Inicialización del mapa

El control Map lo proporciona el paquete NuGet Microsoft.Maui.Controls.Maps, que debes agregar al proyecto de aplicación .NET MAUI.

Después de instalar el paquete NuGet, debe inicializarse en la aplicación llamando al UseMauiMaps método en el MauiAppBuilder objeto del método de MauiProgram la CreateMauiApp clase :

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            })
            .UseMauiMaps();

        return builder.Build();
    }
}

Una vez agregado e inicializado el paquete NuGet, Map las API se pueden usar en el proyecto.

Configuración de la plataforma

Se requiere configuración adicional en Android antes de que se muestre el mapa. Además, en iOS, Android y Mac Catalyst, el acceso a la ubicación del usuario requiere que se hayan concedido permisos de ubicación a la aplicación.

iOS y Mac Catalyst

Mostrar e interactuar con un mapa en iOS y Mac Catalyst no requiere ninguna configuración adicional. Sin embargo, para acceder a los servicios de ubicación, debe establecer las solicitudes de servicios de ubicación necesarias en Info.plist. Normalmente, estos serán uno o varios de los siguientes:

Para obtener más información, consulte Elección de la autorización de servicios de ubicación para solicitar en developer.apple.com.

A continuación se muestra la representación XML de estas claves en Info.plist . Debe actualizar los string valores para reflejar cómo usa la aplicación la información de ubicación:

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Can we use your location at all times?</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Can we use your location when your app is being used?</string>

A continuación, se muestra un mensaje cuando la aplicación intenta acceder a la ubicación del usuario, solicitando acceso:

Captura de pantalla de la solicitud de permisos de ubicación en iOS.

Androide

El proceso de configuración para mostrar e interactuar con un mapa en Android es:

  1. Obtenga una clave de API de Google Maps y agréguela al manifiesto de la aplicación.
  2. Especifique el número de versión de Google Play Services en el manifiesto.
  3. [opcional] Especifique los permisos de ubicación en el manifiesto.
  4. [opcional] Especifique el permiso WRITE_EXTERNAL_STORAGE en el manifiesto.
Obtención de una clave de API de Google Maps

Para usar el Map control en Android, debe generar una clave de API, que será utilizada por el SDK de Google Maps en el que se basa el Map control. Para ello, siga las instrucciones de Configuración en Google Cloud Console y Uso de claves de API en developers.google.com.

Una vez que haya obtenido una clave de API, debe agregarse dentro el <application> elemento del archivo Platforms/Android/AndroidManifest.xml, especificándolo como el valor del com.google.android.geo.API_KEY metadato.

<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true">
  <meta-data android:name="com.google.android.geo.API_KEY" android:value="PASTE-YOUR-API-KEY-HERE" />
</application>

Esto inserta la clave de API en el manifiesto. Sin una clave de API válida, el Map control mostrará una cuadrícula en blanco.

Nota:

com.google.android.geo.API_KEY es el nombre de metadatos recomendado para la clave de API. Se puede usar una clave con este nombre para autenticarse en varias API basadas en Google Maps en Android. Para la compatibilidad con versiones anteriores, se puede usar el com.google.android.maps.v2.API_KEY nombre de los metadatos, pero solo permite la autenticación en la API de Android Maps v2. Una aplicación solo puede especificar uno de los nombres de metadatos de clave de API.

Especificar el número de versión de los servicios de Google Play

Agregue la siguiente declaración dentro del <application> elemento de AndroidManifest.xml:

<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

Esto inserta la versión de los servicios de Google Play con la que se compiló la aplicación, en el manifiesto.

Especificar permisos de ubicación

Si la aplicación necesita acceder a la ubicación del usuario, debe solicitar permiso agregando los ACCESS_COARSE_LOCATION permisos o ACCESS_FINE_LOCATION (o ambos) al manifiesto, como elemento secundario del <manifest> elemento:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  ...
  <!-- Required to access the user's location -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
</manifest>

El ACCESS_COARSE_LOCATION permiso permite a la API usar wiFi o datos móviles, o ambos, para determinar la ubicación del dispositivo. Los ACCESS_FINE_LOCATION permisos permiten a la API usar el sistema de posicionamiento global (GPS), WiFi o datos móviles para determinar una ubicación precisa como sea posible.

A continuación, se muestra un mensaje cuando la aplicación intenta acceder a la ubicación del usuario, solicitando acceso:

Captura de pantalla de la solicitud de permisos de ubicación en Android.

Como alternativa, estos permisos se pueden habilitar en el editor de manifiestos de Android de Visual Studio.

Especificar el permiso "WRITE_EXTERNAL_STORAGE" para escribir en el almacenamiento externo.

Si la aplicación tiene como destino la API 22 o inferior, será necesario agregar el WRITE_EXTERNAL_STORAGE permiso al manifiesto, como elemento secundario del <manifest> elemento:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Esto no es necesario si la aplicación tiene como destino la API 23 o posterior.

Control de mapa

La Map clase define las siguientes propiedades que controlan la apariencia y el comportamiento del mapa:

  • IsShowingUser, de tipo bool, indica si el mapa muestra la ubicación actual del usuario.
  • ItemsSource, de tipo IEnumerable, que especifica la colección de elementos de IEnumerable anclaje que se van a mostrar.
  • ItemTemplate, de tipo DataTemplate, que especifica las DataTemplate que se van a aplicar a cada elemento de la colección de clavijas mostradas.
  • ItemTemplateSelector, de tipo DataTemplateSelector, que especifica el DataTemplateSelector que se usará para elegir un DataTemplate para un pin en tiempo de ejecución.
  • IsScrollEnabled, de tipo bool, determina si el mapa puede desplazarse.
  • IsTrafficEnabled, de tipo bool, indica si los datos de tráfico se superponen en el mapa.
  • IsZoomEnabled, de tipo bool, determina si el mapa puede hacer zoom.
  • MapElements, de tipo IList<MapElement>, representa la lista de elementos del mapa, como polígonos y polilíneas.
  • MapType, de tipo MapType, indica el estilo de presentación del mapa.
  • Pins, de tipo IList<Pin>, representa la lista de pines en el mapa.
  • VisibleRegion, de tipo MapSpan, devuelve la región mostrada actualmente del mapa.

Estas propiedades, a excepción de las MapElementspropiedades , Pinsy VisibleRegion , están respaldadas por BindableProperty objetos, lo que significa que pueden ser destinos de enlaces de datos.

La Map clase también define un MapClicked evento que se desencadena cuando se pulsa el mapa. El MapClickedEventArgs objeto que acompaña al evento tiene una sola propiedad denominada Location, de tipo Location. Cuando se desencadena el evento, la Location propiedad se establece en la ubicación del mapa que se ha pulsado. Para obtener información sobre la Location clase , vea Ubicación y distancia.

Para obtener información sobre las ItemsSource, ItemTemplate, y ItemTemplateSelector propiedades, consulte Mostrar una colección de pines.

Mostrar un mapa

Un Map se puede mostrar agregándolo a un diseño o página.

<ContentPage ...
             xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps">
    <maps:Map x:Name="map" />
</ContentPage>

El código de C# equivalente es el siguiente:

using Map = Microsoft.Maui.Controls.Maps.Map;

namespace WorkingWithMaps
{
    public class MapTypesPageCode : ContentPage
    {
        public MapTypesPageCode()
        {
            Map map = new Map();
            Content = map;
        }
    }
}

En este ejemplo se llama al constructor predeterminado Map , que centra el mapa en Maui, Hawaii::

Captura de pantalla del control de mapa con la ubicación predeterminada.

Como alternativa, se puede pasar un MapSpan argumento a un Map constructor para establecer el punto central y el nivel de zoom del mapa cuando se carga. Para obtener más información, vea Mostrar una ubicación específica en un mapa.

Importante

.NET MAUI tiene dos tipos de Map - Microsoft.Maui.Controls.Maps.Map y Microsoft.Maui.ApplicationModel.Map. Debido a que el espacio de nombres Microsoft.Maui.ApplicationModel es una de las directivas de .NET MAUI, al usar el control global using desde el código, deberá calificar completamente su uso Microsoft.Maui.Controls.Maps.Map o usar un Map.

Tipos de mapa

La Map.MapType propiedad se puede establecer en un MapType miembro de enumeración para definir el estilo de presentación del mapa. La enumeración MapType define los miembros siguientes:

  • Street especifica que se mostrará un mapa de calles.
  • Satellite especifica que se mostrará un mapa que contiene imágenes de satélite.
  • Hybrid especifica que se mostrará un mapa que combina datos de calle y satélite.

De forma predeterminada, Map mostrará un mapa de calles si la propiedad MapType no está definida. Como alternativa, la MapType propiedad se puede establecer en uno de los MapType miembros de enumeración:

<maps:Map MapType="Satellite" />

El código de C# equivalente es el siguiente:

Map map = new Map
{
    MapType = MapType.Satellite
};

Mostrar una ubicación específica en un mapa

La región de un mapa que se va a mostrar cuando se carga un mapa se puede establecer pasando un MapSpan argumento al Map constructor:

<ContentPage ...
             xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
             xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
    <maps:Map>
        <x:Arguments>
            <maps:MapSpan>
                <x:Arguments>
                    <sensors:Location>
                        <x:Arguments>
                            <x:Double>36.9628066</x:Double>
                            <x:Double>-122.0194722</x:Double>
                        </x:Arguments>
                    </sensors:Location>
                    <x:Double>0.01</x:Double>
                    <x:Double>0.01</x:Double>
                </x:Arguments>
            </maps:MapSpan>
        </x:Arguments>
    </maps:Map>
</ContentPage>

El código de C# equivalente es el siguiente:

using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...

Location location = new Location(36.9628066, -122.0194722);
MapSpan mapSpan = new MapSpan(location, 0.01, 0.01);
Map map = new Map(mapSpan);

En este ejemplo se crea un Map objeto que muestra la región especificada por el MapSpan objeto . El MapSpan objeto se centra en la latitud y longitud representada por un Location objeto y abarca 0,01 latitud y 0,01 grados de longitud. Para obtener información sobre la Location clase , vea Ubicación y distancia. Para obtener información sobre cómo pasar argumentos en XAML, consulta Pasar argumentos en XAML.

El resultado es que, cuando se muestra el mapa, se centra en una ubicación específica y abarca un número específico de grados de latitud y longitud:

Captura de pantalla del control de mapa con la ubicación especificada.

Creación de un objeto MapSpan

Hay varios enfoques para crear MapSpan objetos. Un enfoque común es proporcionar los argumentos necesarios al MapSpan constructor. Un conjunto de latitud y longitud representado por un Location objeto y un conjunto de double valores que representan los grados de latitud y longitud que abarca el MapSpan. Para obtener información sobre la Location clase , vea Ubicación y distancia.

Como alternativa, hay tres métodos en la MapSpan clase que devuelven nuevos MapSpan objetos:

  1. ClampLatitude devuelve un MapSpan con el mismo LongitudeDegrees que la instancia de clase del método y un radio definido por sus argumentos north y south.
  2. FromCenterAndRadius devuelve un MapSpan objeto definido por sus Location argumentos y Distance .
  3. WithZoom devuelve un MapSpan objeto con el mismo centro que la instancia de clase del método, pero con un radio multiplicado por su double argumento.

Para obtener información sobre la Distance estructura, vea Ubicación y distancia.

Una vez creado un MapSpan , se puede acceder a las siguientes propiedades para recuperar datos sobre él:

  • Center, de tipo Location, que representa la ubicación en el centro geográfico de MapSpan.
  • LatitudeDegrees, de tipo double, que representa los grados de latitud que abarca .MapSpan
  • LongitudeDegrees, de tipo double, que representa los grados de longitud que abarca .MapSpan
  • Radius, de tipo Distance, que representa el MapSpan radio.

Mover el mapa

Se puede llamar al método Map.MoveToRegion para cambiar la posición y el nivel de zoom de un mapa. Este método acepta un MapSpan argumento que define la región del mapa que se va a mostrar y su nivel de zoom.

En el código siguiente se muestra un ejemplo de cómo mover la región mostrada en un mapa:

using Microsoft.Maui.Maps;
using Microsoft.Maui.Controls.Maps.Map;
...

MapSpan mapSpan = MapSpan.FromCenterAndRadius(location, Distance.FromKilometers(0.444));
map.MoveToRegion(mapSpan);

Acercar el mapa

El nivel de zoom de un Map se puede cambiar sin modificar su ubicación. Esto se puede lograr mediante la interfaz de usuario de mapa o mediante programación llamando al MoveToRegion método con un MapSpan argumento que usa la ubicación actual como Location argumento:

double zoomLevel = 0.5;
double latlongDegrees = 360 / (Math.Pow(2, zoomLevel));
if (map.VisibleRegion != null)
{
    map.MoveToRegion(new MapSpan(map.VisibleRegion.Center, latlongDegrees, latlongDegrees));
}

En este ejemplo, se llama al MoveToRegion método con un MapSpan argumento que especifica la ubicación actual del mapa, a través de la Map.VisibleRegion propiedad y el nivel de zoom como grados de latitud y longitud. El resultado general es que se cambia el nivel de zoom del mapa, pero su ubicación no. Un enfoque alternativo para implementar zoom en un mapa es usar el MapSpan.WithZoom método para controlar el factor de zoom.

Importante

El zoom de un mapa, ya sea a través de la interfaz de usuario del mapa o mediante programación, requiere que la Map.IsZoomEnabled propiedad sea true. Para obtener más información sobre esta propiedad, vea Deshabilitar zoom.

Personalización del comportamiento del mapa

El comportamiento de un Map objeto se puede personalizar estableciendo algunas de sus propiedades y controlando el MapClicked evento.

Nota:

Se puede lograr una personalización adicional del comportamiento del mapa mediante la personalización de su controlador. Para más información, consulte Customize controls with handlers.

Mostrar datos del tráfico

La Map clase define una IsTrafficEnabled propiedad de tipo bool. De forma predeterminada, esta propiedad es false, que indica que los datos de tráfico no se superponen en el mapa. Cuando se establece la propiedad en true, los datos de tráfico se superponen en el mapa.

<maps:Map IsTrafficEnabled="true" />

El código de C# equivalente es el siguiente:

Map map = new Map
{
    IsTrafficEnabled = true
};

Deshabilitar el desplazamiento

La Map clase define una IsScrollEnabled propiedad de tipo bool. De forma predeterminada, esta propiedad es true, que indica que el mapa puede desplazarse. Cuando esta propiedad se establece a false, el mapa no se desplazará.

<maps:Map IsScrollEnabled="false" />

El código de C# equivalente es el siguiente:

Map map = new Map
{
    IsScrollEnabled = false
};

Deshabilitar zoom

La Map clase define una IsZoomEnabled propiedad de tipo bool. De forma predeterminada, esta propiedad es true, que indica que el zoom se puede realizar en el mapa. Cuando esta propiedad se establece en false, el mapa no se puede acercar.

<maps:Map IsZoomEnabled="false" />

El código de C# equivalente es el siguiente:

Map map = new Map
{
    IsZoomEnabled = false
};

Mostrar la ubicación del usuario

La Map clase define una IsShowingUser propiedad de tipo bool. De forma predeterminada, esta propiedad es false, que indica que el mapa no muestra la ubicación actual del usuario. Cuando esta propiedad se establece en true, el mapa muestra la ubicación actual del usuario.

<maps:Map IsShowingUser="true" />

El código de C# equivalente es el siguiente:

Map map = new Map
{
    IsShowingUser = true
};

Importante

El acceso a la ubicación del usuario requiere que se hayan concedido permisos de ubicación a la aplicación. Para obtener más información, consulte Configuración de la plataforma.

Clics de mapa

La Map clase define un MapClicked evento que se desencadena cuando se pulsa el mapa. El MapClickedEventArgs objeto que acompaña al evento tiene una sola propiedad denominada Location, de tipo Location. Cuando se desencadena el evento, la Location propiedad se establece en la ubicación del mapa que ha sido pulsada. Para obtener información sobre la Location clase , vea Ubicación y distancia.

En el ejemplo de código siguiente se muestra un controlador de eventos para el MapClicked evento:

void OnMapClicked(object sender, MapClickedEventArgs e)
{
    System.Diagnostics.Debug.WriteLine($"MapClick: {e.Location.Latitude}, {e.Location.Longitude}");
}

En este ejemplo, el OnMapClicked controlador de eventos genera la latitud y la longitud que representan la ubicación del mapa tocada. El controlador de eventos debe registrarse con el MapClicked evento :

<maps:Map MapClicked="OnMapClicked" />

El código de C# equivalente es el siguiente:

Map map = new Map();
map.MapClicked += OnMapClicked;

Ubicación y distancia

El Microsoft.Maui.Devices.Sensors espacio de nombres contiene una clase Location que se usa normalmente al colocar un mapa y sus marcadores. El Microsoft.Maui.Maps espacio de nombres contiene una Distance estructura que se puede usar opcionalmente al colocar un mapa.

Ubicación

La Location clase encapsula una ubicación almacenada como valores de latitud y longitud. Esta clase define las siguientes propiedades:

  • Accuracy, de tipo double?, que representa la precisión horizontal de Location, en metros.
  • Altitude, de tipo double?, que representa la altitud en metros en un sistema de referencia especificado por la propiedad AltitudeReferenceSystem.
  • AltitudeReferenceSystem, de tipo AltitudeReferenceSystem, que especifica el sistema de referencia en el que se proporciona el valor de altitud.
  • Course, de tipo double?, que indica el valor en grados relativo al norte verdadero.
  • IsFromMockProvider, de tipo bool, que indica si la ubicación es del GPS o de un proveedor de ubicación ficticio.
  • Latitude, de tipo double, que representa la latitud de la ubicación en grados decimales.
  • Longitude, de tipo double, que representa la longitud de la ubicación en grados decimales.
  • Speed, de tipo double?, que representa la velocidad en metros por segundo.
  • Timestamp, de tipo DateTimeOffset, que representa la marca de tiempo en el momento en que se creó Location.
  • VerticalAccuracy, de tipo double?, que especifica la precisión vertical de Location, en metros.

Location Los objetos se crean con una de las sobrecargas del Location constructor, que normalmente requieren argumentos de latitud y longitud mínimos especificados como double valores:

Location location = new Location(36.9628066, -122.0194722);

Al crear un Location objeto, el valor de latitud se fijará entre -90.0 y 90.0, y el valor de longitud se fijará entre -180.0 y 180.0.

Nota:

La GeographyUtils clase tiene un ToRadians método de extensión que convierte un double valor de grados a radianes y un ToDegrees método de extensión que convierte un double valor de radianes a grados.

La Location clase también tiene CalculateDistance métodos que calculan la distancia entre dos ubicaciones.

Distancia

El Distance struct encapsula una distancia almacenada como un double valor, que representa la distancia en metros. Esta estructura define tres propiedades de solo lectura:

  • Kilometers, de tipo double, que representa la distancia en kilómetros que abarca por el Distance.
  • Meters, de tipo double, que representa la distancia en metros que abarca Distance.
  • Miles, de tipo double, que representa la distancia en millas que abarca el Distance.

DistanceLos objetos se pueden crear con el Distance constructor , que requiere un argumento meters especificado como :double

Distance distance = new Distance(1450.5);

Como alternativa, los objetos Distance se pueden crear con los métodos de fábrica FromKilometers, FromMeters, FromMiles y BetweenPositions:

Distance distance1 = Distance.FromKilometers(1.45); // argument represents the number of kilometers
Distance distance2 = Distance.FromMeters(1450.5);   // argument represents the number of meters
Distance distance3 = Distance.FromMiles(0.969);     // argument represents the number of miles
Distance distance4 = Distance.BetweenPositions(location1, location2);

Pines

El Map control permite marcar ubicaciones con Pin objetos . Un Pin es un marcador de mapa que abre una ventana de información cuando se pulsa:

Captura de pantalla de un pin de mapa y su ventana de información.

Cuando se agrega un Pin objeto a la Map.Pins colección, el pin se representa en el mapa.

La clase Pin tiene las siguientes propiedades:

  • Address, de tipo string, que normalmente representa la dirección de la ubicación del anclaje. Sin embargo, puede ser cualquier string contenido, no solo una dirección.
  • Label, de tipo string, que normalmente representa el título del pin.
  • Location, de tipo Location, que representa la latitud y la longitud del pin.
  • Type, de tipo PinType, que representa el tipo de pin.

Estas propiedades están respaldadas por BindableProperty objetos, lo que significa que un Pin puede ser el destino de los enlaces de datos. Para obtener más información sobre los objetos de vínculo Pin de datos, vea Mostrar una colección de pins.

Además, la Pin clase define los eventos MarkerClicked y InfoWindowClicked. El MarkerClicked evento se desencadena cuando se pulsa un pin y el InfoWindowClicked evento se desencadena cuando se pulsa la ventana de información. El PinClickedEventArgs objeto que acompaña a ambos eventos tiene una sola HideInfoWindow propiedad, de tipo bool.

Mostrar un pin

Se Pin puede agregar a un Map en XAML.

<ContentPage ...
             xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
             xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
    <maps:Map x:Name="map">
        <x:Arguments>
            <maps:MapSpan>
                <x:Arguments>
                    <sensors:Location>
                        <x:Arguments>
                            <x:Double>36.9628066</x:Double>
                            <x:Double>-122.0194722</x:Double>
                        </x:Arguments>
                    </sensors:Location>
                    <x:Double>0.01</x:Double>
                    <x:Double>0.01</x:Double>
                </x:Arguments>
            </maps:MapSpan>
        </x:Arguments>
        <maps:Map.Pins>
            <maps:Pin Label="Santa Cruz"
                      Address="The city with a boardwalk"
                      Type="Place">
                <maps:Pin.Location>
                    <sensors:Location>
                        <x:Arguments>
                            <x:Double>36.9628066</x:Double>
                            <x:Double>-122.0194722</x:Double>
                        </x:Arguments>
                    </sensors:Location>
                </maps:Pin.Location>
            </maps:Pin>
        </maps:Map.Pins>
    </maps:Map>
</ContentPage>

Este XAML crea un Map objeto que muestra la región especificada por el MapSpan objeto . El MapSpan objeto está centrado en la latitud y la longitud representadas por un Location objeto, que extiende 0,01 grados de latitud y longitud. Se agrega un Pin objeto a la Map.Pins colección y se dibuja en el Map en la ubicación especificada por su propiedad Location. Para obtener información sobre la Location clase , vea Ubicación y distancia. Para obtener información sobre cómo pasar argumentos en XAML a objetos que carecen de constructores predeterminados, consulta Pasar argumentos en XAML.

El código de C# equivalente es el siguiente:

using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...

Map map = new Map
{
  ...
};

Pin pin = new Pin
{
  Label = "Santa Cruz",
  Address = "The city with a boardwalk",
  Type = PinType.Place,
  Location = new Location(36.9628066, -122.0194722)
};
map.Pins.Add(pin);

Este código de ejemplo da como resultado una sola patilla que se representa en un mapa:

Captura de pantalla de un pin de mapa.

Interactuar con un pin

De forma predeterminada, cuando se pulsa en un Pin, su ventana de información se muestra.

Captura de pantalla de un pin de mapa y su ventana de información.

Al pulsar en otro lugar del mapa, se cierra la ventana de información.

La Pin clase define un MarkerClicked evento, que se desencadena cuando se pulsa un Pin. No es necesario controlar este evento para mostrar la ventana de información. En su lugar, este evento debe controlarse cuando hay un requisito para recibir una notificación de que se ha pulsado un pin específico.

La Pin clase también define un InfoWindowClicked evento que se desencadena cuando se pulsa una ventana de información. Este evento debe controlarse cuando se necesita recibir una notificación de que se ha pulsado una ventana de información específica.

En el código siguiente se muestra un ejemplo de control de estos eventos:

using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...

Pin boardwalkPin = new Pin
{
    Location = new Location(36.9641949, -122.0177232),
    Label = "Boardwalk",
    Address = "Santa Cruz",
    Type = PinType.Place
};
boardwalkPin.MarkerClicked += async (s, args) =>
{
    args.HideInfoWindow = true;
    string pinName = ((Pin)s).Label;
    await DisplayAlert("Pin Clicked", $"{pinName} was clicked.", "Ok");
};

Pin wharfPin = new Pin
{
    Location = new Location(36.9571571, -122.0173544),
    Label = "Wharf",
    Address = "Santa Cruz",
    Type = PinType.Place
};
wharfPin.InfoWindowClicked += async (s, args) =>
{
    string pinName = ((Pin)s).Label;
    await DisplayAlert("Info Window Clicked", $"The info window was clicked for {pinName}.", "Ok");
};
using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...

Pin boardwalkPin = new Pin
{
    Location = new Location(36.9641949, -122.0177232),
    Label = "Boardwalk",
    Address = "Santa Cruz",
    Type = PinType.Place
};
boardwalkPin.MarkerClicked += async (s, args) =>
{
    args.HideInfoWindow = true;
    string pinName = ((Pin)s).Label;
    await DisplayAlertAsync("Pin Clicked", $"{pinName} was clicked.", "Ok");
};

Pin wharfPin = new Pin
{
    Location = new Location(36.9571571, -122.0173544),
    Label = "Wharf",
    Address = "Santa Cruz",
    Type = PinType.Place
};
wharfPin.InfoWindowClicked += async (s, args) =>
{
    string pinName = ((Pin)s).Label;
    await DisplayAlertAsync("Info Window Clicked", $"The info window was clicked for {pinName}.", "Ok");
};

El PinClickedEventArgs objeto que acompaña a ambos eventos tiene una sola HideInfoWindow propiedad, de tipo bool. Cuando esta propiedad se establece en true dentro de un controlador de eventos, la ventana de información se ocultará.

Tipos de anclaje

Pin Los objetos incluyen una propiedad Type de tipo PinType, que representa el tipo de pin. La enumeración PinType define los miembros siguientes:

  • Generic, representa un pin genérico.
  • Place, representa un pin para un lugar.
  • SavedPin, representa un pin para una ubicación guardada.
  • SearchResult, representa un pin para un resultado de búsqueda.

Sin embargo, establecer la Pin.Type propiedad en cualquier PinType miembro no cambia la apariencia del pin representado. En su lugar, debe personalizar el manejador del Pin para personalizar la apariencia del pin. Para obtener más información sobre la personalización del controlador, consulte Personalización de controles con controladores.

Mostrar una colección de insignias

La Map clase define las siguientes propiedades enlazables:

  • ItemsSource, de tipo IEnumerable, que especifica la colección de elementos de pin IEnumerable que se van a mostrar.
  • ItemTemplate de tipo DataTemplate, que especifica el DataTemplate que se va a aplicar a cada elemento de la colección de pines mostrados.
  • ItemTemplateSelector, de tipo DataTemplateSelector, que especifica el DataTemplateSelector que se usará para elegir un DataTemplate para un pin en tiempo de ejecución.

Importante

La ItemTemplate propiedad tiene prioridad cuando se establecen las ItemTemplate propiedades y ItemTemplateSelector .

Se Map puede rellenar con pines mediante el enlace de datos para enlazar su ItemsSource propiedad a una IEnumerable colección:

<ContentPage ...
             xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps">    
    <Grid>
        ...
        <maps:Map x:Name="map"
                  ItemsSource="{Binding Positions}">
            <maps:Map.ItemTemplate>
                <DataTemplate x:DataType="models:Position">
                    <maps:Pin Location="{Binding Location}"
                              Address="{Binding Address}"
                              Label="{Binding Description}" />
                </DataTemplate>    
            </maps:Map.ItemTemplate>
        </maps:Map>
        ...
    </Grid>
</ContentPage>

Los datos de la propiedad ItemsSource se enlazan a la propiedad Positions del modelo de vista conectado, que devuelve un ObservableCollection de objetos Position, que es un tipo personalizado. Cada Position objeto define Address las propiedades y Description , de tipo string, y una Location propiedad , de tipo Location.

La apariencia de cada elemento de la IEnumerable colección se define estableciendo la ItemTemplate propiedad en un DataTemplate que contiene un Pin objeto que los datos enlazan a las propiedades adecuadas.

En la captura de pantalla siguiente se muestra una MapPin recopilación mediante el enlace de datos:

Captura de pantalla del mapa con marcadores vinculados a datos.

Elección de la apariencia del elemento en tiempo de ejecución

La apariencia de cada elemento de la IEnumerable colección se puede elegir en tiempo de ejecución, en función del valor del elemento, estableciendo la ItemTemplateSelector propiedad en :DataTemplateSelector

<ContentPage ...
             xmlns:templates="clr-namespace:WorkingWithMaps.Templates"
             xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
             xmlns:viewmodels="clr-namespace:WorkingWithMaps.ViewModels"
             x:DataType="viewmodels:PinItemsSourcePageViewModel">
    <ContentPage.Resources>
       <templates:MapItemTemplateSelector x:Key="MapItemTemplateSelector">
           <templates:MapItemTemplateSelector.DefaultTemplate>
               <DataTemplate x:DataType="models:Position">
                   <maps:Pin Location="{Binding Location}"
                             Address="{Binding Address}"
                             Label="{Binding Description}" />
               </DataTemplate>
           </templates:MapItemTemplateSelector.DefaultTemplate>
           <templates:MapItemTemplateSelector.SanFranTemplate>
               <DataTemplate x:DataType="models:Position">
                   <maps:Pin Location="{Binding Location}"
                             Address="{Binding Address}"
                             Label="Xamarin!" />
               </DataTemplate>
           </templates:MapItemTemplateSelector.SanFranTemplate>    
       </templates:MapItemTemplateSelector>
    </ContentPage.Resources>

    <Grid>
        ...
        <maps:Map x:Name="map"
                  ItemsSource="{Binding Positions}"
                  ItemTemplateSelector="{StaticResource MapItemTemplateSelector}">
        ...
    </Grid>
</ContentPage>

En el ejemplo siguiente se muestra la MapItemTemplateSelector clase :

using WorkingWithMaps.Models;

namespace WorkingWithMaps.Templates;

public class MapItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate DefaultTemplate { get; set; }
    public DataTemplate SanFranTemplate { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        return ((Position)item).Address.Contains("San Francisco") ? SanFranTemplate : DefaultTemplate;
    }
}

La MapItemTemplateSelector clase define DefaultTemplate y SanFranTemplateDataTemplate propiedades que se asignan a plantillas de datos diferentes. El método OnSelectTemplate devuelve el SanFranTemplate, que muestra "Xamarin" como texto cuando se pulsa un Pin, en el caso de que el elemento tenga una dirección que contenga "San Francisco". Cuando el elemento no tiene una dirección que contenga "San Francisco", el OnSelectTemplate método devuelve .DefaultTemplate

Nota:

Un caso de uso de esta funcionalidad es enlazar propiedades de objetos subclases Pin a diferentes propiedades, en función del Pin subtipo.

Para obtener más información sobre los selectores de plantillas de datos, consulte Creación de un dataTemplateSelector.

Polígonos, polilíneas y círculos

PolygonLos elementos , Polyliney Circle permiten resaltar áreas específicas en un mapa. Un Polygon es una forma completamente cerrada que puede tener un trazo y un color de relleno. Una Polyline es una línea que no encierra completamente un área. Un Circle resaltado de un área circular del mapa:

Polígono y polilínea en un mapa. Círculo en un mapa.

Las Polygonclases , Polyliney Circle derivan de la MapElement clase , que expone las siguientes propiedades enlazables:

  • StrokeColor es un Color objeto que determina el color de línea.
  • StrokeWidth es un float objeto que determina el ancho de línea.

La Polygon clase define una propiedad enlazable adicional:

  • FillColor es un Color objeto que determina el color de fondo del polígono.

Además, las Polygon clases y Polyline definen una GeoPath propiedad , que es una lista de Location objetos que especifican los puntos de la forma.

La Circle clase define las siguientes propiedades enlazables:

  • Center es un Location objeto que define el centro del círculo, en latitud y longitud.
  • Radius es un Distance objeto que define el radio del círculo en metros, kilómetros o millas.
  • FillColor es una Color propiedad que determina el color dentro del perímetro del círculo.

Creación de un polígono

Un Polygon objeto se puede agregar a un mapa creando una instancia de él y agregándolo a la colección del MapElements mapa:

<ContentPage ...
             xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
             xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
    <maps:Map>
        <maps:Map.MapElements>
            <maps:Polygon StrokeColor="#FF9900"
                          StrokeWidth="8"
                          FillColor="#88FF9900">
                <maps:Polygon.Geopath>
                    <sensors:Location>
                        <x:Arguments>
                            <x:Double>47.6458676</x:Double>
                            <x:Double>-122.1356007</x:Double>
                        </x:Arguments>
                    </sensors:Location>
                    <sensors:Location>
                        <x:Arguments>
                            <x:Double>47.6458097</x:Double>
                            <x:Double>-122.142789</x:Double>
                        </x:Arguments>
                    </sensors:Location>
                    ...
                </maps:Polygon.Geopath>
            </maps:Polygon>
        </maps:Map.MapElements>
    </maps:Map>
</ContentPage>

El código de C# equivalente es el siguiente:

using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...

Map map = new Map();

// Instantiate a polygon
Polygon polygon = new Polygon
{
    StrokeWidth = 8,
    StrokeColor = Color.FromArgb("#1BA1E2"),
    FillColor = Color.FromArgb("#881BA1E2"),
    Geopath =
    {
        new Location(47.6368678, -122.137305),
        new Location(47.6368894, -122.134655),
        ...
    }
};

// Add the polygon to the map's MapElements collection
map.MapElements.Add(polygon);

Las StrokeColor propiedades y StrokeWidth se especifican para establecer el esquema del polígono. En este ejemplo, el FillColor valor de propiedad coincide con el StrokeColor valor de propiedad, pero tiene un valor alfa especificado para que sea transparente, lo que permite que el mapa subyacente sea visible a través de la forma. La GeoPath propiedad contiene una lista de Location objetos que definen las coordenadas geográficas de los puntos de polígono. Un Polygon objeto se representa en el mapa una vez que se ha agregado a la MapElements colección de Map.

Nota:

Un Polygon es una forma totalmente cerrada. Los puntos primero y último se conectarán automáticamente si no coinciden.

Creación de una polilínea

Un Polyline objeto se puede agregar a un mapa creando una instancia de él y agregándolo a la colección del MapElements mapa:

<ContentPage ...
             xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
             xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
    <maps:Map>
        <maps:Map.MapElements>
            <maps:Polyline StrokeColor="Black"
                           StrokeWidth="12">
                <maps:Polyline.Geopath>
                    <sensors:Location>
                        <x:Arguments>
                            <x:Double>47.6381401</x:Double>
                            <x:Double>-122.1317367</x:Double>
                        </x:Arguments>
                    </sensors:Location>
                    <sensors:Location>
                        <x:Arguments>
                            <x:Double>47.6381473</x:Double>
                            <x:Double>-122.1350841</x:Double>
                        </x:Arguments>
                    </sensors:Location>
                    ...
                </maps:Polyline.Geopath>
            </maps:Polyline>
        </maps:Map.MapElements>
    </maps:Map>
</ContentPage>

El código de C# equivalente es el siguiente:

using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...

Map map = new Map();

// instantiate a polyline
Polyline polyline = new Polyline
{
    StrokeColor = Colors.Blue,
    StrokeWidth = 12,
    Geopath =
    {
        new Location(47.6381401, -122.1317367),
        new Location(47.6381473, -122.1350841),
        ...
    }
};

// Add the Polyline to the map's MapElements collection
map.MapElements.Add(polyline);

Las StrokeColor propiedades y StrokeWidth se especifican para establecer la apariencia de línea. La GeoPath propiedad contiene una lista de Location objetos que definen las coordenadas geográficas de los puntos de polilínea. Un Polyline objeto se representa en el mapa una vez que se ha agregado a la MapElements colección de Map.

Crear un círculo

Un Circle objeto se puede agregar a un mapa creando una instancia de él y agregándolo a la colección del MapElements mapa:

<ContentPage ...
             xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
             xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
    <maps:Map>
        <maps:Map.MapElements>
            <maps:Circle StrokeColor="#88FF0000"
                         StrokeWidth="8"
                         FillColor="#88FFC0CB">
                <maps:Circle.Center>
                    <sensors:Location>
                        <x:Arguments>
                            <x:Double>37.79752</x:Double>
                            <x:Double>-122.40183</x:Double>
                        </x:Arguments>
                    </sensors:Location>
                </maps:Circle.Center>
                <maps:Circle.Radius>
                    <maps:Distance>
                        <x:Arguments>
                            <x:Double>250</x:Double>
                        </x:Arguments>
                    </maps:Distance>
                </maps:Circle.Radius>
            </maps:Circle>             
        </maps:Map.MapElements>
    </maps:Map>
</ContentPage>

El código de C# equivalente es el siguiente:

using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;

Map map = new Map();

// Instantiate a Circle
Circle circle = new Circle
{
    Center = new Location(37.79752, -122.40183),
    Radius = new Distance(250),
    StrokeColor = Color.FromArgb("#88FF0000"),
    StrokeWidth = 8,
    FillColor = Color.FromArgb("#88FFC0CB")
};

// Add the Circle to the map's MapElements collection
map.MapElements.Add(circle);

La ubicación de Circle en el mapa viene determinada por el valor de las Center propiedades y Radius . La Center propiedad define el centro del círculo, en latitud y longitud, mientras que la Radius propiedad define el radio del círculo en metros. Las StrokeColor propiedades y StrokeWidth se especifican para establecer el contorno del círculo. El FillColor valor de la propiedad especifica el color dentro del perímetro del círculo. En este ejemplo, ambos valores de color especifican un canal alfa, lo que permite que el mapa subyacente sea visible a través del círculo. El Circle objeto se representa en el mapa una vez que se ha agregado a la MapElements colección de Map.

Nota:

La GeographyUtils clase tiene un ToCircumferencePositions método de extensión que convierte un Circle objeto (que define Center y Radius valores de propiedad) en una lista de Location objetos que componen las coordenadas de latitud y longitud del perímetro del círculo.

Geocodificación y geolocalización

La clase Geocoding, en el espacio de nombres Microsoft.Maui.Devices.Sensors, se puede usar para geocodificar una marca de posición en coordenadas posicionales y geocodificar inversamente coordenadas en una marca de posición. Para obtener más información, consulte Geocodificación.

La Geolocation clase , en el Microsoft.Maui.Devices.Sensors espacio de nombres , se puede usar para recuperar las coordenadas de geolocalización actuales del dispositivo. Para obtener más información, consulte Geolocalización.

Inicio de la aplicación de mapa nativo

La aplicación de mapa nativa en cada plataforma se puede iniciar desde una aplicación MAUI de .NET mediante la Launcher clase . Esta clase permite que una aplicación abra otra aplicación a través de su esquema de URI personalizado. La funcionalidad del iniciador se puede invocar con el OpenAsync método , pasando un string argumento o Uri que representa el esquema de dirección URL personalizado que se va a abrir. Para obtener más información sobre la Launcher clase, vea Launcher.

Nota:

Una alternativa al uso de la clase Launcher es usar la clase Map del espacio de nombres Microsoft.Maui.ApplicationModel. Para obtener más información, consulte Mapa.

La aplicación de mapas en cada plataforma usa un esquema de URI personalizado único. Para más información sobre el esquema de URI de mapas en iOS, consulte Vínculos de mapas en developer.apple.com. Para obtener información sobre el esquema de URI de mapas en Android, consulte la Guía para desarrolladores de Maps y Intenciones de Google Maps para Android en developers.android.com. Para obtener información sobre el esquema de URI de mapas en Windows, consulta Iniciar la aplicación Mapas de Windows.

Inicio de la aplicación de mapa en una ubicación específica

Se puede abrir una ubicación en la aplicación de mapas nativas agregando parámetros de consulta adecuados al esquema de URI personalizado para cada aplicación de mapa:

if (DeviceInfo.Current.Platform == DevicePlatform.iOS || DeviceInfo.Current.Platform == DevicePlatform.MacCatalyst)
{
    // https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html
    await Launcher.OpenAsync("http://maps.apple.com/?q=394+Pacific+Ave+San+Francisco+CA");
}
else if (DeviceInfo.Current.Platform == DevicePlatform.Android)
{
    // opens the Maps app directly
    await Launcher.OpenAsync("geo:0,0?q=394+Pacific+Ave+San+Francisco+CA");
}
else if (DeviceInfo.Current.Platform == DevicePlatform.WinUI)
{
    await Launcher.OpenAsync("bingmaps:?where=394 Pacific Ave San Francisco CA");
}

Este código de ejemplo da como resultado que la aplicación de mapa nativa se inicie en cada plataforma, con el mapa centrado en un pin que representa la ubicación especificada.

Inicio de la aplicación de mapa con instrucciones

La aplicación de mapas nativos se puede iniciar para mostrar instrucciones, agregando parámetros de consulta adecuados al esquema de URI personalizado para cada aplicación de mapa:

if (DeviceInfo.Current.Platform == DevicePlatform.iOS || DeviceInfo.Current.Platform == DevicePlatform.MacCatalyst)
{
    // https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html
    await Launcher.OpenAsync("http://maps.apple.com/?daddr=San+Francisco,+CA&saddr=cupertino");
}
else if (DeviceInfo.Current.Platform == DevicePlatform.Android)
{
    // opens the 'task chooser' so the user can pick Maps, Chrome or other mapping app
    await Launcher.OpenAsync("http://maps.google.com/?daddr=San+Francisco,+CA&saddr=Mountain+View");
}
else if (DeviceInfo.Current.Platform == DevicePlatform.WinUI)
{
    await Launcher.OpenAsync("bingmaps:?rtp=adr.394 Pacific Ave San Francisco CA~adr.One Microsoft Way Redmond WA 98052");
}

Este código de ejemplo da como resultado que la aplicación de mapa nativa se inicie en cada plataforma, con el mapa centrado en una ruta entre las ubicaciones especificadas.