Funciones de mapas de vectores

Selecciona la plataforma: Android iOS JavaScript

Ver muestra

La API de Maps JavaScript ofrece dos implementaciones del mapa diferentes: de trama y de vectores. El mapa de trama carga el mapa como una cuadrícula de mosaicos de imágenes de trama basados en píxeles, que Google Maps Platform genera del servidor y, luego, entrega a tu app web. El mapa de vectores está compuesto por mosaicos basados en vectores, que se dibujan en el tiempo de carga del cliente con WebGL, una tecnología web que permite que el navegador acceda a la GPU del dispositivo del usuario para renderizar gráficos 2D y 3D.

El mapa de vectores es el mismo mapa de Google Maps que conocen los usuarios y ofrece una serie de ventajas en comparación con el mapa de mosaicos de trama predeterminado, particularmente, en cuanto a la nitidez de las imágenes basadas en vectores y la incorporación de edificios 3D a niveles de zoom cercanos. El mapa de vectores admite las siguientes funciones:

Comenzar a usar mapas de vectores

Inclinación y rotación

Para configurar la inclinación y la rotación (orientación) en el mapa de vectores, incluye las propiedades heading y tilt cuando inicialices el mapa y llama a los métodos setTilt y setHeading en el mapa. En el siguiente ejemplo, se agregan algunos botones al mapa que muestran cómo ajustar la inclinación y la orientación de forma programática en incrementos de 20 grados.

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>

Prueba la muestra

Cómo usar gestos del mouse y del teclado

Si se habilitaron las interacciones de los usuarios con la inclinación y la rotación (heading) (ya sea de forma programática o en la consola de Google Cloud), los usuarios pueden ajustar la inclinación y la rotación con el mouse y el teclado:

  • Con el mouse, mantén presionada la tecla Mayúsculas y, luego, haz clic y arrastra el mouse hacia arriba y hacia abajo para ajustar la inclinación, y hacia la derecha y la izquierda para ajustar la orientación.
  • Con el teclado, mantén presionada la tecla Mayúsculas y, luego, usa las teclas de flecha hacia arriba y hacia abajo para ajustar la inclinación, y las teclas de flecha hacia la izquierda y la derecha para ajustar la orientación.

Cómo ajustar la inclinación y la orientación de forma programática

Usa los métodos setTilt() y setHeading() para ajustar la inclinación y la orientación de manera programática en un mapa de vectores. La orientación es la dirección hacia la que apunta la cámara, especificada en grados en el sentido de las manecillas del reloj, comenzando por el norte, por lo que map.setHeading(90) rotará el mapa para que el este quede hacia arriba. El ángulo de inclinación se mide desde el cenit, por lo que map.setTilt(0) apunta hacia abajo, mientras que map.setTilt(45) generará una vista oblicua.

  • Llama a setTilt() para establecer el ángulo de inclinación del mapa. Usa getTilt() para obtener el valor de inclinación actual.
  • Llama a setHeading() para establecer la orientación del mapa. Usa getHeading() para obtener el valor de orientación actual.

Para cambiar el centro del mapa y, a la vez, mantener la inclinación y la orientación, usa map.setCenter() o map.panBy().

Ten en cuenta que el rango de ángulos que se pueden usar varía según el nivel de zoom. Los valores fuera de este rango se restringirán al rango permitido actualmente.

También puedes usar el método moveCamera para cambiar de manera programática la orientación, la inclinación, el centro y el zoom. Obtén más información.

Impacto en otros métodos

Cuando se aplica una inclinación o rotación en el mapa, el comportamiento de otros métodos de la API de Maps JavaScript se ve afectado:

  • map.getBounds() siempre muestra el cuadro delimitador más pequeño que incluye la región visible. Cuando se aplica una inclinación, los límites mostrados pueden representar una región más grande que la región visible del viewport del mapa.
  • map.fitBounds() restablecerá la inclinación y la orientación a cero antes de ajustar los límites.
  • map.panToBounds() restablecerá la inclinación y la orientación a cero antes de desplazar lateralmente los límites.
  • map.setTilt() acepta cualquier valor, pero restringe la inclinación máxima según el nivel de zoom del mapa actual.
  • map.setHeading() acepta cualquier valor y lo modifica para que se ajuste al rango [0, 360].

Cómo controlar la cámara

Usa la función map.moveCamera() para actualizar cualquier combinación de propiedades de la cámara a la vez. map.moveCamera() acepta un solo parámetro con todas las propiedades de la cámara que se actualizarán. En el siguiente ejemplo, se muestra cómo llamar a map.moveCamera() para configurar center, zoom, heading y tilt a la vez:

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

Para animar propiedades de la cámara, llama a map.moveCamera() con un bucle de animación, como se muestra a continuación:

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);

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.

Diagrama de propiedades de la cámara

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.

Captura de pantalla de un mapa con una cámara ubicada a un ángulo de visión de 0 grados, con un nivel de zoom de 18
El mapa con el ángulo de visión predeterminado de la cámara
Diagrama en el que se muestra la posición predeterminada de la cámara, directamente sobre la posición del mapa, en un ángulo de 0 grados
El ángulo de visión predeterminado de la cámara

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.

Captura de pantalla de un mapa con una cámara ubicada a un ángulo de visión de 45 grados, con un nivel de zoom de 18
El mapa se muestra con un ángulo de visión de 45 grados
Diagrama en el que se muestra el ángulo de visión de la cámara establecido en 45 grados, con el nivel de zoom aún establecido en 18
Un ángulo de visión de la cámara de 45 grados

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.

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
En las siguientes imágenes, se muestra el aspecto visual de diferentes niveles de zoom:
Captura de pantalla de un mapa con un nivel de zoom 5
Mapa con un nivel de zoom 5
Captura de pantalla de un mapa con un nivel de zoom 15
Mapa con un nivel de zoom 15
Captura de pantalla de un mapa con un nivel de zoom 20
Mapa con un nivel de zoom 20

Zoom fraccionario

Los mapas de vectores admiten el zoom fraccionario, que te permite hacer zoom con valores fraccionarios en lugar de números enteros. Si bien tanto los mapas de tramas como los de vectores admiten el zoom fraccionario, esta opción está activada de forma predeterminada para los mapas de vectores y desactivada de forma predeterminada para los mapas de trama. Usa la opción de mapa isFractionalZoomEnabled para activar y desactivar el zoom fraccionario.

En el siguiente ejemplo, se muestra cómo habilitar el zoom fraccionario al inicializar el mapa:

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

También puedes activar y desactivar el zoom fraccionario si configuras la opción de mapa isFractionalZoomEnabled como se muestra a continuación:

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

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

Puedes configurar un objeto de escucha para que detecte si el zoom fraccionario está activado. Esto resulta muy útil si no configuraste isFractionalZoomEnabled explícitamente como true o false. El siguiente código de ejemplo verifica si está habilitado el zoom fraccionario:

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');
  }
});