Saber cuánto falta para llegar a cada punto de parada es fundamental en cualquier aplicación de rutas. En esta sesión se implementa el cálculo automático de distancias y tiempos entre cada parada de una rodada utilizando la librería de Google Maps Directions Service, integrándola directamente en un proyecto de Ionic con Angular.
¿Cómo se integra la librería de Google Maps en un proyecto Ionic?
Cuando trabajamos con librerías externas que no provienen de Angular ni de Ionic, la forma de incluirlas es diferente. En este caso, se agrega el script de Google Maps directamente en el archivo index.html, justo antes de la etiqueta de cierre del <head> [0:54]. Es imprescindible que utilices tu propia API key en la URL del script, ya que usar la de otra persona puede generar problemas de expiración y consumo no autorizado.
Una vez cargada la librería desde el HTML, necesitamos hacerla accesible dentro de nuestros archivos TypeScript. Para lograrlo, declaramos una constante global en el archivo ride-form.page.ts [1:24]:
typescript
declare const google: any;
Esta técnica se usa cuando no existe un import directo como ocurre con paquetes instalados vía NPM. Al declarar google como tipo any, el objeto se llena automáticamente cuando el script del index.html carga la librería.
¿Qué son los legs y cómo se preparan los waypoints?
Se declara una variable de clase llamada legs, inicializada como un arreglo vacío [1:52]. Los legs son el concepto que utiliza el API de Google Maps para representar la información de distancia y duración entre dos puntos consecutivos de una ruta.
Para preparar los datos que enviaremos al API, se aplica el método slice(1, -1) sobre el arreglo de waypoints [2:18]. Esto elimina el primer y último elemento, ya que Google Maps espera recibir el origen y destino por separado, y los puntos intermedios como waypoints.
Después, se transforma cada waypoint con .map() para darle el formato requerido [2:42]:
typescript
thisWaypoints = thisWaypoints.map(waypoint => ({
location: waypoint,
stopover: true
}));
La propiedad stopover: true indica que cada punto es una parada real, no simplemente un punto de paso.
También se agrega una validación importante: si hay menos de dos waypoints, el método retorna sin hacer nada [3:16]. No tiene sentido calcular distancias con un solo punto.
¿Cómo se construye y ejecuta la petición al Directions Service?
Se crea una instancia del servicio de direcciones [3:30]:
typescript
const directionsService = new google.maps.DirectionsService();
Luego se arma el objeto request con varias propiedades clave [3:44]:
- origin: el primer elemento del arreglo original de waypoints.
- waypoints: los puntos intermedios ya formateados.
- destination: el último elemento, obtenido con
thisWaypoints[thisWaypoints.length - 1].
- travelMode: se establece en
DRIVING porque la aplicación es para motos.
- drivingOptions.departureTime: recibe la hora de salida de la rodada con
new Date(this.ride.start). Esto permite que Google calcule tiempos considerando el tráfico real a esa hora específica [4:46].
- trafficModel: configurado como
BEST_GUESS para obtener la estimación más precisa.
- unitSystem:
google.maps.UnitSystem.METRIC para recibir resultados en kilómetros y metros [5:24].
Finalmente, se ejecuta la consulta con directionsService.route(request, (result, status) => {...}) [5:36]. El callback recibe el resultado y el estado de la petición.
¿Cómo se procesan los resultados?
Del resultado se extrae result.routes[0].legs [6:00]. Google puede devolver múltiples rutas ordenadas de mejor a peor; siempre se toma la primera. Cada leg contiene:
start_address y end_address: direcciones en texto claro.
start_location y end_location: objetos con latitud y longitud.
distance y duration: distancia y tiempo entre puntos.
Para start_location y end_location se extraen únicamente lat y lng [7:30]:
typescript
{
lat: leg.start_location.lat(),
lng: leg.start_location.lng()
}
Cada leg procesado se agrega al arreglo this.ride.waypoints mediante .push(), dejando el objeto listo para enviarse al backend con toda la información de la ruta.
Con esta implementación, cada parada de la rodada queda enriquecida con datos reales de distancia y duración basados en geocoding y condiciones de tráfico. ¿Has trabajado con otras APIs de mapas? Comparte tu experiencia en los comentarios.