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.
This commit is contained in:
@ -15,7 +15,7 @@ export function useETA() {
|
|||||||
const cargando = ref<boolean>(false);
|
const cargando = ref<boolean>(false);
|
||||||
|
|
||||||
// Configuración para el cálculo del ETA mejorado
|
// 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
|
const TIEMPO_PARADA_SEGUNDOS = 45; // segundos detenido por parada
|
||||||
|
|
||||||
// Fórmula Haversine para distancia en línea recta (km)
|
// 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
|
// 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.
|
// y calculamos la proporción según la parada.
|
||||||
if (routeData.estimated_duration_minutes && routeData.distance_km) {
|
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;
|
minutosHastaParada = routeData.estimated_duration_minutes * proporcionDistancia;
|
||||||
} else {
|
} else {
|
||||||
const tiempoViajeMinutos = (distanciaAcumuladaKm / velocidad) * 60;
|
const tiempoViajeMinutos = (distanciaAcumuladaKm / velocidad) * 60;
|
||||||
|
|||||||
@ -116,7 +116,7 @@ export const useFlujoPrincipal = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await encontrarParadaCercana(ubicacion, paradas, map)
|
await encontrarParadaCercana(ubicacion, paradas, map, cancelToken)
|
||||||
const paradaCercanaFound = paradaCercana.value
|
const paradaCercanaFound = paradaCercana.value
|
||||||
|
|
||||||
if (cancelToken?.cancelled || routeStore.selectedRouteId !== _ruta.id) {
|
if (cancelToken?.cancelled || routeStore.selectedRouteId !== _ruta.id) {
|
||||||
|
|||||||
@ -35,7 +35,8 @@ export function useParadaCercana() {
|
|||||||
const encontrarParadaCercana = async (
|
const encontrarParadaCercana = async (
|
||||||
ubicacionUsuario: { lat: number; lng: number },
|
ubicacionUsuario: { lat: number; lng: number },
|
||||||
paradas: BusStop[],
|
paradas: BusStop[],
|
||||||
map: google.maps.Map | undefined
|
map: google.maps.Map | undefined,
|
||||||
|
cancelToken?: { cancelled: boolean }
|
||||||
) => {
|
) => {
|
||||||
if (!paradas || paradas.length === 0 || !ubicacionUsuario) return;
|
if (!paradas || paradas.length === 0 || !ubicacionUsuario) return;
|
||||||
limpiarCaminata();
|
limpiarCaminata();
|
||||||
@ -105,6 +106,12 @@ export function useParadaCercana() {
|
|||||||
console.error('Error cargando Directions API en useParadaCercana', e);
|
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
|
// 3. Fallback a la más cercana lineal si falla API
|
||||||
if (!mejorParada) {
|
if (!mejorParada) {
|
||||||
mejorParada = top5[0] || null;
|
mejorParada = top5[0] || null;
|
||||||
@ -117,7 +124,7 @@ export function useParadaCercana() {
|
|||||||
duracionCaminata.value = mejorDuracion; // en segundos
|
duracionCaminata.value = mejorDuracion; // en segundos
|
||||||
|
|
||||||
// 4. Dibujar polilínea de caminata punteada azul
|
// 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({
|
caminandoPolyline.value = new google.maps.Polyline({
|
||||||
path: mejorRutaPuntos,
|
path: mejorRutaPuntos,
|
||||||
strokeColor: '#F59E0B',
|
strokeColor: '#F59E0B',
|
||||||
|
|||||||
@ -472,7 +472,7 @@ async function highlightOptimalStopForRoute() {
|
|||||||
if (!userCoords.value || routeStore.selectedRouteStops.length === 0) return;
|
if (!userCoords.value || routeStore.selectedRouteStops.length === 0) return;
|
||||||
|
|
||||||
try {
|
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) {
|
} catch (e) {
|
||||||
console.error('Error calculating optimal stop:', e);
|
console.error('Error calculating optimal stop:', e);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user