chore: migrate Google Maps to Routes API and clean up deprecated code
This commit is contained in:
@ -13,15 +13,15 @@ export interface Parada {
|
||||
export function useDirectionsRoute() {
|
||||
const estasCargando = ref<boolean>(false);
|
||||
const errorRuta = ref<string | null>(null);
|
||||
const { registrarRenderer, renderers } = useMapState();
|
||||
const { registrarPolyline, polylines } = useMapState();
|
||||
|
||||
// Limpia los tramos anteriores dibujados en el mapa
|
||||
const limpiarRuta = () => {
|
||||
if (renderers.value.length > 0) {
|
||||
renderers.value.forEach((renderer) => {
|
||||
renderer.setMap(null);
|
||||
if (polylines.value.length > 0) {
|
||||
polylines.value.forEach((polyline) => {
|
||||
polyline.setMap(null);
|
||||
});
|
||||
renderers.value = [];
|
||||
polylines.value = [];
|
||||
}
|
||||
errorRuta.value = null;
|
||||
};
|
||||
@ -40,64 +40,81 @@ export function useDirectionsRoute() {
|
||||
errorRuta.value = null;
|
||||
|
||||
try {
|
||||
const directionsService = new google.maps.DirectionsService();
|
||||
// Límite de la API de Google Maps: Origen, Destino, y hasta 23 waypoints (25 puntos total por request)
|
||||
// Importar librerías necesarias de la nueva API
|
||||
const { Route } = await google.maps.importLibrary("routes") as any;
|
||||
|
||||
// Límite de la API de Google Maps Routes: Origen, Destino, y hasta 25 intermediates
|
||||
const maxPuntosPorChunk = 25;
|
||||
const overlaps = 1;
|
||||
|
||||
// Iteramos sobre las paradas dividiéndolas en chunks con 1 punto en común ("overlap")
|
||||
// para asegurar que las secciones se conecten correctamente.
|
||||
for (let i = 0; i < paradas.length - 1; i += (maxPuntosPorChunk - overlaps)) {
|
||||
const chunk = paradas.slice(i, i + maxPuntosPorChunk);
|
||||
|
||||
// Si el chunk es muy pequeño (último fragmento o vector final), detenemos
|
||||
if (chunk.length < 2) break;
|
||||
|
||||
const origen = new google.maps.LatLng(chunk[0]!.latitud, chunk[0]!.longitud);
|
||||
const destino = new google.maps.LatLng(chunk[chunk.length - 1]!.latitud, chunk[chunk.length - 1]!.longitud);
|
||||
|
||||
// Excluimos el primero y último para que sean los waypoints intermedios
|
||||
const waypoints: google.maps.DirectionsWaypoint[] = chunk.slice(1, -1).map(p => ({
|
||||
location: new google.maps.LatLng(p.latitud, p.longitud),
|
||||
stopover: true
|
||||
}));
|
||||
|
||||
const request: google.maps.DirectionsRequest = {
|
||||
origin: origen,
|
||||
destination: destino,
|
||||
waypoints: waypoints,
|
||||
travelMode: google.maps.TravelMode.DRIVING,
|
||||
optimizeWaypoints: false
|
||||
const origin = {
|
||||
location: {
|
||||
latLng: {
|
||||
latitude: chunk[0]!.latitud,
|
||||
longitude: chunk[0]!.longitud
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await directionsService.route(request);
|
||||
|
||||
const renderer = new google.maps.DirectionsRenderer({
|
||||
map: map,
|
||||
suppressMarkers: true, // SIBU maneja los suyos propios
|
||||
preserveViewport: true, // No auto centrar en cada tramo para evitar parpadeos visuales
|
||||
polylineOptions: isPast ? {
|
||||
strokeColor: '#FDE68A', // amarillo muy tenue
|
||||
strokeWeight: 3,
|
||||
strokeOpacity: 0.4
|
||||
} : {
|
||||
strokeColor: '#FBBF24', // amarillo principal
|
||||
strokeWeight: 5,
|
||||
strokeOpacity: 0.95
|
||||
const destination = {
|
||||
location: {
|
||||
latLng: {
|
||||
latitude: chunk[chunk.length - 1]!.latitud,
|
||||
longitude: chunk[chunk.length - 1]!.longitud
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const intermediates = chunk.slice(1, -1).map(p => ({
|
||||
location: {
|
||||
latLng: {
|
||||
latitude: p.latitud,
|
||||
longitude: p.longitud
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
try {
|
||||
const response = await Route.computeRoutes({
|
||||
origin,
|
||||
destination,
|
||||
intermediates,
|
||||
travelMode: 'DRIVE' as any, // 'DRIVE' es el nuevo estandar en computeRoutes
|
||||
routingPreference: 'TRAFFIC_UNAWARE' as any,
|
||||
polylineQuality: 'HIGH_QUALITY' as any,
|
||||
polylineEncoding: 'ENCODED_POLYLINE' as any,
|
||||
});
|
||||
|
||||
renderer.setDirections(response);
|
||||
registrarRenderer(renderer);
|
||||
if (response.routes && response.routes.length > 0) {
|
||||
const route = response.routes[0];
|
||||
if (route.polyline && route.polyline.encodedPolyline) {
|
||||
const path = google.maps.geometry.encoding.decodePath(route.polyline.encodedPolyline);
|
||||
|
||||
const polyline = new google.maps.Polyline({
|
||||
path: path,
|
||||
map: map,
|
||||
strokeColor: isPast ? '#FDE68A' : '#FBBF24',
|
||||
strokeWeight: isPast ? 3 : 5,
|
||||
strokeOpacity: isPast ? 0.4 : 0.95,
|
||||
icons: isPast ? [{
|
||||
icon: { path: 'M 0,-1 0,1', strokeOpacity: 1, scale: 2 },
|
||||
offset: '0',
|
||||
repeat: '10px'
|
||||
}] : []
|
||||
});
|
||||
|
||||
registrarPolyline(polyline);
|
||||
}
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.warn(`SIBU | Tramo ${i} falló: `, err);
|
||||
// La ruta continúa renderizando los siguientes tramos disponibles, no paramos todo.
|
||||
console.warn(`SIBU | Tramo ${i} falló con Routes API: `, err);
|
||||
}
|
||||
|
||||
// Retardo para evitar sobrecargar a la API y el error "OVER_QUERY_LIMIT"
|
||||
await delay(300);
|
||||
await delay(200);
|
||||
}
|
||||
} catch (err: any) {
|
||||
errorRuta.value = `Error crítico al trazar la ruta: ${err.message || String(err)}`;
|
||||
|
||||
@ -16,7 +16,6 @@ export function useGoogleMaps() {
|
||||
const error = ref<string | null>(null)
|
||||
const {
|
||||
registrarMarker,
|
||||
registrarRenderer,
|
||||
registrarPolyline,
|
||||
registrarCallbackLimpieza,
|
||||
limpiarMapa: limpiarTodoCentralizado
|
||||
@ -58,6 +57,7 @@ export function useGoogleMaps() {
|
||||
await importLibrary('maps');
|
||||
await importLibrary('places');
|
||||
await importLibrary('geometry');
|
||||
await importLibrary('routes');
|
||||
|
||||
if (typeof google === 'undefined' || !google.maps) {
|
||||
throw new Error('Google Maps se cargó pero el espacio de nombres "google.maps" no está disponible.');
|
||||
@ -398,76 +398,104 @@ export function useGoogleMaps() {
|
||||
|
||||
async function addRoutePolyline(paradas: Array<{ lat: number; lng: number }>) {
|
||||
if (!map.value) {
|
||||
console.error('Map not initialized')
|
||||
return []
|
||||
console.error('Map not initialized');
|
||||
return [];
|
||||
}
|
||||
if (!paradas || paradas.length < 2) {
|
||||
console.warn("Se necesitan al menos 2 paradas para trazar una ruta.");
|
||||
return []
|
||||
return [];
|
||||
}
|
||||
|
||||
// Limpiar antes de dibujar una nueva ruta para evitar acumulación
|
||||
limpiarTodoCentralizado()
|
||||
// Limpiar antes de dibujar una nueva ruta
|
||||
limpiarTodoCentralizado();
|
||||
if (map.value && globalOverlays.has(map.value)) {
|
||||
clearAllOverlaysForMap(map.value)
|
||||
clearAllOverlaysForMap(map.value);
|
||||
}
|
||||
|
||||
const directionsService = new google.maps.DirectionsService();
|
||||
const renderizadoresActivos: google.maps.DirectionsRenderer[] = [];
|
||||
const tamañoChunk = 25;
|
||||
const polylinesCreadas: google.maps.Polyline[] = [];
|
||||
const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
||||
for (let i = 0; i < paradas.length - 1; i += (tamañoChunk - 1)) {
|
||||
const chunk = paradas.slice(i, i + tamañoChunk);
|
||||
if (chunk.length < 2) break;
|
||||
try {
|
||||
// Cargar ruta
|
||||
const { Route } = await google.maps.importLibrary("routes") as any;
|
||||
|
||||
const origen = { lat: chunk[0]!.lat, lng: chunk[0]!.lng };
|
||||
const destino = { lat: chunk[chunk.length - 1]!.lat, lng: chunk[chunk.length - 1]!.lng };
|
||||
const tamañoChunk = 25;
|
||||
|
||||
const waypoints = chunk.slice(1, -1).map(p => ({
|
||||
location: { lat: p.lat, lng: p.lng },
|
||||
stopover: true
|
||||
}));
|
||||
for (let i = 0; i < paradas.length - 1; i += (tamañoChunk - 1)) {
|
||||
const chunk = paradas.slice(i, i + tamañoChunk);
|
||||
if (chunk.length < 2) break;
|
||||
|
||||
const request = {
|
||||
origin: origen,
|
||||
destination: destino,
|
||||
waypoints: waypoints,
|
||||
travelMode: google.maps.TravelMode.DRIVING,
|
||||
optimizeWaypoints: false
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await directionsService.route(request);
|
||||
|
||||
const renderer = new google.maps.DirectionsRenderer({
|
||||
map: map.value,
|
||||
suppressMarkers: true,
|
||||
preserveViewport: true, // Siempre conservar la vista ya que trazamos fragmentos
|
||||
polylineOptions: {
|
||||
strokeColor: '#FBBF24', // Amarillo consistente con paradas
|
||||
strokeWeight: 5,
|
||||
strokeOpacity: 0.95
|
||||
const origin = {
|
||||
location: {
|
||||
latLng: {
|
||||
latitude: chunk[0]!.lat,
|
||||
longitude: chunk[0]!.lng
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
const destination = {
|
||||
location: {
|
||||
latLng: {
|
||||
latitude: chunk[chunk.length - 1]!.lat,
|
||||
longitude: chunk[chunk.length - 1]!.lng
|
||||
}
|
||||
}
|
||||
};
|
||||
const intermediates = chunk.slice(1, -1).map(p => ({
|
||||
location: {
|
||||
latLng: {
|
||||
latitude: p.lat,
|
||||
longitude: p.lng
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
renderer.setDirections(response);
|
||||
renderizadoresActivos.push(renderer);
|
||||
registrarRenderer(renderer); // Registrar para limpieza centralizada
|
||||
try {
|
||||
const response = await Route.computeRoutes({
|
||||
origin,
|
||||
destination,
|
||||
intermediates,
|
||||
travelMode: 'DRIVE',
|
||||
routingPreference: 'TRAFFIC_UNAWARE',
|
||||
polylineQuality: 'HIGH_QUALITY',
|
||||
polylineEncoding: 'ENCODED_POLYLINE',
|
||||
});
|
||||
|
||||
// Registrar en global overlays para limpiarlos después
|
||||
if (!globalOverlays.has(map.value)) {
|
||||
globalOverlays.set(map.value, new Set())
|
||||
if (response.routes && response.routes.length > 0) {
|
||||
const route = response.routes[0];
|
||||
if (route.polyline && route.polyline.encodedPolyline) {
|
||||
const path = google.maps.geometry.encoding.decodePath(route.polyline.encodedPolyline);
|
||||
|
||||
const polyline = new google.maps.Polyline({
|
||||
path: path,
|
||||
map: map.value,
|
||||
strokeColor: '#FBBF24',
|
||||
strokeWeight: 5,
|
||||
strokeOpacity: 0.95,
|
||||
geodesic: true
|
||||
});
|
||||
|
||||
polylinesCreadas.push(polyline);
|
||||
registrarPolyline(polyline);
|
||||
|
||||
// Registrar en global overlays
|
||||
if (!globalOverlays.has(map.value)) {
|
||||
globalOverlays.set(map.value, new Set());
|
||||
}
|
||||
globalOverlays.get(map.value)!.add(polyline);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error trazando el tramo (Paradas ${i} a ${i + chunk.length}):`, error);
|
||||
}
|
||||
globalOverlays.get(map.value)!.add(renderer as any);
|
||||
|
||||
} catch (error) {
|
||||
console.error(`Error trazando el tramo (Paradas ${i} a ${i + chunk.length}):`, error);
|
||||
await delay(200);
|
||||
}
|
||||
|
||||
await delay(200);
|
||||
} catch (e) {
|
||||
console.error('Error cargando Routes API:', e);
|
||||
}
|
||||
return renderizadoresActivos;
|
||||
|
||||
return polylinesCreadas;
|
||||
}
|
||||
|
||||
function fitBounds(path: Array<{ lat: number; lng: number }>) {
|
||||
|
||||
@ -2,7 +2,6 @@ import { ref } from 'vue'
|
||||
|
||||
// Registro global de todo lo que está en el mapa
|
||||
const markers = ref<google.maps.Marker[]>([])
|
||||
const renderers = ref<google.maps.DirectionsRenderer[]>([])
|
||||
const polylines = ref<google.maps.Polyline[]>([])
|
||||
const infoWindows = ref<google.maps.InfoWindow[]>([])
|
||||
const circles = ref<google.maps.Circle[]>([])
|
||||
@ -15,11 +14,7 @@ export const useMapState = () => {
|
||||
return marker
|
||||
}
|
||||
|
||||
// Registrar un renderer
|
||||
const registrarRenderer = (renderer: google.maps.DirectionsRenderer) => {
|
||||
if (renderer) renderers.value.push(renderer)
|
||||
return renderer
|
||||
}
|
||||
|
||||
|
||||
// Registrar una polyline
|
||||
const registrarPolyline = (polyline: google.maps.Polyline) => {
|
||||
@ -48,7 +43,7 @@ export const useMapState = () => {
|
||||
|
||||
// ⚠️ FUNCIÓN CRÍTICA: limpiar ABSOLUTAMENTE TODO del mapa
|
||||
const limpiarMapa = () => {
|
||||
console.log(`SIBU | Iniciando limpieza de ${markers.value.length} markers, ${renderers.value.length} renderers, ${polylines.value.length} polylines...`)
|
||||
console.log(`SIBU | Iniciando limpieza de ${markers.value.length} markers, ${polylines.value.length} polylines...`)
|
||||
|
||||
// Eliminar markers y overlays HTML
|
||||
markers.value.forEach(m => {
|
||||
@ -67,18 +62,7 @@ export const useMapState = () => {
|
||||
})
|
||||
markers.value = []
|
||||
|
||||
// Eliminar renderers de Directions
|
||||
renderers.value.forEach(r => {
|
||||
try {
|
||||
if (r) {
|
||||
if (typeof r.setMap === 'function') r.setMap(null);
|
||||
if (typeof r.setDirections === 'function') r.setDirections({ routes: [] } as any);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Error limpiando renderer', e)
|
||||
}
|
||||
})
|
||||
renderers.value = []
|
||||
|
||||
|
||||
// Eliminar polylines
|
||||
polylines.value.forEach(p => {
|
||||
@ -125,12 +109,10 @@ export const useMapState = () => {
|
||||
|
||||
return {
|
||||
markers,
|
||||
renderers,
|
||||
polylines,
|
||||
infoWindows,
|
||||
circles,
|
||||
registrarMarker,
|
||||
registrarRenderer,
|
||||
registrarPolyline,
|
||||
registrarCircle,
|
||||
registrarInfoWindow,
|
||||
|
||||
@ -49,45 +49,70 @@ export function useParadaCercana() {
|
||||
paradasConDistLineal.sort((a, b) => a.distancia - b.distancia);
|
||||
const top5 = paradasConDistLineal.slice(0, 5).map(item => item.parada);
|
||||
|
||||
// 2. Usar Directions API para encontrar la más cercana por calles reales
|
||||
// 2. Usar Routes API para encontrar la más cercana por calles reales
|
||||
let mejorParada: BusStop | null = null;
|
||||
let minimaDistanciaCalles = Infinity;
|
||||
let mejorDuracion = 0;
|
||||
let mejorRutaPuntos: google.maps.LatLng[] = [];
|
||||
|
||||
const directionsService = new google.maps.DirectionsService();
|
||||
try {
|
||||
const { Route } = await google.maps.importLibrary("routes") as any;
|
||||
|
||||
for (const stop of top5) {
|
||||
try {
|
||||
const response = await directionsService.route({
|
||||
origin: new google.maps.LatLng(ubicacionUsuario.lat, ubicacionUsuario.lng),
|
||||
destination: new google.maps.LatLng(stop.latitude, stop.longitude),
|
||||
travelMode: google.maps.TravelMode.DRIVING // Calles reales
|
||||
});
|
||||
for (const stop of top5) {
|
||||
try {
|
||||
const response = await Route.computeRoutes({
|
||||
origin: {
|
||||
location: {
|
||||
latLng: {
|
||||
latitude: ubicacionUsuario.lat,
|
||||
longitude: ubicacionUsuario.lng
|
||||
}
|
||||
}
|
||||
},
|
||||
destination: {
|
||||
location: {
|
||||
latLng: {
|
||||
latitude: stop.latitude,
|
||||
longitude: stop.longitude
|
||||
}
|
||||
}
|
||||
},
|
||||
travelMode: 'DRIVE',
|
||||
routingPreference: 'TRAFFIC_UNAWARE',
|
||||
polylineQuality: 'HIGH_QUALITY',
|
||||
polylineEncoding: 'ENCODED_POLYLINE',
|
||||
});
|
||||
|
||||
if (response.routes && response.routes.length > 0) {
|
||||
const route = response.routes[0];
|
||||
if (!route) continue;
|
||||
let distTotal = 0;
|
||||
let durTotal = 0;
|
||||
if (response.routes && response.routes.length > 0) {
|
||||
const route = response.routes[0];
|
||||
let distTotal = 0;
|
||||
let durTotal = 0;
|
||||
|
||||
if (route.legs) {
|
||||
for (const leg of route.legs) {
|
||||
distTotal += leg.distance?.value || 0;
|
||||
durTotal += leg.duration?.value || 0;
|
||||
if (route.distanceMeters) {
|
||||
distTotal = route.distanceMeters;
|
||||
}
|
||||
|
||||
if (route.duration) {
|
||||
// La duración viene como string "123s"
|
||||
durTotal = parseInt(route.duration);
|
||||
}
|
||||
|
||||
if (distTotal < minimaDistanciaCalles) {
|
||||
minimaDistanciaCalles = distTotal;
|
||||
mejorDuracion = durTotal;
|
||||
mejorParada = stop;
|
||||
|
||||
if (route.polyline && route.polyline.encodedPolyline) {
|
||||
mejorRutaPuntos = google.maps.geometry.encoding.decodePath(route.polyline.encodedPolyline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (distTotal < minimaDistanciaCalles) {
|
||||
minimaDistanciaCalles = distTotal;
|
||||
mejorDuracion = durTotal;
|
||||
mejorParada = stop;
|
||||
mejorRutaPuntos = route.overview_path;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Error calculando ruta a parada', stop.name, e);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Error calculando ruta a parada', stop.name, e);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error cargando Routes API en useParadaCercana', e);
|
||||
}
|
||||
|
||||
// 3. Fallback a la más cercana lineal si falla API
|
||||
|
||||
@ -642,7 +642,7 @@ function drawInternalWalkingRoute(targetStop: BusStop, originOverride?: { lat: n
|
||||
}
|
||||
}
|
||||
|
||||
function calculateWalkingPath(origin: { lat: number, lng: number }, targetStop: BusStop) {
|
||||
async function calculateWalkingPath(origin: { lat: number, lng: number }, targetStop: BusStop) {
|
||||
// 1. Limpiar pulso anterior si existe
|
||||
if (optimalStopPulse.value) {
|
||||
if (typeof optimalStopPulse.value.setMap === 'function') {
|
||||
@ -678,58 +678,71 @@ function calculateWalkingPath(origin: { lat: number, lng: number }, targetStop:
|
||||
}
|
||||
|
||||
// 2. Trazar línea de puntos verde siguiendo RED VIAL PRINCIPAL
|
||||
const directionsService = new google.maps.DirectionsService();
|
||||
directionsService.route({
|
||||
origin: origin,
|
||||
destination: { lat: targetStop.latitude, lng: targetStop.longitude },
|
||||
travelMode: google.maps.TravelMode.DRIVING,
|
||||
}, (dirResult, dirStatus) => {
|
||||
if (dirStatus === 'OK' && dirResult && dirResult.routes && dirResult.routes[0]) {
|
||||
const route = dirResult.routes[0];
|
||||
const leg = route.legs?.[0];
|
||||
try {
|
||||
const { Route } = await google.maps.importLibrary("routes") as any;
|
||||
const response = await Route.computeRoutes({
|
||||
origin: {
|
||||
location: {
|
||||
latLng: { latitude: origin.lat, longitude: origin.lng }
|
||||
}
|
||||
},
|
||||
destination: {
|
||||
location: {
|
||||
latLng: { latitude: targetStop.latitude, longitude: targetStop.longitude }
|
||||
}
|
||||
},
|
||||
travelMode: 'DRIVE',
|
||||
routingPreference: 'TRAFFIC_UNAWARE',
|
||||
polylineQuality: 'HIGH_QUALITY',
|
||||
polylineEncoding: 'ENCODED_POLYLINE',
|
||||
});
|
||||
|
||||
// Guardar info de navegación (ETA y Distancia) (Retirado a favor de ETA Card / Parada Cercana Banner)
|
||||
if (leg) {
|
||||
// console.log('Distancia', leg.distance?.text);
|
||||
}
|
||||
|
||||
if (walkingPolyline.value) walkingPolyline.value.setMap(null);
|
||||
if (walkingPolylineBorder.value) walkingPolylineBorder.value.setMap(null);
|
||||
if (response.routes && response.routes.length > 0) {
|
||||
const route = response.routes[0];
|
||||
|
||||
const { registrarPolyline: regPoly } = useMapState();
|
||||
if (route.polyline && route.polyline.encodedPolyline) {
|
||||
const path = google.maps.geometry.encoding.decodePath(route.polyline.encodedPolyline);
|
||||
|
||||
// CAPA 1: Borde blanco (Para dar contraste estilo Google Maps)
|
||||
walkingPolylineBorder.value = new google.maps.Polyline({
|
||||
path: route.overview_path,
|
||||
geodesic: true,
|
||||
strokeColor: '#FFFFFF',
|
||||
strokeOpacity: 0.9,
|
||||
strokeWeight: 10, // Un poco más grueso para el borde
|
||||
map: map.value,
|
||||
zIndex: 5
|
||||
});
|
||||
regPoly(walkingPolylineBorder.value);
|
||||
if (walkingPolyline.value) walkingPolyline.value.setMap(null);
|
||||
if (walkingPolylineBorder.value) walkingPolylineBorder.value.setMap(null);
|
||||
|
||||
const { registrarPolyline: regPoly } = useMapState();
|
||||
|
||||
// CAPA 2: Línea Indigo Central (La ruta principal)
|
||||
walkingPolyline.value = new google.maps.Polyline({
|
||||
path: route.overview_path,
|
||||
geodesic: true,
|
||||
strokeColor: '#4285F4', // Azul Google Maps
|
||||
strokeOpacity: 1.0,
|
||||
strokeWeight: 5,
|
||||
map: map.value,
|
||||
zIndex: 10
|
||||
});
|
||||
regPoly(walkingPolyline.value);
|
||||
// CAPA 1: Borde blanco (Para dar contraste estilo Google Maps)
|
||||
walkingPolylineBorder.value = new google.maps.Polyline({
|
||||
path: path,
|
||||
geodesic: true,
|
||||
strokeColor: '#FFFFFF',
|
||||
strokeOpacity: 0.9,
|
||||
strokeWeight: 10,
|
||||
map: map.value,
|
||||
zIndex: 5
|
||||
});
|
||||
regPoly(walkingPolylineBorder.value);
|
||||
|
||||
// Ajustar zoom para mostrar toda la ruta de caminata
|
||||
if (map.value) {
|
||||
const bounds = new google.maps.LatLngBounds();
|
||||
route.overview_path.forEach(p => bounds.extend(p));
|
||||
map.value.fitBounds(bounds, { top: 100, bottom: 200, left: 50, right: 50 });
|
||||
// CAPA 2: Línea Indigo Central (La ruta principal)
|
||||
walkingPolyline.value = new google.maps.Polyline({
|
||||
path: path,
|
||||
geodesic: true,
|
||||
strokeColor: '#4285F4', // Azul Google Maps
|
||||
strokeOpacity: 1.0,
|
||||
strokeWeight: 5,
|
||||
map: map.value,
|
||||
zIndex: 10
|
||||
});
|
||||
regPoly(walkingPolyline.value);
|
||||
|
||||
// Ajustar zoom para mostrar toda la ruta de caminata
|
||||
if (map.value) {
|
||||
const bounds = new google.maps.LatLngBounds();
|
||||
path.forEach(p => bounds.extend(p));
|
||||
map.value.fitBounds(bounds, { top: 100, bottom: 200, left: 50, right: 50 });
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn('SIBU | Error trazando ruta a pie con Routes API:', error);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user