React, Google Maps & Forest Gump

Ivan Díaz
Nowports Tech and Product
5 min readMar 4, 2021

Aunque hoy en día todo se puede resolver con JavaScript, hay tareas que resultan una piedra en el zapato. En empleos anteriores, recuerdo pasar malos ratos con la API de Google Maps.

Aun cuando solo me pedían agregar un marcador en cierta latitud y longitud, busqué cómo llevar la interacción al siguiente nivel. Me inspiré con apps populares como Uber, Rappi o Airbnb. Parece complicado hacer algo así pero hay librerías que te facilitan bastante la tarea.

Desde que supe lo que hacía nowports, me emocionó el participar en la funcionalidad de rastreo en tiempo real y pensé “tengo que estar ahí”. Ya dentro del equipo de tecnología, me motivó bastante participar en el desarrollo de esta característica.

Hace algunos días, liberamos un mapa con historial de rastreo para los embarques, en la plataforma de nowports para clientes. Aprendí bastante sobre la manipulación de mapas y cómo crear interacciones interesantes, esta publicación es para mostrarles mi camino.

Con React, vamos a crear un mapa donde podremos ver el trayecto que corre Forest Gump según su película (y sí, me tome el tiempo de investigar su trayecto 😆). Lo haremos más interesante integrando la funcionalidad de agregar una imagen para cada checkpoint. Para que el ejercicio sea de lo más completo, incluiremos el popular ‘dark mode’ y una animación.

En resumen, agregaremos:

  • Dark mode
  • Marcadores en ciertas ubicaciones
  • Un trazo del trayecto, uniendo los marcadores
  • Información de cada checkpoint (imagen e información)
  • Una animación para la ubicación ‘actual’ de forest gum

Iniciemos, ¡corre Forest!

Primero es necesario crear una aplicación de React con create-app-react

Create React App es una forma compatible oficial de crear aplicaciones single-page con React, que nos ofrece una construcción moderna sin configuración. Para saber más, entra aquí.

Ingresamos estos comandos (tomados de la documentación):

npx create-react-app my-app
cd my-app
npm start

Para la manipulación del mapa, nos vamos a apoyar de una librería llamada google-map-react, que es un componente escrito sobre un pequeño conjunto de la API de Google Maps y te permite “renderizar” cualquier componente de React en el mapa de Google. Puedes ver su documentación aquí.

Vamos a instalarla con el siguiente comando:

npm install --save google-map-react

Componente principal

En este componente llamaremos la librería google-map-react. En la función del render llamaremos al componente GoogleMapReact, este es el Wrapper que va a envolver a todo componente que queramos renderizar en el mapa.

Vamos a revisar detenidamente las props que usaremos:

  • bootstrapURLKeys: Declara la Api key de Google Maps, puedes configurar una desde aquí.
  • center: Las coordenadas que declares aquí son las que tomará Google Maps para determinar el centro del mapa al iniciarlo. Más adelante veremos cómo sacarle provecho con una interacción sencilla pero cool.
  • zoom: Es el nivel de acercamiento con el que iniciará el mapa.
  • options: Recibe un objeto con configuraciones especificas que se aplicarán al mapa. En este caso lo usaremos para agregar los estilos del mapa. Puedes ver más configuraciones en la documentación de google maps.
  • onGoogleApiLoaded: Esta prop es de las más importantes. A través de una función que observa el mapa, cuando este sea cargado pone a disposición las clases map y maps, que tienen todos los métodos de la API. En este caso, vamos a agregarlos al estado del componente, para acceder a ellos desde cualquier función.

🚩 Renderizando los checkpoints

Para trazar el trayecto, construí una estructura de datos simulando la respuesta de una API abajo dejo la URL del archivo. Tendremos un array con los checkpoints por donde ha pasado Forest y otro con los checkpoints que faltan por recorrer. Estas dos rutas se van a unir con la posición actual de forest.
👉 https://github.com/owivans/gump-map/blob/main/src/constants/data.js

Por cada objeto de los Arrays, rendericemos el siguiente componente, que serán los checkpoints. Recordemos que este componente estará envuelto por el wrapper GoogleMapReact.

<GoogleMapReact>
<Marker />
</GoogleMapReact>

Como vemos, no tiene nada de relación con la librería, solo es un componente que mostrará el checkpoint en el mapa y, al darle click, la imagen del checkpoint.

Al lograr que un componente de React se renderice en el mapa, las posibles interacciones son infinitas. En la línea 26 se agrega una clase de css que crea una animación en forma de pulso. No tiene nada complejo, es simple css, esto lo usaremos para indicar la posición actual de Forest.

〰 Agregando Polylines como trayectos

Para las Polylines, vamos a crear un componente funcional. Ya que no dependeremos de un estado, solo necesitamos mostrar mostrar información, lo haremos de la siguiente manera:

¿Recuerdan las clases map y maps qué mencioné?

Aquí suceden dos cosas. Estamos declarando dos Polylines: la primera comienza desde el checkpoint donde inició Forest hasta su ubicación ‘actual’ y la segunda de la ubicación ‘actual’ hacia el checkpoint final.

Para trazar el trayecto vamos a crear una instancia de la clase maps y usaremos el método Polyline , dándole como parámetro un objeto que esta compuesto de keys opcionales, con excepción de path que necesita como valor un array que contiene las coordenadas del origen y final. En la documentación viene más a detalle cada una de las opciones.

¡Bien! ahora solo nos queda llamar nuestro componente <Polylines/> dentro de nuestro componente principal. La estructura final es:

<GoogleMapReact>
<Marker />
<Polylines />
</GoogleMapReact>

El resultado visual es algo así :

🌚 Agregando dark mode

Para la paleta de colores usaremos snazzymaps nos pone a la mano una galería de mapas personalizados con distintas paletas de colores. Lo mejor es que nos da el array que necesitamos. Este lo agregaremos en la prop de options de la siguiente manera:

options={styles: [Array]}

En el ejemplo lo usaremos con un operador ternario para elegir el tema, basado en una variable controlada por un switch.

Dejare por aquí el link del repositorio para que puedan ver más a detalle la implementación y también dejo el resultado final del ejercicio.

👉 https://github.com/owivans/gump-map
🌎 https://boiling-escarpment-78557.herokuapp.com/

Espero haya sido de utilidad, nos leemos luego…

--

--

Ivan Díaz
Nowports Tech and Product

Senior Software Engineer at Nowports | Program Lead & JavaScript Mentor at Kodemia