Recursos de mapas vetoriais

Selecione a plataforma: Android iOS JavaScript

Amostra

A API Maps JavaScript oferece duas implementações diferentes do mapa: vetorial e de varredura. O mapa rasterizado carrega o mapa como uma grade de blocos de imagem rasterizada baseada em pixels, que são gerados pelo lado do servidor da Plataforma Google Maps e depois veiculados para o app da Web. O mapa vetorial é composto por blocos baseados em vetores, que são renderizados no momento do carregamento no lado do cliente usando o WebGL, uma tecnologia da Web que permite que o navegador acesse a GPU no dispositivo do usuário para renderizar gráficos 2D e 3D.

Esse é o mesmo mapa do Google que os usuários já conhecem e oferece várias vantagens em relação ao mapa de blocos padrão rasterizado, principalmente a nitidez das imagens baseadas em vetores e a adição de construções em 3D em níveis de zoom próximos. O mapa vetorial oferece suporte aos seguintes recursos:

Comece a usar os mapas vetoriais

Inclinação e rotação

Para definir a inclinação e a rotação (direção) no mapa vetorial, inclua as propriedades heading e tilt na inicialização e chame os métodos setTilt e setHeading nele. O exemplo a seguir adiciona alguns botões ao mapa que aparecem de forma programática, ajustando a inclinação e a direção em incrementos de 20 graus.

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: {
        lat: 37.7893719,
        lng: -122.3942,
      },
      zoom: 16,
      heading: 320,
      tilt: 47.5,
      mapId: "90f87356969d889c",
    }
  );

  const buttons: [string, string, number, google.maps.ControlPosition][] = [
    ["Rotate Left", "rotate", 20, google.maps.ControlPosition.LEFT_CENTER],
    ["Rotate Right", "rotate", -20, google.maps.ControlPosition.RIGHT_CENTER],
    ["Tilt Down", "tilt", 20, google.maps.ControlPosition.TOP_CENTER],
    ["Tilt Up", "tilt", -20, google.maps.ControlPosition.BOTTOM_CENTER],
  ];

  buttons.forEach(([text, mode, amount, position]) => {
    const controlDiv = document.createElement("div");
    const controlUI = document.createElement("button");

    controlUI.classList.add("ui-button");
    controlUI.innerText = `${text}`;
    controlUI.addEventListener("click", () => {
      adjustMap(mode, amount);
    });
    controlDiv.appendChild(controlUI);
    map.controls[position].push(controlDiv);
  });

  const adjustMap = function (mode: string, amount: number) {
    switch (mode) {
      case "tilt":
        map.setTilt(map.getTilt()! + amount);
        break;
      case "rotate":
        map.setHeading(map.getHeading()! + amount);
        break;
      default:
        break;
    }
  };
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: {
      lat: 37.7893719,
      lng: -122.3942,
    },
    zoom: 16,
    heading: 320,
    tilt: 47.5,
    mapId: "90f87356969d889c",
  });
  const buttons = [
    ["Rotate Left", "rotate", 20, google.maps.ControlPosition.LEFT_CENTER],
    ["Rotate Right", "rotate", -20, google.maps.ControlPosition.RIGHT_CENTER],
    ["Tilt Down", "tilt", 20, google.maps.ControlPosition.TOP_CENTER],
    ["Tilt Up", "tilt", -20, google.maps.ControlPosition.BOTTOM_CENTER],
  ];

  buttons.forEach(([text, mode, amount, position]) => {
    const controlDiv = document.createElement("div");
    const controlUI = document.createElement("button");

    controlUI.classList.add("ui-button");
    controlUI.innerText = `${text}`;
    controlUI.addEventListener("click", () => {
      adjustMap(mode, amount);
    });
    controlDiv.appendChild(controlUI);
    map.controls[position].push(controlDiv);
  });

  const adjustMap = function (mode, amount) {
    switch (mode) {
      case "tilt":
        map.setTilt(map.getTilt() + amount);
        break;
      case "rotate":
        map.setHeading(map.getHeading() + amount);
        break;
      default:
        break;
    }
  };
}

window.initMap = initMap;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.ui-button {
  background-color: #fff;
  border: 0;
  border-radius: 2px;
  box-shadow: 0 1px 4px -1px rgba(0, 0, 0, 0.3);
  margin: 10px;
  padding: 0 0.5em;
  font: 400 18px Roboto, Arial, sans-serif;
  overflow: hidden;
  height: 40px;
  cursor: pointer;
}
.ui-button:hover {
  background: rgb(235, 235, 235);
}

HTML

<html>
  <head>
    <title>Tilt and Rotation</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map"></div>

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>

Testar amostra

Usar gestos do mouse e do teclado

Se as interações do usuário de inclinação e rotação (cabeçalho) foram ativadas (programaticamente ou no console do Google Cloud), os usuários podem ajustar a inclinação e a rotação usando o mouse e o teclado:

  • Mantenha pressionada a tecla Shift, clique e arraste o mouse para cima e para baixo, se quiser modificar a inclinação, ou para a direita e esquerda, acertando a direção.
  • Mantenha pressionada a tecla Shift do teclado e use as setas para cima e para baixo, se quiser alterar a inclinação, ou para a direita e esquerda, ajustando a direção.

Ajustar a inclinação e a direção de forma programática

