fix(map): total shielding against ghost lines.

- Updated useDirectionsRoute to support and respect cancelTokens in internal loops.
- Ensured all route tracing calls in useFlujoPrincipal are abortable.
- Prevented late polyline registration after map cleanup.
This commit is contained in:
2026-03-10 17:19:22 -05:00
parent 1b0f309f6a
commit 1c951dfced
2 changed files with 18 additions and 8 deletions

View File

@ -29,7 +29,12 @@ export function useDirectionsRoute() {
// Función utilitaria para pausar ejecución
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
const trazarRuta = async (paradas: Parada[], map: google.maps.Map, isPast: boolean = false) => {
const trazarRuta = async (
paradas: Parada[],
map: google.maps.Map,
isPast: boolean = false,
cancelToken?: { cancelled: boolean }
) => {
if (!paradas || paradas.length < 2) {
errorRuta.value = 'Se requieren al menos 2 paradas para trazar una ruta.';
return;
@ -46,6 +51,9 @@ export function useDirectionsRoute() {
const maxWaypoints = 23; // Google Directions limit is typically 25 including origin/dest
for (let i = 0; i < paradas.length - 1; i += maxWaypoints) {
// GUARD: Abortar si la operación fue cancelada durante el delay
if (cancelToken?.cancelled) break;
const chunk = paradas.slice(i, i + maxWaypoints + 1);
if (chunk.length < 2) break;
@ -73,7 +81,7 @@ export function useDirectionsRoute() {
});
});
if (result.routes && result.routes.length > 0) {
if (result.routes && result.routes.length > 0 && !cancelToken?.cancelled) {
const route = result.routes[0];
if (route?.overview_path) {
const polyline = new google.maps.Polyline({
@ -95,13 +103,15 @@ export function useDirectionsRoute() {
console.warn(`SIBU | Tramo ${i} falló con Directions API: `, err);
}
if (i + maxWaypoints < paradas.length - 1) {
if (i + maxWaypoints < paradas.length - 1 && !cancelToken?.cancelled) {
await delay(300);
}
}
} catch (err: any) {
errorRuta.value = `Error crítico al trazar la ruta: ${err.message || String(err)}`;
console.error(errorRuta.value);
if (!cancelToken?.cancelled) {
errorRuta.value = `Error crítico al trazar la ruta: ${err.message || String(err)}`;
console.error(errorRuta.value);
}
} finally {
estasCargando.value = false;
}

View File

@ -87,7 +87,7 @@ export const useFlujoPrincipal = () => {
// Si no detectamos GPS, trazamos la ruta completa sin zoom guiado
if (!ubicacion) {
await trazarRuta(paradasFormateadas, map, false);
await trazarRuta(paradasFormateadas, map, false, cancelToken);
if (cancelToken?.cancelled) { limpiarMapa(); return; }
const bounds = new google.maps.LatLngBounds()
paradasFormateadas.forEach(p => bounds.extend(new google.maps.LatLng(p.latitud, p.longitud)))
@ -102,7 +102,7 @@ export const useFlujoPrincipal = () => {
}
// Dibujar ruta completa (fondo)
await trazarRuta(paradasFormateadas, map, true);
await trazarRuta(paradasFormateadas, map, true, cancelToken);
if (cancelToken?.cancelled || routeStore.selectedRouteId !== _ruta.id) {
limpiarMapa(); // limpiar polylines ya dibujadas
@ -135,7 +135,7 @@ export const useFlujoPrincipal = () => {
if (idx !== -1) {
const tramoRelevante = paradasFormateadas.slice(idx)
if (tramoRelevante.length > 1) {
await trazarRuta(tramoRelevante, map, false)
await trazarRuta(tramoRelevante, map, false, cancelToken)
}
}