Prácticas recomendadas para 3D Maps

En esta guía, se proporciona una descripción detallada de los componentes web de Mapas en 3D y las consideraciones que se deben tener en cuenta al realizar la integración con tu aplicación.

Ejemplo de caso de uso para la búsqueda de lugares y la búsqueda de rutas.
Ejemplo de búsqueda de lugares y búsqueda de rutas.

Consideraciones de rendimiento

Para garantizar una experiencia fluida y responsiva en cuanto a la interactividad y los elementos visuales, considera los siguientes enfoques.

Carga el mapa

La configuración inicial de carga y procesamiento de los mapas en 3D combina técnicas de configuración del navegador y prácticas recomendadas de la IU para brindar una experiencia del usuario óptima.

  • Carga de la API: Usa la carga dinámica asíncrona de Mapas en 3D para cargar la API de Maps JavaScript en la carga inicial de la página.
  • Bibliotecas: Carga bibliotecas de forma programática cuando sea necesario, como google.maps.importLibrary("maps3d"). Como alternativa, si usas componentes web como <gmp-map-3d> directamente en tu página HTML con carga de secuencia de comandos directa, las bibliotecas se cargarán automáticamente en el momento adecuado.
  • Administra las funciones del mapa base: Usa un mapId personalizado para filtrar los POI del mapa base (modo HÍBRIDO) y controlar su densidad, en especial si la aplicación tiene su propio conjunto de elementos personalizados, como marcadores o polilíneas. Esto evita el desorden visual y la posible superposición. También puedes inhabilitar las funciones de los mosaicos vectoriales del mapa base, como los PDI, las polilíneas de rutas, los nombres de rutas y los nombres de calles (modo SATÉLITE).
  • Eventos: Detecta los eventos gmp-steadystate o gmp-error para compilar tu lógica posterior, como cargar marcadores y animar la cámara.
Secuencia de carga del mapa
Lienzo de fondo > Tiles minimizados > Malla de terreno > Malla de superficie (p.ej., edificios) > Etiquetas de lugares de interés y rutas, elementos personalizados que se cargan en paralelo (marcadores, modelos 3D, etc.)
  • Interacción del usuario: Espera el evento gmp-steadystate antes de realizar cambios en el contenido del mapa. Si un usuario comienza a interactuar (desplazamiento lateral, zoom) con el mapa antes del evento inicial gmp-steadystate, el evento solo se activará después de que el usuario deje de interactuar. Evita mostrar o actualizar contenido superpuesto (como marcadores o polígonos) mientras el usuario desplaza o acerca el mapa. Para ello, escucha los eventos gmp-centerchange, gmp-headingchange, gmp-rangechange, gmp-rollchange y gmp-tiltchange.

  • Usa requestAnimationFrame() (rAF) para las actualizaciones continuas y separa estrictamente los cálculos intensivos de las llamadas de dibujo.

    • Usa rAF: Sincroniza las actualizaciones con la frecuencia de visualización del navegador para lograr una animación fluida de 60 FPS y reducir el consumo de energía.
    • Evita el trabajo de dibujo intensivo: No realices tareas pesadas que no sean de dibujo durante la actualización final.
    • Lógica separada: Realiza toda la lógica intensiva antes de las llamadas de actualización de componentes web mínimos dentro del bucle de rAF.
  • Configuración inicial de la escena: <gmp-map-3d> La configuración de la cámara, como la inclinación, afectará la velocidad de carga. Cuanto más se acerque o incline la escena, más polígonos detallados se mostrarán y requerirán carga. El nivel de detalle también dependerá de la ubicación (p.ej., una ciudad con muchos edificios en comparación con un campo con solo elementos naturales).

    • Se prefieren las vistas con menos acercamiento (altitud alta) y con poca o ninguna inclinación.
    • Agrega límites (ejemplo) al mapa para que los usuarios se concentren en un área en particular y los mosaicos se puedan cargar por completo.
  • Visualización previa: Si bien <gmp-map-3d> se carga muy rápido, es posible que tarde un poco en mostrarse en resolución completa para los usuarios con dispositivos de gama baja (GPU baja) o ancho de banda (4G lento). En este caso, puedes crear un precargador con una imagen, una animación o un texto con la carga de la escena 3D en segundo plano. Consulta el evento clave que se debe usar a continuación:

