Resumen del capítulo 28. Ubicación y mapas
Nota:
Este libro se publicó en la primavera de 2016 y no se ha actualizado desde entonces. Gran parte del libro sigue siendo útil, pero algunos de los materiales están anticuados y algunos temas ya no son completamente correctos o completos.
Xamarin.Forms admite un elemento Map
derivado de View
. Debido a los requisitos de la plataforma especial implicados en el uso de mapas, se implementan en un ensamblado independiente, Xamarin.Forms.Maps, e implican un espacio de nombres diferente: Xamarin.Forms.Maps
.
Sistema de coordenadas geográfico
Un sistema de coordenadas geográfico identifica las posiciones en un objeto esférico (o casi esférico) como la Tierra. Una coordenada consta de una latitud y longitud expresadas en ángulos.
Un círculo excelente denominado equator
está a la mitad del intervalo entre los dos polos a través de los cuales se extiende conceptualmente el eje de la Tierra.
Paralelos y latitud
Un ángulo medido al norte o al sur del ecuador desde el centro de la Tierra marca las líneas de igual latitud conocidas como paralelos. Van desde 0 grados en el ecuador hasta 90 grados en los polos norte y sur. Convencionalmente, las latitudes al norte del ecuador son valores positivos y al sur del ecuador son valores negativos.
Longitud y meridianos
Los semicírculos máximos desde el polo norte al polo sur son líneas de la misma longitud, también conocidas como meridianos. Se refieren al meridiano cero de Greenwich, Inglaterra. Convencionalmente, las longitudes al este del meridiano cero son valores positivos que van desde 0 hasta 180 grados, y las longitudes al oeste del meridiano cero son valores negativos desde 0 hasta –180 grados.
Proyección equirectangular
Cualquier mapa plano de la Tierra introduce distorsiones. Si todas las líneas de latitud y longitud son rectas, y si las diferencias iguales en los ángulos de latitud y longitud se corresponden con las mismas distancias en el mapa, el resultado es una proyección equirectangular. Este mapa distorsiona las áreas más próximas a los polos porque se extienden horizontalmente.
Proyección de Mercator
La popular proyección de Mercator intenta compensar la ampliación horizontal mediante la ampliación vertical de estas áreas. Esto da como resultado un mapa en el que las áreas cercanas a los polos aparecen mucho más grandes de lo que son en realidad, pero cualquier área local se ajusta bastante al área real.
Iconos y servicios de mapas
Los servicios de mapas usan una variación de la proyección de Mercator denominada Web Mercator
. Los servicios de mapas ofrecen iconos de mapa de bits a un cliente en función de la ubicación y el nivel de zoom.
Obtener la ubicación del usuario
Las clases Map
de Xamarin.Forms no incluyen instalaciones para obtener la ubicación geográfica del usuario, pero esto suele ser conveniente cuando se trabaja con mapas, por lo que un servicio de dependencia debe controlar esta cuestión.
Nota:
En su lugar, las aplicaciones Xamarin.Forms pueden usar la clase Geolocation
incluida en Xamarin.Essentials.
API de seguimiento de ubicación
La solución Xamarin.FormsBook.Platform contiene código para una API de herramienta de seguimiento de ubicación. La estructura GeographicLocation
encapsula una latitud y una longitud. La interfaz ILocationTracker
define dos métodos para iniciar y pausar el seguimiento de la ubicación, y un evento cuando hay una nueva ubicación disponible.
Administrador de ubicación en iOS
La implementación en iOS de ILocationTracker
es una clase LocationTracker
que hace uso de CLLocationManager
en iOS.
Administrador de ubicación en Android
La implementación en Android de ILocationTracker
es una clase LocationTracker
que hace uso de la clase LocationManager
en Android.
Localizador geográfico en la UWP
La implementación en la Plataforma universal de Windows de ILocationTracker
es una clase LocationTracker
que hace uso de Geolocator
en la UWP.
Mostrar la ubicación del teléfono
El ejemplo WhereAmI usa el seguimiento de ubicación para mostrar la ubicación del teléfono, tanto en texto como en un mapa equirectangular.
Sobrecarga necesaria
Se requiere cierta sobrecarga para que WhereAmI use el seguimiento de ubicación. En primer lugar, todos los proyectos de la solución WhereAmI deben tener referencias a los proyectos correspondientes en Xamarin.FormsBook.Platform, y cada proyecto de WhereAmI debe llamar al método Toolkit.Init
.
Se requiere una sobrecarga adicional específica de la plataforma, en forma de permisos de ubicación.
Permiso de ubicación para iOS
En el caso de iOS, el archivo info. plist debe incluir elementos que contengan el texto de una pregunta que pida al usuario que permita obtener la ubicación de ese usuario.
Permisos de ubicación para Android
Las aplicaciones Android que obtienen la ubicación del usuario deben tener un permiso ACCESS_FILE_LOCATION en el archivo AndroidManifest.xml.
Permisos de ubicación para la UWP
Una aplicación de la Plataforma universal de Windows debe tener una funcionalidad de dispositivo location
marcada en el archivo Package.appxmanifest.
Trabajar con Xamarin.Forms.Maps
Hay varios requisitos implicados en el uso de la clase Map
.
Paquete NuGet
La biblioteca de NuGet Xamarin.Forms.Maps se debe agregar a la solución de la aplicación. El número de versión debe ser el mismo que el paquete Xamarin.Forms instalado actualmente.
Inicializar el paquete de mapas
Los proyectos de aplicaciones deben llamar al método Xamarin.FormsMaps.Init
después de hacer una llamada a Xamarin.Forms.Forms.Init
.
Habilitación de servicios de mapas
Dado que Map
puede obtener la ubicación del usuario, la aplicación debe obtener permiso para el usuario de la manera descrita anteriormente en este capítulo:
Habilitación de mapas de iOS
Una aplicación de iOS que usa Map
necesita dos líneas en el archivo info.plist.
Habilitación de mapas de Android
Se requiere una clave de autorización para usar los servicios de mapa de Google. Esta clave está insertada en el archivo AndroidManifest.xml. Además, el archivo AndroidManifest.xml requiere las etiquetas manifest
implicadas en la obtención de la ubicación del usuario.
Habilitación de mapas de la UWP
Una aplicación de la Plataforma universal de Windows requiere una clave de autorización para usar Bing Maps. Esta clave se pasa como un argumento al método Xamarin.FormsMaps.Init
. La aplicación también debe estar habilitada para los servicios de ubicación.
Mapa sin adornar
El ejemplo MapDemos consta de un archivo MapsDemoHomePage.xaml y un archivo de código subyacente MapsDemoHomePage.xaml.cs que permite navegar a varios programas de demostración.
En el archivo BasicMapPage.xaml se muestra cómo mostrar la vista Map
. De forma predeterminada, muestra la ciudad de Roma, pero el usuario puede manipular el mapa.
Para deshabilitar el desplazamiento horizontal y vertical, establezca la propiedad HasScrollEnabled
en false
. Para deshabilitar el zoom, establezca HasZoomEnabled
en false
. Es posible que estas propiedades no funcionen en todas las plataformas.
Calles y terreno
Puede mostrar diferentes tipos de mapas estableciendo la propiedad Map
en MapType
de tipo MapType
, una enumeración con tres miembros:
En el archivo MapTypesPage.xaml se muestra cómo usar un botón de radio para seleccionar el tipo de mapa. Hace uso de la clase RadioButtonManager
en la biblioteca Xamarin.FormsBook.Toolkit y una clase basada en el archivo MapTypeRadioButton.xaml.
Coordenadas de mapa
Un programa puede obtener el área actual en la que se muestra Map
a través de la propiedad VisibleRegion
. Esta propiedad no está respaldada por una propiedad enlazable y no hay ningún mecanismo de notificación para indicar cuándo ha cambiado, por lo que un programa que desee supervisar la propiedad probablemente debería usar un temporizador para ese propósito.
VisibleRegion
es de tipo MapSpan
, una clase con cuatro propiedades de solo lectura:
Center
de tipoPosition
LatitudeDegrees
de tipodouble
, que indica la altura del área mostrada del mapaLongitudeDegrees
de tipodouble
, que indica la anchura del área mostrada del mapaRadius
de tipoDistance
, que indica el tamaño del área circular más grande visible en el mapa
Position
y Distance
son estructuras. Position
define dos propiedades de solo lectura establecidas mediante el constructor Position
:
Distance
está diseñado para proporcionar una distancia independiente de la unidad mediante la conversión entre las unidades métricas e imperiales. Un valor Distance
se puede crear de varias maneras:
- Constructor
Distance
, con una distancia en metros - Método estático
Distance.FromMeters
- Método estático
Distance.FromKilometers
- Método estático
Distance.FromMiles
El valor está disponible a partir de tres propiedades:
Meters
de tipodouble
Kilometers
de tipodouble
Miles
de tipodouble
El archivo MapCoordinatesPage.xaml contiene varios elementos Label
para mostrar la información de MapSpan
. En el archivo de código subyacente MapCoordinatesPage.xaml.cs se usa un temporizador para mantener la información actualizada cuando el usuario manipula el mapa.
Extensiones de posición
Una nueva biblioteca para este libro denominada Xamarin.FormsBook.Toolkit.Maps contiene tipos específicos de mapa pero independientes de la plataforma. La clase PositionExtensions
tiene un método ToString
para Position
y un método para calcular la distancia entre dos valores Position
.
Establecimiento de una ubicación inicial
Puede llamar al método MoveToRegion
de Map
para establecer mediante programación una ubicación y un nivel de zoom en el mapa. El argumento es de tipo MapSpan
. Puede crear un objeto MapSpan
con una de las siguientes opciones:
- Constructor
MapSpan
conPosition
, y un intervalo de latitud y longitud MapSpan.FromCenterAndRadius
conPosition
y radio
También es posible crear un nuevo atributo MapSpan
a partir de uno existente mediante los métodos ClampLatitude
o WithZoom
.
El archivo WyomingPage.xaml y el archivo de código subyacente WyomingPage.xaml.cs demuestran cómo utilizar el método MoveToRegion
para mostrar el estado de Wyoming.
También puede usar el constructor Map
con un objeto MapSpan
para inicializar la ubicación del mapa. En el archivo XamarinHQPage.xaml se muestra cómo hacerlo completamente en XAML para mostrar las oficinas centrales de Xamarin en San Francisco.
Zoom dinámico
Puede usar Slider
para aplicar el zoom dinámico a un mapa. El archivo RadiusZoomPage.xaml y el archivo de código subyacente RadiusZoomPage.xaml.cs muestran cómo cambiar el radio de un mapa en función del valor Slider
.
El archivo LongitudeZoomPage.xaml y el archivo de código subyacente LongitudeZoomPage.xaml.cs muestran un enfoque alternativo que funciona mejor en Android, pero ningún enfoque funciona bien en las plataformas Windows.
Ubicación del teléfono
La propiedad IsShowingUser
de Map
funciona de forma ligeramente diferente en cada plataforma, como bien muestra el archivo ShowLocationPage.xaml:
- En iOS, un punto azul indica la ubicación del teléfono, pero la navegación es manual.
- En Android, se muestra un icono que, cuando se presiona, mueve el mapa a la ubicación del teléfono.
- La UWP funciona de forma similar a iOS, salvo que, a veces, la navegación hasta la ubicación es automática.
El proyecto MapDemos intenta imitar el enfoque de Android definiendo primero un botón basado en iconos según el archivo MyLocationButton.xaml y el archivo de código subyacente MyLocationButton.xaml.cs.
El archivo GoToLocationPage.xaml y el archivo de código subyacente GoToLocationPage.xaml.cs usan este botón para desplazarse a la ubicación del teléfono.
Marcadores y museos de ciencia
Por último, la clase Map
define una propiedad Pins
de tipo IList<Pin>
. La clase Pin
define cuatro propiedades:
Label
de tipostring
, una propiedad obligatoriaAddress
de tipostring
, una dirección opcional legible por humanosPosition
de tipoPosition
, que indica dónde se muestra el marcador en el mapaType
de tipoPinType
, una enumeración, que no se utiliza
El proyecto MapDemos contiene el archivo ScienceMuseums.xml, que enumera los museos de ciencia de Estados Unidos, y las clases Locations
y Site
para deserializar estos datos.
El archivo ScienceMuseumsPage.xaml y el archivo de código subyacente ScienceMuseumsPage.xaml.cs muestran los marcadores de estos museos de ciencia en el mapa. Cuando el usuario pulsa un marcador, muestra la dirección y un sitio web del museo.
Distancia entre dos puntos
La clase PositionExtensions
contiene un método DistanceTo
con un cálculo simplificado de la distancia entre dos ubicaciones geográficas.
Se usa en el archivo LocalMuseumsPage.xaml y en el archivo de código subyacente LocalMuseumsPage.xaml.cs para mostrar también la distancia al museo de la ubicación del usuario:
El programa también muestra cómo restringir dinámicamente el número de marcadores en función de la ubicación del mapa.
Geocodificación y regreso
El ensamblado Xamarin.Forms.Maps también contiene una clase Geocoder
con un método GetPositionsForAddressAsync
que convierte una dirección de texto en cero o más posiciones geográficas posibles, y otro método GetAddressesForPositionAsync
que convierte en la otra dirección.
El archivo GeocoderRoundTrip.xaml y el archivo de código subyacente GeocoderRoundTrip.xaml.cs demuestran esta utilidad.