document.addEventListener('DOMContentLoaded', function() { // Initialize any interactive elements initDemoSimulation(); // Smooth scroll for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); document.querySelector(this.getAttribute('href')).scrollIntoView({ behavior: 'smooth' }); }); }); }); async function initTransportSystem() { console.log("Initializing Delhi Metro system..."); try { // Load static GTFS data from GitHub repository const routes = await fetch('https://raw.githubusercontent.com/emote-warrior/GTFSDelhi/main/routes.txt') .then(res => res.text()); const trips = await fetch('https://raw.githubusercontent.com/emote-warrior/GTFSDelhi/main/trips.txt') .then(res => res.text()); const stops = await fetch('https://raw.githubusercontent.com/emote-warrior/GTFSDelhi/main/stops.txt') .then(res => res.text()); // Parse CSV data const routesData = parseCSV(routes); const tripsData = parseCSV(trips); const stopsData = parseCSV(stops); // Process and visualize data visualizeNetwork(routesData, tripsData, stopsData); updateRealTimeStatus(); } catch (error) { console.error('Error loading transport data:', error); document.querySelector('#network-visualization').innerHTML = `

Error loading data. Please try again later.

`; } } function parseCSV(csvText) { const lines = csvText.split('\n'); const headers = lines[0].split(','); const result = []; for (let i = 1; i < lines.length; i++) { if (!lines[i]) continue; const obj = {}; const currentline = lines[i].split(','); for (let j = 0; j < headers.length; j++) { obj[headers[j]] = currentline[j]; } result.push(obj); } return result; } let map; let routeLayers = {}; let stopMarkers = {}; let tripLines = {}; function visualizeNetwork(routes, trips, stops) { // Initialize map centered on Delhi map = L.map('network-visualization').setView([28.6139, 77.2090], 12); // Add base tile layer L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map); // Process stops data (need to convert stop_lat/stop_lon to numbers) stops.forEach(stop => { stop.stop_lat = parseFloat(stop.stop_lat); stop.stop_lon = parseFloat(stop.stop_lon); }); // Group stops by route (simplified - in real app you'd use trips.txt and stop_times.txt) const stopsByRoute = {}; routes.forEach(route => { stopsByRoute[route.route_id] = stops.slice(0, 10); // Just show first 10 stops per route for demo }); // Create route layers routes.forEach(route => { const routeStops = stopsByRoute[route.route_id] || []; const routeCoordinates = routeStops.map(stop => [stop.stop_lat, stop.stop_lon]); routeLayers[route.route_id] = L.polyline(routeCoordinates, { color: `#${route.route_color || '333'}`, weight: 5, opacity: 0.7 }).bindPopup(`${route.route_long_name}
Route ID: ${route.route_id}`); }); // Create stop markers stops.forEach(stop => { stopMarkers[stop.stop_id] = L.circleMarker([stop.stop_lat, stop.stop_lon], { radius: 6, fillColor: "#ff7800", color: "#000", weight: 1, opacity: 1, fillOpacity: 0.8 }).bindPopup(`${stop.stop_name}
Stop ID: ${stop.stop_id}`); }); // Create trip lines (simplified - in real app you'd use actual trip paths) trips.slice(0, 20).forEach(trip => { // Limit to 20 trips for demo const routeStops = stopsByRoute[trip.route_id] || []; if (routeStops.length > 1) { const tripCoordinates = [ [routeStops[0].stop_lat, routeStops[0].stop_lon], [routeStops[routeStops.length-1].stop_lat, routeStops[routeStops.length-1].stop_lon] ]; tripLines[trip.trip_id] = L.polyline(tripCoordinates, { color: '#555', weight: 2, dashArray: '5, 5' }).bindPopup(`Trip ID: ${trip.trip_id}
Route: ${trip.route_id}`); } }); // Set up layer controls document.getElementById('show-routes').addEventListener('click', () => { Object.values(routeLayers).forEach(layer => map.addLayer(layer)); }); document.getElementById('show-stops').addEventListener('click', () => { Object.values(stopMarkers).forEach(marker => map.addLayer(marker)); }); document.getElementById('show-trips').addEventListener('click', () => { Object.values(tripLines).forEach(line => map.addLayer(line)); }); document.getElementById('reset-view').addEventListener('click', () => { map.setView([28.6139, 77.2090], 12); map.eachLayer(layer => { if (layer instanceof L.Polyline || layer instanceof L.CircleMarker) { map.removeLayer(layer); } }); }); // Show routes by default Object.values(routeLayers).forEach(layer => map.addLayer(layer)); } function updateRealTimeStatus() { // Simulate real-time updates setInterval(() => { const alerts = document.querySelectorAll('#current-alerts li'); const suggestions = document.querySelectorAll('#optimization-suggestions li'); // Rotate alerts and suggestions if (alerts.length > 0) { const firstAlert = alerts[0]; firstAlert.parentNode.appendChild(firstAlert); firstAlert.classList.add('animate-pulse'); setTimeout(() => firstAlert.classList.remove('animate-pulse'), 1000); } if (suggestions.length > 0) { const firstSuggestion = suggestions[0]; firstSuggestion.parentNode.appendChild(firstSuggestion); } }, 8000); } // Initialize on DOM load document.addEventListener('DOMContentLoaded', function() { initTransportSystem(); document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); document.querySelector(this.getAttribute('href')).scrollIntoView({ behavior: 'smooth' }); }); }); });