Ejemplo de precargador
Ejemplo de precargador
// create the map in the background and wait for gmp-steadystate event
async function initMap() {
    await google.maps.importLibrary("maps3d");
    const map = document.querySelector('gmp-map-3d');
    const div = document.querySelector('div'); // preloader "
    map.addEventListener('gmp-steadystate', ({isSteady}) => {
        if (isSteady) {
            div.style.display = 'none';
        }
    });
}
initMap();
  • Mapa 2D:
    • A estos usuarios se les puede mostrar un mapa alternativo en 2D (SATELLITE) que incluya tus datos geográficos, como los marcadores.
Ejemplo de mapa satelital
  • Como alternativa, se puede mostrar un mapa estático complementario en 2D en modo SATÉLITE para que los usuarios visualicen un lugar determinado mientras se carga.

Administración y rendimiento de los elementos visuales

Los mapas en 3D ofrecen varias formas de mostrar elementos visuales, como marcadores, polilíneas, polígonos y modelos en 3D, con un rendimiento óptimo y un tiempo de renderización mínimo, incluso para elementos visuales de mayor volumen.

Marcadores

Ejemplo de carga de marcadores
Ejemplo de situación: De 150 a 300 ms para cargar 300 marcadores con 41 glifos de marcadores SVG diferentes (laptop moderna: macOS M3 Pro, Chrome)
  • Elección de personalización óptima:
    • PinElement: Para cambios básicos en el marcador (color, escala, borde, glifo de texto), usa el elemento <gmp-pin> o la clase PinElement. Este es el método de personalización con el mejor rendimiento.
    • Usa marcadores HTMLImageElement o SVGElement con moderación: Úsalos para una mayor personalización, como agregar transparencia o insertar una imagen, como un ícono, en un SVGElement (requiere codificación en base64). Se rasterizarán durante la carga y generarán una sobrecarga de rendimiento. HTMLImageElement y SVGElement deben estar envueltos en el elemento <template> antes de asignarse a la ranura predeterminada de Marker3DElement.
    • Por el momento, no se puede agregar HTML o CSS sin formato.
  • Administra el comportamiento de colisión: Aprovecha la propiedad collisionBehavior del marcador. Para los marcadores críticos que siempre deben estar visibles, configura el comportamiento según corresponda. En el caso de los marcadores menos importantes, permite que se oculten para mantener una experiencia de mapa más limpia y menos desordenada, especialmente en niveles de zoom altos.
  • Solo POIs críticos: Solo usa drawsWhenOccluded (o configura la propiedad de forma programática) para los marcadores que deben verse a través de edificios o terrenos (p.ej., un objetivo de rescate, una línea de servicios subterránea o el avatar de un usuario).
  • Prueba de oclusión: Dado que el mapa es en 3D, los marcadores pueden quedar visualmente ocultos (ocluidos) por edificios o el terreno. Prueba diferentes ángulos de cámara y altitudes de marcadores para garantizar que los PDI importantes sigan siendo visibles, o bien implementa una lógica para ajustar la visibilidad y la altitud cuando estén obstruidos.
  • Aprovecha la altitud: En los mapas en 3D, los marcadores deben usar la posición con un valor de altitud. En el caso de los marcadores asociados al terreno o a los edificios, usa altitudeMode: "RELATIVE_TO_GROUND", "RELATIVE_TO_MESH" o parámetros de configuración similares para garantizar que el marcador se fije correctamente cuando se incline o rote el mapa.

Polígonos y polilíneas

