Com o SDK do Maps para iOS, é possível mudar o ponto de vista do usuário do mapa alterando a câmera do mapa.
Com o SDK do Maps para iOS, os usuários podem inclinar e girar os mapas para ajustar a uma orientação útil para o contexto. Em qualquer nível de zoom, os usuários podem mover o mapa ou mudar a perspectiva com pouquíssima latência.
As mudanças na câmera não alteram marcadores, polilinhas ou outros elementos gráficos que você adicionou, mas você pode mudar essas adições para que se adequem melhor à nova visualização.
A visualização do mapa
O SDK do Maps para iOS usa a projeção de Mercator para representar a superfície do mundo (uma esfera) na tela do dispositivo (uma superfície plana).
A posição da câmera
A visualização de mapa é modelada como uma câmera apontada para um plano nivelado. A posição da câmera, e, consequentemente, a renderização do mapa, é especificada pelas seguintes propriedades: alvo (localização de latitude/longitude), rolamento, inclinação e zoom.
Alvo (local)
O alvo da câmera é o local do centro do mapa, especificado como coordenadas de latitude e longitude.
A latitude pode variar entre -85 e 85 graus, inclusive. Valores acima ou abaixo desse intervalo são fixados para o valor mais próximo dentro desse intervalo. Por exemplo, uma latitude especificada como 100 terá o valor de 85. A longitude varia entre -180 e 180 graus. Valores acima ou abaixo desse intervalo são alterados para se adequarem ao intervalo (-180, 180). Por exemplo, 480, 840 e 1200 serão alterados para 120 graus.Rolamento (orientação)
O rolamento da câmera especifica a direção da bússola, medida em graus a partir do norte verdadeiro, correspondendo à borda superior do mapa. Se você desenhar uma linha vertical do centro do mapa para a borda superior, o rolamento corresponde à direção da câmera (medida em graus) em relação ao Norte verdadeiro.
Um rolamento de 0 significa que a parte superior do mapa aponta para o Norte verdadeiro. O valor de 90 graus significa que a parte superior do mapa aponta para o Leste (90 graus em uma bússola). Um valor de 180 significa que a parte superior do mapa aponta para o Sul.
Com a API Maps você pode alterar o rolamento de um mapa. Ao dirigir um carro, muitas vezes giramos um mapa de estradas para alinhá-lo com a direção da viagem, enquanto ao fazer uma trilha usando um mapa e uma bússola, geralmente orientamos o mapa para que a linha vertical aponte para o Norte.
Inclinação (ângulo de visão)
A inclinação define a posição da câmera em um arco diretamente sobre a posição central do mapa, medida em graus a partir do nadir (a direção que aponta diretamente abaixo da câmera). Um valor de 0 corresponde a uma câmera apontada para baixo. Valores maiores que 0 correspondem a uma câmera inclinada para o horizonte pelo número especificado de graus. Quando você muda o ângulo de visão, o mapa é apresentado em perspectiva, com elementos distantes aparecendo menores, e elementos próximos aparecendo maiores. Isso é ilustrado abaixo.
Nas imagens a seguir, o ângulo de visão é 0 grau. A primeira imagem mostra um esquema da situação. A posição 1 é a posição da câmera, e a posição 2 é a posição atual do mapa. O mapa resultante está abaixo.
Nas imagens abaixo, o ângulo de visão é de 45 graus. A câmera se move no meio do caminho ao longo de um arco, entre diretamente para cima (0 grau) e o solo (90 graus), para a posição 3. A câmera ainda está direcionada para o ponto central do mapa, mas agora a área representada pela linha na posição 4 está visível.
O mapa nesta captura de tela ainda está centralizado sobre o mesmo ponto do mapa original. No entanto, mais elementos apareceram na parte superior. À medida que você ultrapassa o ângulo de 45 graus, os elementos entre a câmera e a posição do mapa aparecem proporcionalmente maiores, enquanto os elementos que estão além da posição do mapa aparecem proporcionalmente menores, produzindo um efeito tridimensional.
Zoom
O nível de zoom da câmera determina a escala do mapa. Em níveis mais elevados de zoom, é possível ver mais detalhes na tela, enquanto em níveis de zoom menores, uma parte maior do mundo pode ser vista. No nível de zoom 0, a escala do mapa faz com que todo o mundo tenha uma largura de aproximadamente 256 pontos.
Um aumento de zoom de 1 dobra a largura do mundo na tela. Assim, com o nível de zoom em N, a largura do mundo é aproximadamente 256 x 2N pontos. Por exemplo, no nível de zoom 2, o mundo todo tem aproximadamente 1.024 pontos de largura.
O nível de zoom não precisa ser um número inteiro. A variação permitida pelo mapa depende de diversos fatores, incluindo destino, tipo de mapa e tamanho da tela. Qualquer número fora do intervalo será convertido para o valor válido mais próximo, que pode ser o nível de zoom mínimo ou máximo. A lista a seguir mostra o nível aproximado de detalhamento que você consegue ver em cada nível de zoom:
- 1: mundo
- 5: terra/continente
- 10: cidade
- 15: ruas
- 20: construções
Definir a posição inicial da câmera
Defina a posição inicial da câmera usando o objeto
GMSCameraPosition
, que permite definir a latitude e a longitude do alvo, além de
rumo, inclinação e zoom.
Para definir a posição inicial da câmera, crie um objeto GMSMapViewOptions
e defina a propriedade camera
como GMSCameraPosition
. Em seguida, transmita suas
opções para o
construtor de conveniência
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];
Também é possível criar o objeto GMSMapView
usando o método de inicialização
UIView
padrão. Nesse caso, a posição da câmera começa no local padrão e você
pode mudar isso após a criação.
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];
Mudar a posição da câmera
É possível mudar a posição da câmera de forma programática para definir a localização,
a direção, a inclinação e o zoom. Embora GMSMapView
ofereça vários métodos que
podem ser usados para mudar a posição da câmera, normalmente você usa GMSCameraPosition
ou
GMSCameraUpdate
:
GMSCameraPosition
contém propriedades e métodos que você usa para mudar todos os parâmetros de posição da câmera: destino, rumo, inclinação e zoom.GMSCameraUpdate
permite mudar o alvo, o rumo, a inclinação e o zoom e também contém outros métodos de conveniência para oferecer suporte à rolagem, zoom avançado, centralização da câmera em limites predefinidos e muito mais.
Ao mover a câmera, você pode escolher "fixar" a câmera na nova posição, o que significa que não há animação, ou animar o movimento. Por exemplo, se você animar uma mudança no local de destino da câmera, a animação vai passar do local anterior para o novo.
A animação alterna entre os atributos atuais da câmera e os novos. É possível controlar a duração da animação usando a Core Animation.
Usar GMSCameraPosition
Para mudar a câmera com
GMSCameraPosition
,
crie um novo objeto ou copie um objeto existente e defina-o no
objeto GMSMapView
. Use o objeto GMSCameraPosition
para fixar a câmera no
novo local com ou sem animação.
Use um objeto GMSCameraPosition
para configurar qualquer propriedade da câmera, como
latitude, longitude, zoom, rumo e ângulo de visualização. Em seguida, use esse objeto
para definir a propriedade 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];
Omita qualquer propriedade GMSCameraPosition
que você queira definir como o valor padrão.
Para animar o movimento, use o método animateToCameraPosition:
em vez de
definir a propriedade camera
.
Usar GMSCameraUpdate
GMSCameraUpdate
permite atualizar a posição da câmera e escolher se o posicionamento nessa nova posição será com ou sem animação. A vantagem de GMSCameraUpdate
é a praticidade. É possível
usar GMSCameraPosition
para realizar as mesmas tarefas que GMSCameraUpdate
, mas
GMSCameraUpdate
oferece métodos auxiliares adicionais para facilitar a
manipulação da câmera.
Por exemplo, para usar GMSCameraPosition
para incrementar o nível de zoom atual,
primeiro determine o nível de zoom atual e, em seguida, crie um
objeto GMSCameraPosition
em que você defina o zoom como um valor maior que
o atual.
Como alternativa, crie um objeto GMSCameraUpdate
com o método zoomIn:
.
Em seguida, atualize a câmera transmitindo o objeto GMSCameraUpdate
para o
método animateWithCameraUpdate:
GMSMapView
.
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];
Use o método moveCamera:
GMSMapView
para fixar a câmera na nova posição.
No próximo exemplo, você vai usar GMSCameraUpdate
para animar um movimento da câmera
para centralizá-la em 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];
Criar um objeto GMSCameraUpdate
Crie um objeto GMSCameraUpdate
usando um dos métodos dele.
zoomIn:
ezoomOut:
- Altere o nível de zoom atual em 1,0, mantendo todas as outras propriedades.
zoomTo:
- Muda o nível de zoom para o valor especificado, mantendo todas as outras propriedades.
zoomBy:
- Aumenta (ou diminui, se o valor é negativo) o nível de zoom pelo valor especificado.
zoomBy:atPoint:
- Aumenta (ou diminui, se o valor é negativo) o nível de zoom pelo valor fornecido, mantendo a posição dos pontos especificados na tela.
setTarget:
- Altera a latitude e a longitude da câmera, preservando todas as outras propriedades.
setTarget:zoom:
- Altera a latitude, a longitude e o zoom da câmera, preservando todas as outras propriedades.
setCamera:
- Define um novo
GMSCameraPosition
. scrollByX:Y:
- Altera a latitude e a longitude da câmera para mover o mapa pelo número especificado de pontos. Um valor x positivo move a câmera para a direita, fazendo com que o mapa pareça ser movido para a esquerda. Um valor y positivo move a câmera para baixo, fazendo com que o mapa pareça ser movido para cima. A rolagem é relativa à direção atual da câmera. Por exemplo, se o rumo da câmera é 90 graus, o ponto de referência será "para cima".
fitBounds:
- Transforma a câmera para centralizar os limites especificados na tela no maior nível de zoom possível. Aplica um preenchimento padrão de 64 pontos aos limites.
fitBounds:withPadding:
- Transforma a câmera para centralizar os limites especificados na tela no maior nível de zoom possível. Use esse método para especificar o mesmo padding, em pontos, para todos os lados da caixa limitadora.
fitBounds:withEdgeInsets:
- Transforma a câmera para centralizar os limites especificados na
tela no maior nível de zoom possível. Com
UIEdgeInsets
, você especifica o padding para cada lado da caixa delimitadora de forma independente.
Use GMSMapView
para mudar uma única propriedade
GMSMapView
oferece vários métodos que permitem mover a câmera sem usar um
objeto GMSCameraPosition
ou GMSCameraUpdate
. Com esses métodos, como
animateToLocation:
ou animateToZoom:
, é possível animar uma mudança em uma
única propriedade da câmera.
Por exemplo, use o método toViewingAngle:
para animar uma mudança no ângulo
da câmera.
Swift
mapView.animate(toViewingAngle: 45)
Objective-C
[mapView animateToViewingAngle:45];
Definir alvo (local)
A localização determina o centro do mapa. As localizações são especificadas por
latitude e longitude e representadas programaticamente por um
CLLocationCoordinate2D
, criado com CLLocationCoordinate2DMake
.
Use GMSCameraPosition
para mudar o local. Neste exemplo, o mapa é fixado no novo local.
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 a mudança e mover o mapa para o novo local, use o método animateToCameraPosition:
em vez de definir a propriedade camera
. Ou
use o método animateToLocation:
em GMSMapView
.
Swift
mapView.animate(toLocation: CLLocationCoordinate2D(latitude: -33.868, longitude: 151.208))
Objective-C
[mapView animateToLocation:CLLocationCoordinate2DMake(-33.868, 151.208)];
Também é possível criar um objeto GMSCameraUpdate
para mover a câmera. Use o
método integrado, scrollByX:Y:
, para especificar o número de pontos para rolar a
câmera nas direções X e Y. Neste exemplo, você rola a câmera 200
pontos para a direita e 100 pontos para baixo:
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];
Definir rumo (orientação)
O rumo é a direção da bússola, medida em graus a partir do norte verdadeiro, para a borda superior do mapa. Por exemplo, um rumo de 90 graus resulta em um mapa em que a borda superior aponta para o leste.
Defina a direção de maneira programática com GMSCameraPosition
ou GMSCameraUpdate
ou com o método animateToBearing:
de GMSMapView
.
Swift
mapView.animate(toBearing: 0)
Objective-C
[mapView animateToBearing:0];
Definir inclinação (ângulo de visualização)
O ângulo de visualização é a posição da câmera em um arco entre a posição diretamente acima do centro do mapa e a superfície da Terra, medida em graus a partir do nadir (a direção que aponta diretamente abaixo da câmera). Quando você muda o ângulo de visualização, o mapa aparece em perspectiva, com os recursos entre a câmera e a posição do mapa aparecendo proporcionalmente maiores, e os recursos além da posição do mapa aparecendo proporcionalmente menores, gerando um efeito tridimensional.
O ângulo de visualização pode variar entre 0 (apontando diretamente para baixo no mapa) e um máximo que depende do nível de zoom. Para o nível de zoom 16 ou mais recente, o ângulo máximo é 65 graus. Para o nível de zoom 10 ou menor, o ângulo máximo é de 30 graus.
Defina o ângulo de visualização de maneira programática usando GMSCameraPosition
ou
GMSCameraUpdate
ou com o método animateToViewingAngle:
de GMSMapView
.
Swift
mapView.animate(toViewingAngle: 45)
Objective-C
[mapView animateToViewingAngle:45];
Definir zoom
O nível de zoom da câmera determina a escala do mapa. Em níveis maiores de zoom, é possível ver mais detalhes na tela, enquanto em níveis de zoom menores, uma parte maior do mundo pode ser vista.
Defina o zoom de maneira programática com GMSCameraPosition
ou GMSCameraUpdate
ou
com o método animateToZoom:
de GMSMapView
.
Swift
mapView.animate(toZoom: 12)
Objective-C
[mapView animateToZoom:12];
O exemplo a seguir usa o método zoomIn:
para criar um objeto GMSCameraUpdate
para animar um zoom em um nível do nível atual.
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];
Definir limites
Para mover a câmera de modo que toda a área de interesse fique visível no maior nível de zoom possível, defina limites para a visualização da câmera. Por exemplo, se você quer mostrar todos os postos de gasolina a cinco quilômetros da posição atual do usuário, mova a câmera para que todos fiquem visíveis na tela:
- Calcule os
GMSCoordinateBounds
que você quer mostrar na tela. - Use o método
cameraForBounds:insets:
deGMSMapView
para retornar um novoGMSCameraPosition
.
A definição desses limites garante que o GMSCoordinateBounds
informado se ajuste totalmente
ao tamanho do mapa atual. Esse método define a inclinação e o rumo do mapa como 0.
O exemplo a seguir demonstra como mudar a câmera para que as cidades de Vancouver e Calgary apareçam na mesma visualização.
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;
Restringir o deslocamento do usuário a uma área específica
Esses cenários definem os limites do mapa, mas o usuário pode rolar ou mover o mapa para fora desses limites. Em vez disso, pode ser útil restringir os limites centrais de coordenadas do ponto focal do mapa (o alvo da câmera) para que os usuários só possam rolar e mover o mapa dentro desses limites.
Por exemplo, um app de varejo de um shopping ou aeroporto pode querer restringir o mapa a limites específicos, permitindo que os usuários rolem e movimentem o mapa dentro desses limites.
Para restringir a movimentação a limites específicos, defina a propriedade cameraTargetBounds
de
GMSMapView
como um objeto GMSCoordinateBounds
que define os limites necessários.
Para remover a restrição mais tarde, defina cameraTargetBounds
como nulo.
Swift
mapView.cameraTargetBounds = bounds
Objective-C
mapView.cameraTargetBounds = bounds;
O diagrama a seguir mostra um cenário em que o alvo da câmera está restrito a uma área ligeiramente maior que a janela de visualização. O usuário pode rolar e deslocar o mapa, desde que o alvo da câmera permaneça dentro da área limitada. A cruz representa o alvo da câmera:
O mapa sempre preenche a janela de visualização, mesmo que o resultado seja a exibição de áreas fora dos limites definidos. Por exemplo, se você posicionar o alvo da câmera no canto da área limitada, a área além do canto ficará visível na janela de visualização, mas os usuários não poderão rolar o mapa para essa área. O diagrama a seguir ilustra esse cenário. A cruz representa o alvo da câmera:
No diagrama a seguir, o alvo da câmera tem limites muito restritos, oferecendo ao usuário pouca oportunidade para rolar ou deslocar o mapa. A cruz representa o alvo da câmera:
Definir um zoom mínimo ou máximo
As constantes globais kGMSMinZoomLevel
e kGMSMaxZoomLevel
definem os valores de zoom mínimo ou máximo. Por padrão, as propriedades minZoom
e maxZoom
do GMSMapView
são definidas como essas constantes.
Para restringir o intervalo de níveis de zoom disponíveis no mapa, defina um nível de zoom mínimo e máximo. O código a seguir restringe o nível de zoom entre 10 e 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];
É necessário definir o intervalo de zoom com o método setMinZoom:maxZoom:
. No entanto, é possível ler os valores atuais usando as propriedades minZoom
e maxZoom
. Essa
abordagem é útil para restringir apenas um dos valores. O código a seguir
muda apenas o nível de zoom mínimo.
Swift
mapView.setMinZoom(12, maxZoom: mapView.maxZoom)
Objective-C
[mapView setMinZoom:12 maxZoom:mapView.maxZoom];
Se, após atualizar o zoom mínimo e máximo, o nível de zoom da câmera for definido como um valor fora do novo intervalo, o zoom atual será atualizado automaticamente para exibir o valor válido mais próximo. Por exemplo, no código abaixo, o zoom original é definido como 4. Quando o intervalo de zoom é definido posteriormente como 10 a 15, o zoom atual é atualizado para 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];