Resumen del capítulo 28. Ubicación y mapas

Download SampleDescargar el ejemplo

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:

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:

El valor está disponible a partir de tres propiedades:

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:

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 tipo string, una propiedad obligatoria
  • Address de tipo string, una dirección opcional legible por humanos
  • Position de tipo Position, que indica dónde se muestra el marcador en el mapa
  • Type de tipo PinType, 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:

Triple screenshot of Local Museums Page

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.