From 2c4698e1a5f3f6be75904aa1740ef72abed3c52b Mon Sep 17 00:00:00 2001 From: Serverlele30 <46974281+Serverlele30@users.noreply.github.com> Date: Wed, 31 Dec 2025 21:05:09 +0100 Subject: [PATCH] Add files via upload --- index.html | 383 +++++++++++++++++++++++++++++++++++++++++++++- service-worker.js | 2 +- 2 files changed, 381 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index ccfd455..5d8f022 100644 --- a/index.html +++ b/index.html @@ -49,7 +49,7 @@ background-color: #000; position: sticky; top: 0; - z-index: 100; + z-index: 10000; border-bottom: 2px solid #FFED00; } @@ -100,6 +100,7 @@ border-radius: 6px; transition: background-color 0.2s; line-height: 1; + z-index: 10001; } .menu-btn:active { @@ -116,7 +117,7 @@ height: 100%; background-color: #000; border-left: 2px solid #FFED00; - z-index: 1000; + z-index: 10003; transition: right 0.3s ease; } @@ -131,7 +132,7 @@ width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.7); - z-index: 999; + z-index: 10002; display: none; } @@ -1679,7 +1680,138 @@ font-size: 16px; } } + + /* Live-Map Styles */ + .livemap-container { + width: 100%; + height: calc(100vh - 140px); + position: relative; + overflow: hidden; + } + + #liveMap { + width: 100%; + height: 100%; + } + + .livemap-controls { + position: absolute; + top: 10px; + left: 10px; + right: 10px; + z-index: 1000; + display: flex; + flex-direction: column; + gap: 10px; + } + + .livemap-info { + background-color: rgba(0, 0, 0, 0.85); + padding: 12px 16px; + border-radius: 8px; + border: 2px solid #FFED00; + font-size: 16px; + font-weight: bold; + text-align: center; + color: #FFED00; + } + + .livemap-filters { + display: flex; + gap: 8px; + flex-wrap: wrap; + justify-content: center; + } + + .filter-btn { + background-color: rgba(0, 0, 0, 0.85); + border: 2px solid #666; + color: #FFED00; + padding: 8px 14px; + border-radius: 6px; + font-family: 'DotMatrix', 'Courier New', monospace; + font-size: 14px; + cursor: pointer; + transition: all 0.2s; + font-weight: bold; + } + + .filter-btn.active { + background-color: #FFED00; + color: #000; + border-color: #FFED00; + } + + .filter-btn:active { + transform: scale(0.95); + } + + /* Leaflet Marker Styling */ + .vehicle-marker { + font-size: 24px; + text-align: center; + animation: pulse-marker 2s ease-in-out infinite; + } + + @keyframes pulse-marker { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.1); } + } + + .vehicle-popup { + font-family: 'DotMatrix', 'Courier New', monospace; + } + + .vehicle-popup .popup-line { + font-size: 18px; + font-weight: bold; + color: #FFED00; + margin-bottom: 8px; + } + + .vehicle-popup .popup-direction { + font-size: 14px; + margin-bottom: 6px; + } + + .vehicle-popup .popup-delay { + font-size: 12px; + color: #ff5555; + font-weight: bold; + } + + @media (max-width: 767px) { + .livemap-controls { + top: 5px; + left: 5px; + right: 5px; + } + + .livemap-info { + padding: 10px 12px; + font-size: 14px; + } + + .filter-btn { + padding: 6px 10px; + font-size: 12px; + } + + .vehicle-marker { + font-size: 20px; + } + } + + + + + +
@@ -1718,6 +1850,10 @@ ๐Ÿ—บ๏ธ Routenplaner +
@@ -1810,6 +1946,25 @@ + +
+
+
+
+ ๐Ÿš‡ Lade Fahrzeuge... +
+
+ + + + + +
+
+
+
+
+
@@ -1932,12 +2087,40 @@ }); // Switch views + const viewLiveMap = document.getElementById('view-livemap'); + if (viewName === 'departures') { viewDepartures.classList.add('active'); viewJourney.classList.remove('active'); + viewLiveMap.classList.remove('active'); + + // Stop Live-Map Updates + if (liveMapUpdateInterval) { + clearInterval(liveMapUpdateInterval); + liveMapUpdateInterval = null; + } } else if (viewName === 'journey') { viewDepartures.classList.remove('active'); viewJourney.classList.add('active'); + viewLiveMap.classList.remove('active'); + + // Stop Live-Map Updates + if (liveMapUpdateInterval) { + clearInterval(liveMapUpdateInterval); + liveMapUpdateInterval = null; + } + } else if (viewName === 'livemap') { + viewDepartures.classList.remove('active'); + viewJourney.classList.remove('active'); + viewLiveMap.classList.add('active'); + + // Initialize Live-Map wenn noch nicht geschehen + setTimeout(() => { + initLiveMap(); + if (liveMap) { + liveMap.invalidateSize(); + } + }, 100); } currentView = viewName; @@ -3417,6 +3600,200 @@ if (!navigator.onLine) { offlineIndicator.classList.add('show'); } + + // ========================================== + // LIVE-MAP FUNCTIONALITY + // ========================================== + + let liveMap = null; + let vehicleMarkers = []; + let liveMapUpdateInterval = null; + let activeVehicleTypes = new Set(['all']); + + // Fahrzeug-Icons nach Typ + function getVehicleEmoji(product) { + const type = product?.mode || product?.name || ''; + + if (type.includes('subway') || type.includes('U-Bahn') || type.match(/^U\d/)) { + return '๐Ÿš‡'; + } else if (type.includes('suburban') || type.includes('S-Bahn') || type.match(/^S\d/)) { + return '๐Ÿš†'; + } else if (type.includes('tram') || type.includes('Tram') || type.includes('M1') || type.includes('M2')) { + return '๐ŸšŠ'; + } else if (type.includes('bus') || type.includes('Bus')) { + return '๐ŸšŒ'; + } else if (type.includes('regional') || type.includes('RE') || type.includes('RB')) { + return '๐Ÿš‰'; + } else if (type.includes('express') || type.includes('ICE') || type.includes('IC')) { + return '๐Ÿš…'; + } + + return '๐Ÿš'; // Default + } + + // Fahrzeugtyp bestimmen + function getVehicleType(product) { + const type = product?.mode || product?.name || ''; + + if (type.includes('subway') || type.includes('U-Bahn') || type.match(/^U\d/)) { + return 'subway'; + } else if (type.includes('suburban') || type.includes('S-Bahn') || type.match(/^S\d/)) { + return 'suburban'; + } else if (type.includes('tram') || type.includes('Tram')) { + return 'tram'; + } else if (type.includes('bus') || type.includes('Bus')) { + return 'bus'; + } + + return 'other'; + } + + // Live-Map initialisieren + function initLiveMap() { + if (liveMap) return; // Bereits initialisiert + + // Map zentriert auf Berlin + liveMap = L.map('liveMap').setView([52.52, 13.405], 12); + + // Tile Layer (OpenStreetMap) + L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + attribution: 'ยฉ OpenStreetMap contributors', + maxZoom: 18 + }).addTo(liveMap); + + // Fahrzeuge laden + loadVehicles(); + + // Auto-Update alle 10 Sekunden + liveMapUpdateInterval = setInterval(loadVehicles, 10000); + } + + // Fahrzeuge von API laden + async function loadVehicles() { + try { + // Berlin Bounding Box + const bounds = { + north: 52.70, + south: 52.35, + west: 13.08, + east: 13.76 + }; + + const url = `${API_BASE}/radar?` + + `north=${bounds.north}&south=${bounds.south}&` + + `west=${bounds.west}&east=${bounds.east}&` + + `results=200&duration=60&` + + `subway=true&bus=true&tram=true&suburban=true®ional=true`; + + const response = await fetch(url); + if (!response.ok) throw new Error('Radar API Error'); + + const data = await response.json(); + displayVehicles(data.movements || []); + + } catch (error) { + console.error('Load vehicles error:', error); + document.getElementById('vehicleCount').textContent = + 'โš ๏ธ Fehler beim Laden der Fahrzeuge'; + } + } + + // Fahrzeuge auf Map anzeigen + function displayVehicles(movements) { + // Alte Marker entfernen + vehicleMarkers.forEach(marker => marker.remove()); + vehicleMarkers = []; + + // Filtern nach aktiven Typen + const filteredMovements = movements.filter(m => { + if (activeVehicleTypes.has('all')) return true; + const vehicleType = getVehicleType(m.line?.product); + return activeVehicleTypes.has(vehicleType); + }); + + // Update Counter + document.getElementById('vehicleCount').innerHTML = + `๐Ÿš‡ ${filteredMovements.length} Fahrzeuge aktiv`; + + // Marker erstellen + filteredMovements.forEach(movement => { + if (!movement.location || !movement.location.latitude || !movement.location.longitude) { + return; + } + + const lat = movement.location.latitude; + const lon = movement.location.longitude; + const emoji = getVehicleEmoji(movement.line?.product); + + // Custom Icon mit Emoji + const icon = L.divIcon({ + html: `
${emoji}
`, + className: 'custom-marker', + iconSize: [32, 32], + iconAnchor: [16, 16] + }); + + // Marker erstellen + const marker = L.marker([lat, lon], { icon: icon }); + + // Popup mit Fahrzeuginfos + const lineName = movement.line?.name || 'Unbekannt'; + const direction = movement.direction || 'Keine Angabe'; + const delay = movement.delay ? `+${Math.round(movement.delay / 60)} min Verspรคtung` : 'Pรผnktlich'; + + const popupContent = ` +
+ + + +
+ `; + + marker.bindPopup(popupContent); + marker.addTo(liveMap); + vehicleMarkers.push(marker); + }); + } + + // Filter Buttons + document.querySelectorAll('.filter-btn').forEach(btn => { + btn.addEventListener('click', function() { + const type = this.dataset.type; + + if (type === 'all') { + // Alle Filter deaktivieren, nur "Alle" aktiv + document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active')); + this.classList.add('active'); + activeVehicleTypes.clear(); + activeVehicleTypes.add('all'); + } else { + // "Alle" deaktivieren + document.querySelector('.filter-btn[data-type="all"]').classList.remove('active'); + activeVehicleTypes.delete('all'); + + // Toggle Filter + if (activeVehicleTypes.has(type)) { + activeVehicleTypes.delete(type); + this.classList.remove('active'); + } else { + activeVehicleTypes.add(type); + this.classList.add('active'); + } + + // Falls keine Filter aktiv, "Alle" wieder aktivieren + if (activeVehicleTypes.size === 0) { + activeVehicleTypes.add('all'); + document.querySelector('.filter-btn[data-type="all"]').classList.add('active'); + } + } + + // Fahrzeuge neu laden mit Filter + loadVehicles(); + + if (navigator.vibrate) navigator.vibrate(5); + }); + }); + diff --git a/service-worker.js b/service-worker.js index ee4d176..895dd4f 100644 --- a/service-worker.js +++ b/service-worker.js @@ -1,4 +1,4 @@ -const CACHE_NAME = 'vbb-status-v15'; +const CACHE_NAME = 'vbb-status-v17'; const urlsToCache = [ '/', '/index.html',