Use os métodos setTilt() e setHeading() para ajustar de forma programática a inclinação e a direção em um mapa vetorial. A direção é para onde a câmera está voltada, em graus no sentido horário, a partir do norte. Então, map.setHeading(90) rotaciona o mapa para que o leste esteja voltado para cima. O ângulo de inclinação é medido no zênite. Então, quando map.setTilt(0), o mapa é mostrado de cima para baixo em linha reta, enquanto map.setTilt(45) resulta em uma visualização oblíqua.

  • Chame setTilt() para definir o ângulo de inclinação do mapa. Use getTilt() para saber o valor atual.
  • Chame setHeading() para definir a direção do mapa. Use getHeading() para saber o valor atual.

Ao usar map.setCenter() ou map.panBy(), você muda o centro do mapa, preservando a inclinação e a direção.

O intervalo de ângulos que podem ser usados varia de acordo com o nível de zoom atual. Os valores fora desse intervalo são ajustados.

Você também pode usar o método moveCamera para mudar a direção, a inclinação, o centro e o zoom de forma programática. Saiba mais.

Impacto em outros métodos

Quando inclinação ou rotação são implementadas no mapa, o comportamento de outros métodos da API Maps JavaScript é afetado:

  • map.getBounds() sempre retorna a menor caixa delimitadora que inclui a região visível. Quando você usa a inclinação, os limites retornados podem representar uma região maior do que a área visível da janela de visualização.
  • map.fitBounds() redefine a inclinação e a direção como zero antes de ajustar os limites.
  • map.panToBounds() redefine a inclinação e a direção como zero antes de movimentar os limites.
  • map.setTilt() aceita qualquer valor, mas restringe a inclinação máxima com base no nível de zoom atual do mapa.
  • map.setHeading() aceita qualquer valor e o modifica para se ajustar ao intervalo [0, 360].

Controlar a câmera

Use a função map.moveCamera() para atualizar qualquer combinação de propriedades da câmera de uma só vez. map.moveCamera() aceita um único parâmetro que contém todas as propriedades da câmera a serem atualizadas. O exemplo a seguir mostra a chamada de map.moveCamera() para definir center, zoom, heading e tilt de uma só vez:

map.moveCamera({
  center: new google.maps.LatLng(37.7893719, -122.3942),
  zoom: 16,
  heading: 320,
  tilt: 47.5
});

É possível animar as propriedades da câmera chamando map.moveCamera() com um loop de animação, como mostrado abaixo:

const degreesPerSecond = 3;

function animateCamera(time) {
  // Update the heading, leave everything else as-is.
  map.moveCamera({
    heading: (time / 1000) * degreesPerSecond
  });

  requestAnimationFrame(animateCamera);
}

// Start the animation.
requestAnimationFrame(animateCamera);

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.

Diagrama de propriedades da câmera

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.

Captura de tela de um mapa com uma câmera posicionada em um ângulo de visão de 0 grau, com um nível 18 de zoom.
O mapa exibido com ângulo de visão padrão da câmera.
Diagrama que mostra a posição padrão da câmera, diretamente sobre a posição do mapa, em um ângulo de 0 grau.
O ângulo de visão padrão da câmera.

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.

Captura de tela de um mapa com uma câmera posicionada em um ângulo de visão de 45 graus, com um nível 18 de zoom.
O mapa exibido com um ângulo de visão de 45 graus.
Diagrama que mostra o ângulo de visão da câmera ajustado em 45 graus, com o nível de zoom ainda definido em 18.
Um ângulo de visão de 45 graus.

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.

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
As imagens a seguir mostram a aparência dos diferentes níveis de zoom:
Captura de tela de um mapa com nível 5 de zoom
Um mapa no nível de zoom 5.
Captura de tela de um mapa com nível 15 de zoom
Um mapa no nível de zoom 15.
Captura de tela de um mapa com nível 20 de zoom
Um mapa no nível de zoom 20.

Zoom fracionário

Os mapas vetoriais são compatíveis com zoom fracionário, o que permite aplicar zoom usando valores fracionários, em vez de números inteiros. Embora os mapas vetorial e raterizado sejam compatíveis com o zoom fracionário, ele é ativado por padrão para mapas vetoriais e desativado por padrão para mapas rasterizados. Use a opção de mapa isFractionalZoomEnabled para ativar e desativar o zoom fracionário.

O exemplo a seguir mostra a ativação do zoom fracionário ao inicializar o mapa:

map = new google.maps.Map(document.getElementById('map'), {
  center: {lat: -34.397, lng: 150.644},
  zoom: 8,
  isFractionalZoomEnabled: true
});

Também é possível ativar e desativar o zoom fracionário definindo a opção de mapa isFractionalZoomEnabled como mostrado aqui:

// Using map.set
map.set('isFractionalZoomEnabled', true);

// Using map.setOptions
map.setOptions({isFractionalZoomEnabled: true});

Você pode definir um listener para detectar se o zoom fracionário está ativado. Isso será mais útil se você não tiver definido explicitamente isFractionalZoomEnabled como true ou false. O código de exemplo a seguir verifica se o zoom fracionário está ativado:

map.addListener('isfractionalzoomenabled_changed', () => {
  const isFractionalZoomEnabled = map.get('isFractionalZoomEnabled');
  if (isFractionalZoomEnabled === false) {
    console.log('not using fractional zoom');
  } else if (isFractionalZoomEnabled === true) {
    console.log('using fractional zoom');
  } else {
    console.log('map not done initializing yet');
  }
});