Ejemplo de carga de polígonos
Ejemplo de situación: De 100 a 150 ms para cargar 1,000 polígonos (laptop moderna: macOS M3 Pro, Chrome)
  • Simplify Geometry: Antes de la renderización, aplica un algoritmo de simplificación a los datos de tu ruta. Esto reduce la cantidad de vértices y conserva la forma general, lo que mejora drásticamente la velocidad de renderización, en especial para los límites o las rutas complejos.
  • Diezmado por nivel de zoom: Para los conjuntos de datos muy grandes, considera cargar la geometría con mayor detalle solo cuando el usuario acerque el área. Con un nivel de zoom bajo, solo se necesita una versión muy simplificada de la polilínea o el polígono.
  • Pre-calculate for Extruded Polygons: Si tus polígonos son extruidos (extruded: true), los datos de la ruta definen un volumen 3D (una malla). El procesamiento de polígonos complejos con una gran cantidad de vértices es costoso en términos de procesamiento. Asegúrate de que los datos de origen de tus polígonos sean lo más simples posible.
  • Prueba el rendimiento de las polilíneas y los polígonos: Cuando agregues polilíneas o polígonos complejos o numerosos, especialmente cuando se extruyan para 3D, asegúrate de que no provoquen caídas en la velocidad de fotogramas. Limita la cantidad de vértices o usa algoritmos de simplificación si es necesario.
  • Cuando actualices una forma, modifica todo el array de la ruta de acceso en una sola operación en lugar de iterar y modificar elementos individuales. Una sola operación de asignación (p.ej., polyline.path = newPathArray;) es mucho más eficiente que varias actualizaciones iterativas.
  • Evita las polilíneas extruidas (si es posible): Si bien las polilíneas pueden usar un valor de altitud para colocarse en el espacio 3D, la extrusión de una polilínea (p.ej., darle un ancho de trazo y un gran intervalo de altitud) puede ser gráficamente intensiva. Siempre que sea posible, usa polilíneas 2D en el suelo (RELATIVE_TO_GROUND) o un ancho de trazo mínimo para obtener un mejor rendimiento.
  • Solo usa drawsOccludedSegments para los elementos de ruta críticos. En el caso de las formas contextuales o de fondo, permite que la geometría 3D del mapa las oculte de forma natural. Mostrar geometría oculta no crítica agrega complejidad innecesaria a la renderización.

Modelos 3D

La renderización y la interactividad de los modelos 3D en formato .glb, como el evento gmp-click, son muy rápidas en <gmp-map-3d>.

Ejemplo de carga de modelo 3D
Ejemplo de situación: Se tarda alrededor de 2 segundos en mostrar 1,000 instancias de un modelo 3D ligero (200 KB) que se mueve a lo largo de una ruta. (laptop moderna: macOS M3 Pro, Chrome)
  • Minimiza el tamaño del archivo con la compresión: Para garantizar una carga rápida, especialmente en redes móviles, mantén los archivos de modelos .glb complejos por debajo de los 5 MB (idealmente, menos). El método principal para lograr esto es aplicar la compresión Draco a los datos de la malla dentro de tus archivos .glb, lo que puede reducir significativamente el tamaño del archivo (a menudo en más del 50%) con una pérdida mínima de calidad visual.
  • Centra el origen del modelo: Asegúrate de que el software de modelado 3D exporte el modelo con su origen (punto 0, 0, 0) centrado en la base del modelo. Esto simplifica el posicionamiento y la rotación en el mapa, lo que garantiza que el modelo se fije correctamente en las coordenadas de latitud y longitud.
  • Administra el CORS: Si los archivos de tu modelo están alojados en un dominio o CDN diferente al de tu aplicación web, debes configurar el servidor de alojamiento para que incluya los encabezados necesarios de uso compartido de recursos multiorigen (CORS) (p.ej., Access-Control-Allow-Origin: *). De lo contrario, el mapa no podrá cargar el modelo.