Con el SDK de Maps para iOS, puedes cambiar el punto de vista del usuario modificando la cámara del mapa.
Con el SDK de Maps para iOS, los usuarios pueden inclinar y rotar los mapas para ajustarlos a una orientación útil para su contexto. A cualquier nivel de zoom, los usuarios pueden desplazar el mapa o cambiar su perspectiva con una latencia muy reducida.
Los cambios en la cámara no producen cambios en los marcadores, las polilíneas ni otros gráficos que agregues, aunque probablemente te convenga modificar los elementos que agregues para que se ajusten mejor a la vista nueva.
La vista del mapa
El SDK de Maps para iOS usa la proyección de Mercator para representar la superficie de la Tierra (una esfera) en la pantalla de tu dispositivo (un plano).
La posición de la cámara
La vista de mapa responde a un modelo en el cual una cámara apunta hacia abajo sobre un plano. La posición de la cámara (y, por lo tanto, la renderización del mapa) se especifica mediante las siguientes propiedades: objetivo (ubicación de latitud/longitud), rumbo, inclinación y zoom.
Objetivo (ubicación)
El objetivo de la cámara es la ubicación del centro del mapa, especificada como coordenadas de latitud y longitud.
La latitud puede variar entre -85 y 85 grados, inclusive. Los valores superiores o inferiores a este rango se fijarán al valor más cercano dentro de este rango. Por ejemplo, si se especifica una latitud de 100, el valor se fijará en 85. La longitud varía entre -180 y 180 grados, inclusive. Los valores superiores o inferiores a este rango se ajustarán de forma tal que queden dentro del rango (-180, 180). Por ejemplo, 480, 840 y 1200 se ajustarán a 120 grados.Rumbo (orientación)
El rumbo de la cámara especifica la dirección de la brújula, medida en grados a partir del norte verdadero, que corresponde al borde superior del mapa. Si dibujas una línea vertical desde el centro del mapa hasta el borde superior del mapa, el rumbo corresponde a la orientación de la cámara (medida en grados) en relación con el norte verdadero.
Un rumbo igual a 0 significa que la parte superior del mapa apunta al norte verdadero. Un valor de rumbo igual a 90 significa que la parte superior del mapa apunta hacia el este (90 grados en una brújula). Un valor igual a 180 significa que la parte superior del mapa apunta al sur.
La API de Google Maps te permite cambiar el rumbo de un mapa. Quienes conducen un auto a menudo giran el mapa de la ruta para alinearlo con la dirección en la que se desplazan, mientras que los senderistas que usan mapas y brújula suelen orientar los mapas de modo que la línea vertical apunte hacia el norte.
Inclinación (ángulo de visión)
La inclinación es la posición de la cámara en un arco directamente sobre la posición central del mapa, medida en grados a partir del nadir (la dirección que apunta justo debajo de la cámara). Un valor igual a 0 corresponde a una cámara que apunta hacia abajo. Los valores superiores a 0 corresponden a una cámara que se inclina hacia el horizonte según la cantidad de grados especificada. Cuando cambias el ángulo de visión, el mapa aparece en perspectiva; los componentes apartados se ven más pequeños y los cercanos, más grandes. En las siguientes ilustraciones se demuestra esto.
En las siguientes imágenes, el ángulo de visión es de 0 grados. En la primera imagen, se muestra un esquema de esto. La posición 1 es la posición de la cámara, y la 2 es la del mapa actual. El mapa resultante se muestra debajo.
En las siguientes imágenes, el ángulo de visión es de 45 grados. Ten en cuenta que la cámara se desplaza a la mitad del trayecto de un arco entre el cénit (0 grados) y el suelo (90 grados), hasta la posición 3. La cámara continúa apuntando hacia el punto central del mapa, pero ahora puede verse el área representada por la línea en la posición 4.
El mapa de esta captura de pantalla continúa centrado en el mismo punto que el mapa original, aunque aparecieron más componentes en la parte superior. A medida que el ángulo supera los 45 grados, los componentes que se encuentran entre la posición del mapa y la cámara tienen un tamaño proporcionalmente mayor, mientras que los componentes que se encuentran más allá de la posición del mapa tienen un tamaño proporcionalmente menor. Esto genera un efecto tridimensional.
Zoom
El nivel de zoom de la cámara determina la escala del mapa. A mayores niveles de zoom pueden observarse más detalles en la pantalla, mientras que a menores niveles de zoom el mundo se ve de manera más abarcadora. En el nivel de zoom 0, la escala del mapa hace que el mundo tenga un ancho aproximado de 256 puntos.
Un aumento de 1 punto en el nivel de zoom duplica el ancho del mundo en la pantalla. Por lo tanto, con el nivel de zoom N, el ancho del mundo equivale aproximadamente a 256 * 2N puntos. Por ejemplo, en el nivel de zoom 2, el ancho del mundo en su totalidad es de aproximadamente 1,024 puntos.
No es necesario que el nivel de zoom sea un número entero. El rango de niveles de zoom que permite el mapa depende de varios factores, como el objetivo, el tipo de mapa y el tamaño de la pantalla. Cualquier número que esté fuera del rango se convertirá en el siguiente valor válido más cercano, que puede ser el nivel de zoom mínimo o el nivel de zoom máximo. En la siguiente lista, se muestra el nivel aproximado de detalle que puedes esperar ver en cada nivel de zoom:
- 1: Mundo
- 5: Tierra firme y continente
- 10: Ciudad
- 15: Calles
- 20: Edificios
Cómo establecer la posición inicial de la cámara
Establece la posición inicial de la cámara con el objeto GMSCameraPosition
, que te permite establecer la latitud y la longitud del objetivo junto con el rumbo, la inclinación y el zoom.
Para establecer la posición inicial de la cámara, crea un objeto GMSMapViewOptions
y establece la propiedad camera
en GMSCameraPosition
. Luego, pasa tus opciones al constructor de conveniencia GMSMapView
.
Swift
let options = GMSMapViewOptions() options.camera = GMSCameraPosition.camera(withLatitude: -33.8683, longitude: 151.2086, zoom: 16) let mapView = GMSMapView(options:options)
Objective-C
GMSMapViewOptions *options = [[GMSMapViewOptions alloc] init]; options.camera = [GMSCameraPosition cameraWithLatitude:-33.8683 longitude:151.2086 zoom:16]; GMSMapView *mapView = [[GMSMapView alloc] initWithOptions:options];
También puedes crear el objeto GMSMapView
con el método de inicialización UIView
predeterminado. En este caso, la posición de la cámara comienza en la ubicación predeterminada y la puedes cambiar después de la creación.
Swift
let options = GMSMapViewOptions() options.frame = self.view.bounds let mapView = GMSMapView(options:options)
Objective-C
GMSMapViewOptions *options = [[GMSMapViewOptions alloc] init]; options.frame = self.view.bounds; GMSMapView *mapView = [[GMSMapView alloc] initWithOptions:options];
Cómo cambiar la posición de la cámara
Puedes cambiar de manera programática la posición de la cámara para establecer la ubicación, el rumbo, la inclinación y el zoom. Si bien GMSMapView
proporciona varios métodos que puedes usar para cambiar la posición de la cámara, por lo general, se usa GMSCameraPosition
o GMSCameraUpdate
:
GMSCameraPosition
contiene propiedades y métodos que usas para cambiar todos los parámetros de posición de la cámara: objetivo, rumbo, inclinación y zoom.GMSCameraUpdate
te permite cambiar el objetivo, el rumbo, la inclinación y el zoom, y también contiene métodos de conveniencia adicionales para admitir el desplazamiento, el zoom avanzado, el centrado de la cámara dentro de límites predefinidos y mucho más.
Cuando mueves la cámara, puedes elegir "ajustar" la cámara a la nueva posición, lo que significa que no hay animación, o bien animar el movimiento. Por ejemplo, si animas un cambio en la ubicación objetivo de la cámara, la animación se desplaza de la ubicación anterior a la nueva.
En la animación se interpolan los atributos actuales y los nuevos de la cámara. Puedes controlar la duración de la animación con Core Animation.
Usa GMSCameraPosition
Para cambiar la cámara con GMSCameraPosition
, creas un objeto nuevo o copias uno existente y, luego, lo configuras en el objeto GMSMapView
. Usa el objeto GMSCameraPosition
para mover rápidamente la cámara hasta la nueva ubicación con o sin animación.
Usa un objeto GMSCameraPosition
para configurar cualquier propiedad de la cámara, como la latitud, la longitud, el zoom, el rumbo y el ángulo de visión. Luego, usa ese objeto para establecer la propiedad camera
de GMSMapView
.
Swift
let fancy = GMSCameraPosition( latitude: -33, longitude: 151, zoom: 6, bearing: 270, viewingAngle: 45 ) mapView.camera = fancy
Objective-C
GMSCameraPosition *fancy = [GMSCameraPosition cameraWithLatitude:-33.8683 longitude:151.2086 zoom:6 bearing:30 viewingAngle:45]; [mapView setCamera:fancy];
Omite cualquier propiedad GMSCameraPosition
que quieras establecer en su valor predeterminado.
Para animar el movimiento, usa el método animateToCameraPosition:
en lugar de configurar la propiedad camera
.
Usa GMSCameraUpdate
GMSCameraUpdate
te permite actualizar la posición de la cámara y elegir si quieres ajustarla o animarla a esa posición nueva. La ventaja de GMSCameraUpdate
es la comodidad. Puedes usar GMSCameraPosition
para realizar las mismas tareas que GMSCameraUpdate
, pero GMSCameraUpdate
proporciona métodos auxiliares adicionales para facilitar la manipulación de la cámara.
Por ejemplo, para usar GMSCameraPosition
y aumentar el nivel de zoom actual, primero debes determinar el nivel de zoom actual y, luego, crear un objeto GMSCameraPosition
en el que establezcas el zoom en un valor uno mayor que el zoom actual.
Como alternativa, crea un objeto GMSCameraUpdate
con el método zoomIn:
.
Luego, pasa el objeto GMSCameraUpdate
al método animateWithCameraUpdate:
de GMSMapView
para actualizar la cámara.
Swift
// Zoom in one zoom level let zoomCamera = GMSCameraUpdate.zoomIn() mapView.animate(with: zoomCamera)
Objective-C
// Zoom in one zoom level GMSCameraUpdate *zoomCamera = [GMSCameraUpdate zoomIn]; [mapView animateWithCameraUpdate:zoomCamera];
En su lugar, usa el método moveCamera:
de GMSMapView
para ajustar la cámara a la nueva posición.
En el siguiente ejemplo, usas GMSCameraUpdate
para animar un movimiento de la cámara para centrarla en Vancouver.
Swift
// Center the camera on Vancouver, Canada let vancouver = CLLocationCoordinate2D(latitude: 49.26, longitude: -123.11) let vancouverCam = GMSCameraUpdate.setTarget(vancouver) mapView.animate(with: vancouverCam)
Objective-C
// Center the camera on Vancouver, Canada CLLocationCoordinate2D vancouver = CLLocationCoordinate2DMake(49.26, -123.11); GMSCameraUpdate *vancouverCam = [GMSCameraUpdate setTarget:vancouver]; [mapView animateWithCameraUpdate:vancouverCam];
Cómo construir un objeto GMSCameraUpdate
Construye un objeto GMSCameraUpdate
con uno de sus métodos.
zoomIn:
yzoomOut:
- Modifican el nivel de zoom en un valor de 1.0 y, al mismo tiempo, mantienen todas las demás propiedades como están.
zoomTo:
- Modifica el nivel de zoom al valor indicado y, al mismo tiempo, mantiene todas las demás propiedades como están.
zoomBy:
- Aumenta (o disminuye, si el valor es negativo) el nivel de zoom según el valor indicado.
zoomBy:atPoint:
- Aumenta (o disminuye, si el valor es negativo) el nivel de zoom según el valor determinado y, al mismo tiempo, mantiene la posición del punto especificado en la pantalla.
setTarget:
- Modifica la latitud y longitud de la cámara y, al mismo tiempo, mantiene todas las demás propiedades.
setTarget:zoom:
- Modifica la latitud, la longitud y el zoom de la cámara y, al mismo tiempo, mantiene todas las demás propiedades.
setCamera:
- Establece un
GMSCameraPosition
nuevo. scrollByX:Y:
- Cambia la latitud y longitud de la cámara para mover el mapa según la cantidad de puntos especificada. Un valor de "x" positivo hace que la cámara se desplace hacia la derecha, de modo que el mapa parezca desplazarse hacia la izquierda. Un valor de “Y” positivo hace que la cámara se desplace hacia abajo, de modo que el mapa parezca desplazarse hacia arriba. El desplazamiento se relaciona con el rumbo actual de la cámara. Por ejemplo, si la cámara tiene un rumbo de 90 grados, el este equivale a "arriba".
fitBounds:
- Transforma la cámara para centrar los límites especificados en la pantalla al máximo nivel de zoom posible. Aplica un padding predeterminado de 64 puntos a los límites.
fitBounds:withPadding:
- Transforma la cámara para centrar los límites especificados en la pantalla al máximo nivel de zoom posible. Usa este método para especificar el mismo padding, en puntos, para todos los lados del cuadro de límite.
fitBounds:withEdgeInsets:
- Transforma la cámara para centrar los límites especificados en la pantalla al máximo nivel de zoom posible. Con
UIEdgeInsets
, especificas el padding para cada lado del cuadro de límite de forma independiente.
Usa GMSMapView
para cambiar una sola propiedad
GMSMapView
proporciona varios métodos que te permiten mover la cámara sin usar un objeto GMSCameraPosition
o GMSCameraUpdate
. Con estos métodos, como animateToLocation:
o animateToZoom:
, puedes animar un cambio en una sola propiedad de la cámara.
Por ejemplo, usa el método toViewingAngle:
para animar un cambio en la inclinación de la cámara.
Swift
mapView.animate(toViewingAngle: 45)
Objective-C
[mapView animateToViewingAngle:45];
Cómo establecer un objetivo (ubicación)
La ubicación determina el centro del mapa. Las ubicaciones se especifican mediante latitudes y longitudes, y se representan de manera programática a través de un CLLocationCoordinate2D
, creado con CLLocationCoordinate2DMake
.
Usa GMSCameraPosition
para cambiar la ubicación. En este ejemplo, el mapa se ajusta a la nueva ubicación.
Swift
let target = CLLocationCoordinate2D(latitude: -33.868, longitude: 151.208) mapView.camera = GMSCameraPosition(target: target, zoom: 6)
Objective-C
CLLocationCoordinate2D target = CLLocationCoordinate2DMake(-33.868, 151.208); mapView.camera = [GMSCameraPosition cameraWithTarget:target zoom:6];
Para animar el cambio y desplazar el mapa a la nueva ubicación, puedes usar el método animateToCameraPosition:
en lugar de configurar la propiedad camera
. También puedes usar el método animateToLocation:
en GMSMapView
.
Swift
mapView.animate(toLocation: CLLocationCoordinate2D(latitude: -33.868, longitude: 151.208))
Objective-C
[mapView animateToLocation:CLLocationCoordinate2DMake(-33.868, 151.208)];
También puedes crear un objeto GMSCameraUpdate
para mover la cámara. Usa su método integrado, scrollByX:Y:
, para especificar la cantidad de puntos que se usarán para desplazar la cámara en las direcciones X e Y. En este ejemplo, desplazas la cámara 200 puntos hacia la derecha y 100 puntos hacia abajo:
Swift
// Move the camera 200 points to the right, and 100 points downwards let downwards = GMSCameraUpdate.scrollBy(x: 200, y: 100) mapView.animate(with: downwards)
Objective-C
// Move the camera 200 points to the right, and 100 points downwards GMSCameraUpdate *downwards = [GMSCameraUpdate scrollByX:200.0 Y:100.0]; [mapView animateWithCameraUpdate:downwards];
Establece el rumbo (orientación)
El rumbo es la dirección de la brújula, medida en grados a partir del norte verdadero, para el borde superior del mapa. Por ejemplo, un rumbo de 90 grados da como resultado un mapa en el que el borde superior apunta al este.
Configura el rumbo de manera programática con GMSCameraPosition
o GMSCameraUpdate
, o con el método animateToBearing:
de GMSMapView
.
Swift
mapView.animate(toBearing: 0)
Objective-C
[mapView animateToBearing:0];
Cómo configurar la inclinación (ángulo de visión)
El ángulo de visión es la posición de la cámara en un arco entre la posición central del mapa y la superficie de la Tierra, medida en grados a partir del nadir (la dirección que apunta justo debajo de la cámara). Cuando cambias el ángulo de visión, el mapa aparece en perspectiva, los elementos que se hallan entre la posición del mapa y la cámara tienen un tamaño proporcionalmente mayor, y los elementos que se hallan más allá de la posición del mapa tienen un tamaño proporcionalmente menor. Esto genera un efecto tridimensional.
El ángulo de visión puede variar entre 0 (orientación directamente hacia abajo en el mapa) y un valor máximo que depende del nivel de zoom. Para un nivel de zoom de 16 o superior, el ángulo máximo es de 65 grados. Para un nivel de zoom de 10 o inferior, el ángulo máximo es de 30 grados.
Configura el ángulo de visión de manera programática con GMSCameraPosition
o GMSCameraUpdate
, o con el método animateToViewingAngle:
de GMSMapView
.
Swift
mapView.animate(toViewingAngle: 45)
Objective-C
[mapView animateToViewingAngle:45];
Cómo establecer el zoom
El nivel de zoom de la cámara determina la escala del mapa. A mayores niveles de zoom, puedes ver más detalles en la pantalla, mientras que a menores niveles de zoom puedes ver más del mundo.
Configura el zoom de manera programática con GMSCameraPosition
o GMSCameraUpdate
o con el método animateToZoom:
de GMSMapView
.
Swift
mapView.animate(toZoom: 12)
Objective-C
[mapView animateToZoom:12];
En el siguiente ejemplo, se usa el método zoomIn:
para construir un objeto GMSCameraUpdate
con el objetivo de animar un zoom de un nivel desde el nivel actual.
Swift
// Zoom in one zoom level let zoomCamera = GMSCameraUpdate.zoomIn() mapView.animate(with: zoomCamera)
Objective-C
// Zoom in one zoom level GMSCameraUpdate *zoomCamera = [GMSCameraUpdate zoomIn]; [mapView animateWithCameraUpdate:zoomCamera];
Establece límites
Para mover la cámara de modo que sea visible un área de interés completa con el mayor nivel de zoom posible, establece límites para la vista de la cámara. Por ejemplo, si quieres mostrar todas las gasolineras a ocho kilómetros alrededor de la posición actual del usuario, mueve la cámara para que se vean todas en la pantalla:
- Calcula el
GMSCoordinateBounds
que deseas que se vea en la pantalla. - Usa el método
cameraForBounds:insets:
deGMSMapView
para mostrar un nuevoGMSCameraPosition
.
Configurar estos límites garantiza que el GMSCoordinateBounds
determinado quepa por completo dentro del tamaño del mapa actual. Ten en cuenta que este método establece la inclinación y el rumbo del mapa en 0.
En el siguiente ejemplo, se muestra cómo cambiar la cámara para que las ciudades de Vancouver y Calgary aparezcan en la misma vista.
Swift
let vancouver = CLLocationCoordinate2D(latitude: 49.26, longitude: -123.11) let calgary = CLLocationCoordinate2D(latitude: 51.05,longitude: -114.05) let bounds = GMSCoordinateBounds(coordinate: vancouver, coordinate: calgary) let camera = mapView.camera(for: bounds, insets: UIEdgeInsets())! mapView.camera = camera
Objective-C
CLLocationCoordinate2D vancouver = CLLocationCoordinate2DMake(49.26, -123.11); CLLocationCoordinate2D calgary = CLLocationCoordinate2DMake(51.05, -114.05); GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithCoordinate:vancouver coordinate:calgary]; GMSCameraPosition *camera = [mapView cameraForBounds:bounds insets:UIEdgeInsetsZero]; mapView.camera = camera;
Cómo restringir el desplazamiento lateral del usuario en un área determinada
En estas situaciones, se establecen los límites del mapa, pero el usuario puede desplazarse vertical o lateralmente por fuera de estos límites. Como alternativa, puedes restringir los límites centrales de coordenadas del punto focal del mapa (objetivo de la cámara) para que los usuarios solo puedan desplazarse y obtener una vista panorámica dentro de estos límites.
Por ejemplo, en una app de venta minorista para un centro comercial o un aeropuerto, podrías restringir el mapa a límites específicos, de modo que los usuarios puedan desplazarse vertical y lateralmente dentro de dichos límites.
Para restringir el desplazamiento panorámico a límites específicos, establece la propiedad cameraTargetBounds
de GMSMapView
en un objeto GMSCoordinateBounds
que defina los límites requeridos.
Para quitar la restricción más adelante, establece cameraTargetBounds
en nulo.
Swift
mapView.cameraTargetBounds = bounds
Objective-C
mapView.cameraTargetBounds = bounds;
En el siguiente diagrama, se ilustra una situación en la cual el objetivo de la cámara está restringido a un área ligeramente más grande que el viewport. El usuario puede desplazarse vertical o lateralmente, siempre que el objetivo de la cámara permanezca dentro del área limitada. La cruz representa el objetivo de la cámara:
El mapa siempre ocupa por completo el viewport, incluso aunque se terminen mostrando áreas que se encuentren fuera de los límites definidos. Por ejemplo, si ubicas el objetivo de tu cámara en una esquina del área limitada, el área más allá de la esquina se puede ver en el viewport, pero los usuarios no se pueden desplazar hacia ella. En el siguiente diagrama, se ilustra esta situación. La cruz representa el objetivo de la cámara:
En el siguiente diagrama, el objetivo de la cámara tiene límites muy restringidos, lo cual ofrece al usuario muy pocas oportunidades de desplazamiento vertical o lateral en el mapa. La cruz representa el objetivo de la cámara:
Establece un zoom mínimo o máximo
Las constantes globales kGMSMinZoomLevel
y kGMSMaxZoomLevel
definen los valores de zoom mínimo o máximo. De forma predeterminada, las propiedades minZoom
y maxZoom
de GMSMapView
se establecen en estas constantes.
Para restringir el rango de niveles de zoom disponibles para el mapa, establece un nivel de zoom mínimo y máximo. En el siguiente código, se restringe el nivel de zoom a un rango de 10 a 15.
Swift
let camera = GMSCameraPosition( latitude: 41.887, longitude: -87.622, zoom: 12 ) let mapView = GMSMapView(frame: .zero, camera: camera) mapView.setMinZoom(10, maxZoom: 15)
Objective-C
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:41.887 longitude:-87.622 zoom:12]; GMSMapView *mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera]; [mapView setMinZoom:10 maxZoom:15];
Debes configurar el rango de zoom con el método setMinZoom:maxZoom:
. Sin embargo, puedes leer los valores actuales con las propiedades minZoom
y maxZoom
. Este enfoque es útil cuando se restringe solo uno de los valores. En el siguiente código, solo se cambia el nivel de zoom mínimo.
Swift
mapView.setMinZoom(12, maxZoom: mapView.maxZoom)
Objective-C
[mapView setMinZoom:12 maxZoom:mapView.maxZoom];
Si, tras actualizar el valor mínimo y máximo de zoom, se fija el nivel de zoom de la cámara en un valor fuera del nuevo rango, el zoom actual se actualizará y se mostrará el valor válido más cercano. Por ejemplo, en el siguiente código, el zoom original se define como 4. Cuando el rango de zoom se fija en el rango de 10 a 15, el zoom actual se actualiza a 10.
Swift
// Sets the zoom level to 4. let camera2 = GMSCameraPosition( latitude: 41.887, longitude: -87.622, zoom: 4 ) let mapView2 = GMSMapView(frame: .zero, camera: camera) // The current zoom, 4, is outside of the range. The zoom will change to 10. mapView.setMinZoom(10, maxZoom: 15)
Objective-C
// Sets the zoom level to 4. GMSCameraPosition *camera2 = [GMSCameraPosition cameraWithLatitude:41.887 longitude:-87.622 zoom:4]; GMSMapView *mapView2 = [GMSMapView mapWithFrame:CGRectZero camera:camera]; // The current zoom, 4, is outside of the range. The zoom will change to 10. [mapView setMinZoom:10 maxZoom:15];