// Manejador de rutas internas const InternalRoutes = { paths: [], currentRoute: null, pathsLayer: null, map: null, // Inicializar el módulo init: async function(mapInstance) { this.map = mapInstance; await this.loadPaths(); this.initPathsLayer(); }, // Cargar los caminos desde paths.json async loadPaths() { try { const response = await fetch('paths.json'); this.paths = await response.json(); } catch (error) { console.error('Error loading internal paths:', error); this.paths = []; } }, // Inicializar la capa de caminos initPathsLayer() { if (this.pathsLayer) { this.map.removeLayer(this.pathsLayer); } this.pathsLayer = L.layerGroup().addTo(this.map); this.renderPaths(); }, // Renderizar los caminos en el mapa renderPaths() { this.paths.forEach(path => { L.polyline(path.points, { color: '#1a73e8', weight: 2, opacity: 0.3 }).addTo(this.pathsLayer); }); }, // Encontrar el punto más cercano en los caminos findNearestPathPoint(latlng) { let nearestPoint = null; let minDistance = Infinity; let nearestPathId = null; let pointIndex = -1; this.paths.forEach(path => { path.points.forEach((point, index) => { const d = this.calculateDistance( latlng[0], latlng[1], point[0], point[1] ); if (d < minDistance) { minDistance = d; nearestPoint = point; nearestPathId = path.id; pointIndex = index; } }); }); return { point: nearestPoint, pathId: nearestPathId, index: pointIndex, distance: minDistance }; }, // Calcular distancia entre dos puntos calculateDistance(lat1, lon1, lat2, lon2) { const R = 6371; // Radio de la Tierra en km const dLat = (lat2 - lat1) * Math.PI / 180; const dLon = (lon2 - lon1) * Math.PI / 180; const a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * Math.sin(dLon/2) * Math.sin(dLon/2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); return R * c; }, // Encontrar la mejor ruta interna entre dos puntos findRoute(startPoint, endPoint) { const start = this.findNearestPathPoint([startPoint.lat, startPoint.lng]); const end = this.findNearestPathPoint([endPoint.lat, endPoint.lng]); // Si los puntos están muy lejos de los caminos internos, retornar null if (start.distance > 0.0002 || end.distance > 0.0002) { return null; } // Encontrar la mejor ruta usando los caminos internos return this.findBestPath(start, end); }, // Algoritmo para encontrar la mejor ruta entre dos puntos findBestPath(start, end) { // Si están en el mismo camino, usar ese segmento const samePath = this.paths.find(p => p.id === start.pathId && p.id === end.pathId); if (samePath) { return { points: samePath.points.slice( Math.min(start.index, end.index), Math.max(start.index, end.index) + 1 ), isInternal: true }; } // Implementar búsqueda de ruta entre diferentes caminos // Por ahora retornamos null para usar ruta externa return null; }, // Mostrar una ruta en el mapa showRoute(route) { if (this.currentRoute) { this.map.removeLayer(this.currentRoute); } this.currentRoute = L.polyline(route.points, { color: '#1a73e8', weight: 6 }).addTo(this.map); this.map.fitBounds(this.currentRoute.getBounds(), { padding: [50, 50] }); }, // Limpiar la ruta actual clearRoute() { if (this.currentRoute) { this.map.removeLayer(this.currentRoute); this.currentRoute = null; } } }; // Función para integrar con el sistema existente function tryInternalRoute(startPoint, endPoint) { const internalRoute = InternalRoutes.findRoute(startPoint, endPoint); if (internalRoute) { InternalRoutes.showRoute(internalRoute); return true; } return false; }