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:
@ -29,7 +29,12 @@ export function useDirectionsRoute() {
|
|||||||
// Función utilitaria para pausar ejecución
|
// Función utilitaria para pausar ejecución
|
||||||
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
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) {
|
if (!paradas || paradas.length < 2) {
|
||||||
errorRuta.value = 'Se requieren al menos 2 paradas para trazar una ruta.';
|
errorRuta.value = 'Se requieren al menos 2 paradas para trazar una ruta.';
|
||||||
return;
|
return;
|
||||||
@ -46,6 +51,9 @@ export function useDirectionsRoute() {
|
|||||||
const maxWaypoints = 23; // Google Directions limit is typically 25 including origin/dest
|
const maxWaypoints = 23; // Google Directions limit is typically 25 including origin/dest
|
||||||
|
|
||||||
for (let i = 0; i < paradas.length - 1; i += maxWaypoints) {
|
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);
|
const chunk = paradas.slice(i, i + maxWaypoints + 1);
|
||||||
if (chunk.length < 2) break;
|
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];
|
const route = result.routes[0];
|
||||||
if (route?.overview_path) {
|
if (route?.overview_path) {
|
||||||
const polyline = new google.maps.Polyline({
|
const polyline = new google.maps.Polyline({
|
||||||
@ -95,13 +103,15 @@ export function useDirectionsRoute() {
|
|||||||
console.warn(`SIBU | Tramo ${i} falló con Directions API: `, err);
|
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);
|
await delay(300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
if (!cancelToken?.cancelled) {
|
||||||
errorRuta.value = `Error crítico al trazar la ruta: ${err.message || String(err)}`;
|
errorRuta.value = `Error crítico al trazar la ruta: ${err.message || String(err)}`;
|
||||||
console.error(errorRuta.value);
|
console.error(errorRuta.value);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
estasCargando.value = false;
|
estasCargando.value = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -87,7 +87,7 @@ export const useFlujoPrincipal = () => {
|
|||||||
|
|
||||||
// Si no detectamos GPS, trazamos la ruta completa sin zoom guiado
|
// Si no detectamos GPS, trazamos la ruta completa sin zoom guiado
|
||||||
if (!ubicacion) {
|
if (!ubicacion) {
|
||||||
await trazarRuta(paradasFormateadas, map, false);
|
await trazarRuta(paradasFormateadas, map, false, cancelToken);
|
||||||
if (cancelToken?.cancelled) { limpiarMapa(); return; }
|
if (cancelToken?.cancelled) { limpiarMapa(); return; }
|
||||||
const bounds = new google.maps.LatLngBounds()
|
const bounds = new google.maps.LatLngBounds()
|
||||||
paradasFormateadas.forEach(p => bounds.extend(new google.maps.LatLng(p.latitud, p.longitud)))
|
paradasFormateadas.forEach(p => bounds.extend(new google.maps.LatLng(p.latitud, p.longitud)))
|
||||||
@ -102,7 +102,7 @@ export const useFlujoPrincipal = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dibujar ruta completa (fondo)
|
// Dibujar ruta completa (fondo)
|
||||||
await trazarRuta(paradasFormateadas, map, true);
|
await trazarRuta(paradasFormateadas, map, true, cancelToken);
|
||||||
|
|
||||||
if (cancelToken?.cancelled || routeStore.selectedRouteId !== _ruta.id) {
|
if (cancelToken?.cancelled || routeStore.selectedRouteId !== _ruta.id) {
|
||||||
limpiarMapa(); // limpiar polylines ya dibujadas
|
limpiarMapa(); // limpiar polylines ya dibujadas
|
||||||
@ -135,7 +135,7 @@ export const useFlujoPrincipal = () => {
|
|||||||
if (idx !== -1) {
|
if (idx !== -1) {
|
||||||
const tramoRelevante = paradasFormateadas.slice(idx)
|
const tramoRelevante = paradasFormateadas.slice(idx)
|
||||||
if (tramoRelevante.length > 1) {
|
if (tramoRelevante.length > 1) {
|
||||||
await trazarRuta(tramoRelevante, map, false)
|
await trazarRuta(tramoRelevante, map, false, cancelToken)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user