From 1b0f309f6a405fe924d5270a7d26908125ba499e Mon Sep 17 00:00:00 2001 From: Hanzo_dev <2002samudiojohan@gmail.com> Date: Tue, 10 Mar 2026 17:10:01 -0500 Subject: [PATCH] fix(map): prevent ghost polylines and improve ETA accuracy. - Added cancel tokens to avoid 'traces' on map after route removal. - Fixed math bug in ETA proportion calculating 16.6% less time than real. - Set average bus speed to 30km/h for more realistic calculations. --- frontend/src/composables/useETA.ts | 5 +++-- frontend/src/composables/useFlujoPrincipal.ts | 2 +- frontend/src/composables/useParadaCercana.ts | 11 +++++++++-- frontend/src/views/MapView.vue | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/frontend/src/composables/useETA.ts b/frontend/src/composables/useETA.ts index d3059ce..faaf6c4 100644 --- a/frontend/src/composables/useETA.ts +++ b/frontend/src/composables/useETA.ts @@ -15,7 +15,7 @@ export function useETA() { const cargando = ref(false); // Configuración para el cálculo del ETA mejorado - const VELOCIDAD_PROMEDIO_KMH = 35; // km/h (promedio ciudad/carretera) + const VELOCIDAD_PROMEDIO_KMH = 30; // km/h (promedio ciudad/carretera) const TIEMPO_PARADA_SEGUNDOS = 45; // segundos detenido por parada // Fórmula Haversine para distancia en línea recta (km) @@ -111,7 +111,8 @@ export function useETA() { // Si la ruta tiene una duración estimada en BD, la usamos como base para el trayecto total // y calculamos la proporción según la parada. if (routeData.estimated_duration_minutes && routeData.distance_km) { - const proporcionDistancia = distanciaAcumuladaKm / (routeData.distance_km * 1.2); + // Bug fix: No multiplicar el denominador por 1.2 si distance_km ya es la distancia real + const proporcionDistancia = Math.min(distanciaAcumuladaKm / routeData.distance_km, 1.0); minutosHastaParada = routeData.estimated_duration_minutes * proporcionDistancia; } else { const tiempoViajeMinutos = (distanciaAcumuladaKm / velocidad) * 60; diff --git a/frontend/src/composables/useFlujoPrincipal.ts b/frontend/src/composables/useFlujoPrincipal.ts index b5696e2..55a0b67 100644 --- a/frontend/src/composables/useFlujoPrincipal.ts +++ b/frontend/src/composables/useFlujoPrincipal.ts @@ -116,7 +116,7 @@ export const useFlujoPrincipal = () => { return; } - await encontrarParadaCercana(ubicacion, paradas, map) + await encontrarParadaCercana(ubicacion, paradas, map, cancelToken) const paradaCercanaFound = paradaCercana.value if (cancelToken?.cancelled || routeStore.selectedRouteId !== _ruta.id) { diff --git a/frontend/src/composables/useParadaCercana.ts b/frontend/src/composables/useParadaCercana.ts index e847f80..8f391ec 100644 --- a/frontend/src/composables/useParadaCercana.ts +++ b/frontend/src/composables/useParadaCercana.ts @@ -35,7 +35,8 @@ export function useParadaCercana() { const encontrarParadaCercana = async ( ubicacionUsuario: { lat: number; lng: number }, paradas: BusStop[], - map: google.maps.Map | undefined + map: google.maps.Map | undefined, + cancelToken?: { cancelled: boolean } ) => { if (!paradas || paradas.length === 0 || !ubicacionUsuario) return; limpiarCaminata(); @@ -105,6 +106,12 @@ export function useParadaCercana() { console.error('Error cargando Directions API en useParadaCercana', e); } + // GUARD: Si se canceló durante las peticiones HTTP, abortar antes de dibujar y asignar + if (cancelToken?.cancelled) { + console.log('SIB | Operación encontrarParadaCercana cancelada'); + return; + } + // 3. Fallback a la más cercana lineal si falla API if (!mejorParada) { mejorParada = top5[0] || null; @@ -117,7 +124,7 @@ export function useParadaCercana() { duracionCaminata.value = mejorDuracion; // en segundos // 4. Dibujar polilínea de caminata punteada azul - if (map && mejorRutaPuntos.length > 0) { + if (map && mejorRutaPuntos.length > 0 && !cancelToken?.cancelled) { caminandoPolyline.value = new google.maps.Polyline({ path: mejorRutaPuntos, strokeColor: '#F59E0B', diff --git a/frontend/src/views/MapView.vue b/frontend/src/views/MapView.vue index f40c2a1..d341097 100644 --- a/frontend/src/views/MapView.vue +++ b/frontend/src/views/MapView.vue @@ -472,7 +472,7 @@ async function highlightOptimalStopForRoute() { if (!userCoords.value || routeStore.selectedRouteStops.length === 0) return; try { - await encontrarParadaCercana(userCoords.value, routeStore.selectedRouteStops as BusStop[], map.value || undefined); + await encontrarParadaCercana(userCoords.value, routeStore.selectedRouteStops as BusStop[], map.value || undefined, currentCancelToken); } catch (e) { console.error('Error calculating optimal stop:', e); }