From 6f4bd86c1806c32295f1f63a34953bf1f1dcd992 Mon Sep 17 00:00:00 2001 From: Serverlele30 <46974281+Serverlele30@users.noreply.github.com> Date: Fri, 22 Aug 2025 09:50:14 +0200 Subject: [PATCH] Add files via upload --- old/README.md | 4 + old/VBB-Live-Maps-BG/app.js | 224 +++++++++++++++++++++++++++++++ old/VBB-Live-Maps-BG/index.html | 23 ++++ old/VBB-Live-Maps-BG/style.css | 69 ++++++++++ old/app.js | 225 ++++++++++++++++++++++++++++++++ old/app.js.backup | 192 +++++++++++++++++++++++++++ old/index.html | 25 ++++ old/style.css | 43 ++++++ 8 files changed, 805 insertions(+) create mode 100644 old/README.md create mode 100644 old/VBB-Live-Maps-BG/app.js create mode 100644 old/VBB-Live-Maps-BG/index.html create mode 100644 old/VBB-Live-Maps-BG/style.css create mode 100644 old/app.js create mode 100644 old/app.js.backup create mode 100644 old/index.html create mode 100644 old/style.css diff --git a/old/README.md b/old/README.md new file mode 100644 index 0000000..9030bd8 --- /dev/null +++ b/old/README.md @@ -0,0 +1,4 @@ +# VBB-Live-Maps +VBB Live Maps ist eine interaktive Live-Karte, die Fahrzeuge des Berliner Nahverkehrs (z. B. Busse, U-Bahnen, S-Bahnen etc.) in Echtzeit anzeigt. + +https://vbb-live-maps.netlify.app/ diff --git a/old/VBB-Live-Maps-BG/app.js b/old/VBB-Live-Maps-BG/app.js new file mode 100644 index 0000000..31fc441 --- /dev/null +++ b/old/VBB-Live-Maps-BG/app.js @@ -0,0 +1,224 @@ +// ============================= +// Karte initialisieren +// ============================= +const map = L.map('map', { zoomControl: false }).setView([52.52, 13.405], 13); + +L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + maxZoom: 19, + attribution: '© OpenStreetMap contributors' +}).addTo(map); + + +const vehiclesLayer = L.layerGroup().addTo(map); +const vehicleMarkers = {}; + +const lineColors = { + 'S45': '#CD9C53', 'S46': '#CD9C53', 'S47': '#CD9C53', 'S6': '#CD9C53', 'S65': '#CD9C53', 'S66': '#CD9C53', + 'S42': '#CB6418', + 'S4': '#AD5937', 'S41': '#AD5937', + 'U5': '#7E5330', 'U55': '#7E5330', + 'S9': '#992746', 'S95': '#992746', 'S96': '#992746', + 'U12': ['#7DAD4C', '#DA421E'], + 'U2': '#DA421E', + 'S3': '#EB7405', 'S5': '#EB7405', 'S55': '#EB7405', 'S56': '#EB7405', + 'U9': '#F3791D', + 'S3-wannsee': '#F0D722', 'U4': '#F0D722', + 'U1': '#7DAD4C', 'U15': '#7DAD4C', + 'S8': '#66AA22', 'S85': '#66AA22', 'S86': '#66AA22', + 'S2': '#007734', 'S21': '#007734', 'S25': '#007734', 'S26': '#007734', + 'U3': '#16683D', 'U35': '#16683D', + 'S3-charlottenburg': '#009BD5', 'U7': '#009BD5', + 'S10': '#0082C4', 'S19': '#0082C4', + 'S3-berlin-schoenefeld': '#0066AD', 'S35': '#0066AD', 'S36': '#0066AD', + 'U8': '#224F86', + 'S7': '#816DA6', 'S75': '#816DA6', 'S76': '#816DA6', + 'U6': '#8C6DAB', + 'S1': '#DA6BA2', 'S15': '#DA6BA2', 'S16': '#DA6BA2', 'U0': '#DA6BA2', + 'U10': '#808080', 'U11': '#808080', + 'F10': '#528DBA', + 'F11': '#528DBA', + 'F12': '#528DBA', + 'F21': '#528DBA', + 'F23': '#528DBA', + 'F24': '#528DBA' +}; + +const symbols = { + bus: '🚌', + tram: '🚎', + subway: '🚉', + suburban: '🚋', + regional: '🚆', + express: '🚄', + longDistance: '🚅', + ferry: '🛥️' +}; + +function getLineColor(lineName, product) { + if(lineName === 'U12') return null; + + if(lineName.startsWith('S3 ')) { + if(lineName.toLowerCase().includes('wannsee')) return lineColors['S3-wannsee']; + if(lineName.toLowerCase().includes('charlottenburg') || lineName.toLowerCase().includes('schönefeld')) return lineColors['S3-berlin-schoenefeld']; + return lineColors['S3']; + } + + if(lineColors[lineName]) return lineColors[lineName]; + if(product === 'suburban') return '#CD9C53'; + if(product === 'subway') return '#7DAD4C'; + return '#666'; +} + +function createDivIcon(vehicle) { + const product = vehicle.line?.product; + const lineName = vehicle.line?.name || '?'; + const symbol = symbols[product] || '❓'; + + if(lineName === 'U12') { + const iconHtml = ` +
+ + + + + + + + + + + +
+ ${symbol} +
+
+ U12 +
+
+ `; + return L.divIcon({ + html: iconHtml, + className: '', + iconSize: [30, 40], + iconAnchor: [15, 20] + }); + } + + const lineColor = getLineColor(lineName, product); + const labelStyle = `background: ${lineColor}; color: white; padding: 2px 6px; border-radius: 3px; display: inline-block; font-weight: bold; font-size: 12px; user-select: none; font-family: Arial, sans-serif;`; + + const iconHtml = ` +
+
${symbol}
+
${lineName}
+
+ `; + + return L.divIcon({ + html: iconHtml, + className: '', + iconSize: [30, 40], + iconAnchor: [15, 20] + }); +} + +async function loadVehicles() { + const bounds = map.getBounds(); + const bbox = `north=${bounds.getNorth()}&west=${bounds.getWest()}&south=${bounds.getSouth()}&east=${bounds.getEast()}`; + + try { + const res = await fetch(`https://v6.vbb.transport.rest/radar?${bbox}&results=200&duration=30`); + const result = await res.json(); + const data = result.movements || []; + + const newIds = new Set(); + + data.forEach(vehicle => { + const id = vehicle.tripId; + const loc = vehicle.location; + if (!loc || !loc.latitude || !loc.longitude) return; + + newIds.add(id); + const icon = createDivIcon(vehicle); + + if (vehicleMarkers[id]) { + vehicleMarkers[id].setLatLng([loc.latitude, loc.longitude]); + } else { + const marker = L.marker([loc.latitude, loc.longitude], { icon }) + .bindPopup(` + Linie: ${vehicle.line?.name || 'unbekannt'}
+ Typ: ${vehicle.line?.product || 'unbekannt'}
+ Richtung: ${vehicle.direction || 'unbekannt'} + `) + .addTo(vehiclesLayer); + vehicleMarkers[id] = marker; + } + }); + + Object.keys(vehicleMarkers).forEach(id => { + if (!newIds.has(id)) { + vehiclesLayer.removeLayer(vehicleMarkers[id]); + delete vehicleMarkers[id]; + } + }); + } catch (e) { + console.error('Fehler beim Laden der Fahrzeuge:', e); + } +} + +function locateAndLoad() { + if (!navigator.geolocation) { + alert('Geolocation nicht unterstützt'); + loadVehicles(); + return; + } + navigator.geolocation.getCurrentPosition(pos => { + const { latitude, longitude } = pos.coords; + map.setView([latitude, longitude], 14); + + const locationIcon = L.divIcon({ + className: 'user-location-icon', + iconSize: [12, 12], + iconAnchor: [6, 6] + }); + + L.marker([latitude, longitude], { icon: locationIcon }).addTo(map); + loadVehicles(); + }, () => { + map.setView([52.52, 13.405], 13); + loadVehicles(); + }); +} + +locateAndLoad(); +setInterval(loadVehicles, 610); +map.on('moveend', loadVehicles); + +// ==================== +// Uhr unten rechts +// ==================== +const ssTimeEl = document.getElementById('ss-time'); +const ssDateEl = document.getElementById('ss-date'); + +function updateClock() { + const now = new Date(); + ssTimeEl.textContent = now.toLocaleTimeString('de-DE', { hour12: false }); + ssDateEl.textContent = now.toLocaleDateString('de-DE', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: '2-digit' + }); +} + +updateClock(); +setInterval(updateClock, 1000); + + + + + + + + + diff --git a/old/VBB-Live-Maps-BG/index.html b/old/VBB-Live-Maps-BG/index.html new file mode 100644 index 0000000..5e7fd13 --- /dev/null +++ b/old/VBB-Live-Maps-BG/index.html @@ -0,0 +1,23 @@ + + + + + + VBB Live Tracker + + + + + +
+ + +
+
--:--:--
+
----
+
+ + + + + diff --git a/old/VBB-Live-Maps-BG/style.css b/old/VBB-Live-Maps-BG/style.css new file mode 100644 index 0000000..e85d1cd --- /dev/null +++ b/old/VBB-Live-Maps-BG/style.css @@ -0,0 +1,69 @@ +/* ==================== */ +/* Grundlayout */ +/* ==================== */ +html, body, #map { + height: 100%; + margin: 0; + padding: 0; +} + +.leaflet-marker-icon { + transition: transform 1s linear; +} + +.line-label { + padding: 2px 6px; + border-radius: 3px; + font-weight: bold; + font-size: 10px; + display: inline-block; + color: white; + margin-top: 2px; + user-select: none; + font-family: Arial, sans-serif; +} + +.user-location-icon { + background-color: #007bff; + border: 2px solid white; + border-radius: 50%; + width: 12px; + height: 12px; + box-shadow: 0 0 6px rgba(0, 123, 255, 0.6); +} + +/* ==================== */ +/* Uhr unten rechts */ +/* ==================== */ +#clock { + position: fixed; + right: 40px; + bottom: 40px; + z-index: 9999; + text-align: right; + font-family: "Comic Sans MS", Comic Sans, cursive; /* Comic Sans einfügen */ + color: #ffffff; + text-shadow: 0 0 8px rgba(0,0,0,0.7); + user-select: none; + + /* Hintergrund-Box */ + background: rgba(0, 0, 0, 0.6); + padding: 16px 24px; + border-radius: 12px; + backdrop-filter: blur(4px); + +} + + +#clock .time { + font-size: clamp(42px, 6vw, 72px); + line-height: 1.1; + font-weight: 700; +} + +#clock .date { + font-size: clamp(18px, 3vw, 28px); + line-height: 1.2; + opacity: 0.9; +} + diff --git a/old/app.js b/old/app.js new file mode 100644 index 0000000..55221f0 --- /dev/null +++ b/old/app.js @@ -0,0 +1,225 @@ +// ============================= +// Karte initialisieren +// ============================= +const map = L.map('map').setView([52.52, 13.405], 13); + +L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + maxZoom: 19, + attribution: '© OpenStreetMap contributors' +}).addTo(map); + +// Layer für Fahrzeuge +const vehiclesLayer = L.layerGroup().addTo(map); +const vehicleMarkers = {}; + +// ============================= +// Farben & Symbole +// ============================= +const lineColors = { + 'S45': '#CD9C53', 'S46': '#CD9C53', 'S47': '#CD9C53', 'S6': '#CD9C53', 'S65': '#CD9C53', 'S66': '#CD9C53', + 'S42': '#CB6418', 'S4': '#AD5937', 'S41': '#AD5937', 'U5': '#7E5330', 'U55': '#7E5330', + 'S9': '#992746', 'S95': '#992746', 'S96': '#992746', 'U12': ['#7DAD4C', '#DA421E'], 'U2': '#DA421E', + 'S3': '#EB7405', 'S5': '#EB7405', 'S55': '#EB7405', 'S56': '#EB7405', 'U9': '#F3791D', + 'S3-wannsee': '#F0D722', 'U4': '#F0D722', 'U1': '#7DAD4C', 'U15': '#7DAD4C', + 'S8': '#66AA22', 'S85': '#66AA22', 'S86': '#66AA22', 'S2': '#007734', 'S21': '#007734', + 'S25': '#007734', 'S26': '#007734', 'U3': '#16683D', 'U35': '#16683D', + 'S3-charlottenburg': '#009BD5', 'U7': '#009BD5', 'S10': '#0082C4', 'S19': '#0082C4', + 'S3-berlin-schoenefeld': '#0066AD', 'S35': '#0066AD', 'S36': '#0066AD', 'U8': '#224F86', + 'S7': '#816DA6', 'S75': '#816DA6', 'S76': '#816DA6', 'U6': '#8C6DAB', + 'S1': '#DA6BA2', 'S15': '#DA6BA2', 'S16': '#DA6BA2', 'U0': '#DA6BA2', + 'U10': '#808080', 'U11': '#808080', 'F10': '#528DBA', 'F11': '#528DBA', + 'F12': '#528DBA', 'F21': '#528DBA', 'F23': '#528DBA', 'F24': '#528DBA' +}; + +const symbols = { + bus: '🚌', tram: '🚎', subway: '🚉', suburban: '🚋', + regional: '🚆', express: '🚄', longDistance: '🚅', ferry: '🛥️' +}; + +// ============================= +// Hilfsfunktionen +// ============================= +function getLineColor(lineName, product) { + if(lineName === 'U12') return null; + if(lineName.startsWith('S3 ')) { + if(lineName.toLowerCase().includes('wannsee')) return lineColors['S3-wannsee']; + if(lineName.toLowerCase().includes('charlottenburg') || lineName.toLowerCase().includes('schönefeld')) return lineColors['S3-berlin-schoenefeld']; + return lineColors['S3']; + } + if(lineColors[lineName]) return lineColors[lineName]; + if(product === 'suburban') return '#CD9C53'; + if(product === 'subway') return '#7DAD4C'; + return '#666'; +} + +function createDivIcon(vehicle) { + const product = vehicle.line?.product; + const lineName = vehicle.line?.name || '?'; + const symbol = symbols[product] || '❓'; + + if(lineName === 'U12') { + const iconHtml = ` +
+ + + + + + + + + + + +
+ ${symbol} +
+
+ U12 +
+
+ `; + return L.divIcon({ html: iconHtml, className: '', iconSize: [30, 40], iconAnchor: [15, 20] }); + } + + const lineColor = getLineColor(lineName, product); + const labelStyle = `background: ${lineColor}; color: white; padding: 2px 6px; border-radius: 3px; display: inline-block; font-weight: bold; font-size: 12px; user-select: none; font-family: Arial, sans-serif;`; + + const iconHtml = ` +
+
${symbol}
+
${lineName}
+
+ `; + + return L.divIcon({ html: iconHtml, className: '', iconSize: [30, 40], iconAnchor: [15, 20] }); +} + +// ============================= +// Fahrzeuge laden +// ============================= +async function loadVehicles() { + const bounds = map.getBounds(); + const bbox = `north=${bounds.getNorth()}&west=${bounds.getWest()}&south=${bounds.getSouth()}&east=${bounds.getEast()}`; + + try { + const res = await fetch(`https://v6.vbb.transport.rest/radar?${bbox}&results=100&duration=30`); + const result = await res.json(); + const data = result.movements || []; + + const newIds = new Set(); + + data.forEach(vehicle => { + const id = vehicle.tripId; + const loc = vehicle.location; + if (!loc || !loc.latitude || !loc.longitude) return; + + newIds.add(id); + const icon = createDivIcon(vehicle); + + if (vehicleMarkers[id]) { + vehicleMarkers[id].setLatLng([loc.latitude, loc.longitude]); + } else { + const marker = L.marker([loc.latitude, loc.longitude], { icon }) + .bindPopup(`Linie: ${vehicle.line?.name || 'unbekannt'}
Typ: ${vehicle.line?.product || 'unbekannt'}
Richtung: ${vehicle.direction || 'unbekannt'}`) + .addTo(vehiclesLayer); + vehicleMarkers[id] = marker; + } + }); + + Object.keys(vehicleMarkers).forEach(id => { + if (!newIds.has(id)) { + vehiclesLayer.removeLayer(vehicleMarkers[id]); + delete vehicleMarkers[id]; + } + }); + } catch (e) { + console.error('Fehler beim Laden der Fahrzeuge:', e); + } +} + +// ============================= +// Geolocation & Auto-Update +// ============================= +function locateAndLoad() { + if (!navigator.geolocation) { + loadVehicles(); + return; + } + navigator.geolocation.getCurrentPosition(pos => { + map.setView([pos.coords.latitude, pos.coords.longitude], 14); + loadVehicles(); + }, () => { + loadVehicles(); + }); +} + +locateAndLoad(); +setInterval(loadVehicles, 30000); +map.on('moveend', loadVehicles); + +// ============================= +// Bahnhöfe mit Live-Abfahrten +// ============================= +const stations = [ + { name: "Berlin Zoologischer Garten", id: "900023201", coords: [52.5069, 13.3326] }, + { name: "Berlin Alexanderplatz", id: "900100003", coords: [52.5215, 13.4115] }, + { name: "Berlin Gesundbrunnen", id: "900007102", coords: [52.5483, 13.3889] }, + { name: "Berlin Spandau", id: "900029101", coords: [52.5341, 13.1977] }, + { name: "Berlin Südkreuz", id: "900058101", coords: [52.4752, 13.3653] }, + { name: "Berlin Ostbahnhof", id: "900100004", coords: [52.5100, 13.4340] } +]; + +async function loadStationDepartures(stationId, marker, stationName) { + const symbols = { + bus: '🚌', tram: '🚎', subway: '🚉', suburban: '🚋', + regional: '🚆', express: '🚄', longDistance: '🚅', ferry: '🛥️' + }; + + try { + const res = await fetch(`https://v6.vbb.transport.rest/stops/${stationId}/departures?duration=30&results=10`); + if (!res.ok) throw new Error(`HTTP ${res.status}`); + const data = await res.json(); + const departures = data.departures || []; + + let html = `${stationName}
`; + html += ``; + html += ``; + + departures.forEach((dep, index) => { + const line = dep.line?.name || "?"; + const product = dep.line?.product; + const icon = symbols[product] || '❓'; + const direction = dep.direction || "?"; + const when = dep.when ? new Date(dep.when) : null; + const planned = dep.plannedWhen ? new Date(dep.plannedWhen) : null; + const delay = when && planned ? Math.round((when - planned) / 60000) : 0; + const timeStr = when ? when.toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" }) : "n/a"; + const delayStr = delay > 0 ? `+${delay} min` : ""; + + const color = getLineColor(line, product); + const bg = index % 2 === 0 ? '#f9f9f9' : '#fff'; + + html += ` + + + + `; + }); + + html += `
LinieRichtungZeit
${icon} ${line}${direction}${timeStr} ${delayStr}
`; + marker.setPopupContent(html).openPopup(); + } catch (err) { + marker.setPopupContent(`${stationName}
Fehler beim Laden`); + console.error(err); + } +} + + +stations.forEach(station => { + const marker = L.marker(station.coords) + .addTo(map) + .bindPopup(`${station.name}
Lade Abfahrten...`); + + marker.on('click', () => loadStationDepartures(station.id, marker, station.name)); +}); diff --git a/old/app.js.backup b/old/app.js.backup new file mode 100644 index 0000000..b095f3c --- /dev/null +++ b/old/app.js.backup @@ -0,0 +1,192 @@ +const map = L.map('map').setView([52.52, 13.405], 13); + +L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + maxZoom: 19, + attribution: '© OpenStreetMap contributors' +}).addTo(map); + +const vehiclesLayer = L.layerGroup().addTo(map); +const vehicleMarkers = {}; + +const lineColors = { + 'S45': '#CD9C53', 'S46': '#CD9C53', 'S47': '#CD9C53', 'S6': '#CD9C53', 'S65': '#CD9C53', 'S66': '#CD9C53', + 'S42': '#CB6418', + 'S4': '#AD5937', 'S41': '#AD5937', + 'U5': '#7E5330', 'U55': '#7E5330', + 'S9': '#992746', 'S95': '#992746', 'S96': '#992746', + 'U12': ['#7DAD4C', '#DA421E'], + 'U2': '#DA421E', + 'S3': '#EB7405', 'S5': '#EB7405', 'S55': '#EB7405', 'S56': '#EB7405', + 'U9': '#F3791D', + 'S3-wannsee': '#F0D722', 'U4': '#F0D722', + 'U1': '#7DAD4C', 'U15': '#7DAD4C', + 'S8': '#66AA22', 'S85': '#66AA22', 'S86': '#66AA22', + 'S2': '#007734', 'S21': '#007734', 'S25': '#007734', 'S26': '#007734', + 'U3': '#16683D', 'U35': '#16683D', + 'S3-charlottenburg': '#009BD5', 'U7': '#009BD5', + 'S10': '#0082C4', 'S19': '#0082C4', + 'S3-berlin-schoenefeld': '#0066AD', 'S35': '#0066AD', 'S36': '#0066AD', + 'U8': '#224F86', + 'S7': '#816DA6', 'S75': '#816DA6', 'S76': '#816DA6', + 'U6': '#8C6DAB', + 'S1': '#DA6BA2', 'S15': '#DA6BA2', 'S16': '#DA6BA2', 'U0': '#DA6BA2', + 'U10': '#808080', 'U11': '#808080', + 'F10': '#528DBA', + 'F11': '#528DBA', + 'F12': '#528DBA', + 'F21': '#528DBA', + 'F23': '#528DBA', + 'F24': '#528DBA' +}; + +const symbols = { + bus: '🚌', + tram: '🚎', + subway: '🚉', + suburban: '🚋', + regional: '🚆', + express: '🚄', + longDistance: '🚅', + ferry: '🛥️' +}; + +function getLineColor(lineName, product) { + if(lineName === 'U12') return null; + + if(lineName.startsWith('S3 ')) { + if(lineName.toLowerCase().includes('wannsee')) return lineColors['S3-wannsee']; + if(lineName.toLowerCase().includes('charlottenburg') || lineName.toLowerCase().includes('schönefeld')) return lineColors['S3-berlin-schoenefeld']; + return lineColors['S3']; + } + + if(lineColors[lineName]) return lineColors[lineName]; + if(product === 'suburban') return '#CD9C53'; + if(product === 'subway') return '#7DAD4C'; + return '#666'; +} + +function createDivIcon(vehicle) { + const product = vehicle.line?.product; + const lineName = vehicle.line?.name || '?'; + const symbol = symbols[product] || '❓'; + + if(lineName === 'U12') { + const iconHtml = ` +
+ + + + + + + + + + + +
+ ${symbol} +
+
+ U12 +
+
+ `; + return L.divIcon({ + html: iconHtml, + className: '', + iconSize: [30, 40], + iconAnchor: [15, 20] + }); + } + + const lineColor = getLineColor(lineName, product); + const labelStyle = `background: ${lineColor}; color: white; padding: 2px 6px; border-radius: 3px; display: inline-block; font-weight: bold; font-size: 12px; user-select: none; font-family: Arial, sans-serif;`; + + const iconHtml = ` +
+
${symbol}
+
${lineName}
+
+ `; + + return L.divIcon({ + html: iconHtml, + className: '', + iconSize: [30, 40], + iconAnchor: [15, 20] + }); +} + +async function loadVehicles() { + const bounds = map.getBounds(); + const bbox = `north=${bounds.getNorth()}&west=${bounds.getWest()}&south=${bounds.getSouth()}&east=${bounds.getEast()}`; + + try { + const res = await fetch(`https://v6.vbb.transport.rest/radar?${bbox}&results=100&duration=30`); + const result = await res.json(); + const data = result.movements || []; + + const newIds = new Set(); + + data.forEach(vehicle => { + const id = vehicle.tripId; + const loc = vehicle.location; + if (!loc || !loc.latitude || !loc.longitude) return; + + newIds.add(id); + const icon = createDivIcon(vehicle); + + if (vehicleMarkers[id]) { + vehicleMarkers[id].setLatLng([loc.latitude, loc.longitude]); + } else { + const marker = L.marker([loc.latitude, loc.longitude], { icon }) + .bindPopup(` + Linie: ${vehicle.line?.name || 'unbekannt'}
+ Typ: ${vehicle.line?.product || 'unbekannt'}
+ Richtung: ${vehicle.direction || 'unbekannt'} + `) + .addTo(vehiclesLayer); + vehicleMarkers[id] = marker; + } + }); + + Object.keys(vehicleMarkers).forEach(id => { + if (!newIds.has(id)) { + vehiclesLayer.removeLayer(vehicleMarkers[id]); + delete vehicleMarkers[id]; + } + }); + } catch (e) { + console.error('Fehler beim Laden der Fahrzeuge:', e); + } +} + +function locateAndLoad() { + if (!navigator.geolocation) { + alert('Geolocation nicht unterstützt'); + loadVehicles(); + return; + } + navigator.geolocation.getCurrentPosition(pos => { + const { latitude, longitude } = pos.coords; + map.setView([latitude, longitude], 14); + + const locationIcon = L.divIcon({ + className: 'user-location-icon', + iconSize: [12, 12], + iconAnchor: [6, 6] + }); + + L.marker([latitude, longitude], { icon: locationIcon }).addTo(map); + loadVehicles(); + }, () => { + map.setView([52.52, 13.405], 13); + loadVehicles(); + }); +} + +locateAndLoad(); +setInterval(loadVehicles, 610); +map.on('moveend', loadVehicles); + diff --git a/old/index.html b/old/index.html new file mode 100644 index 0000000..8dcc62a --- /dev/null +++ b/old/index.html @@ -0,0 +1,25 @@ + + + + + + VBB Live Tracker + + + + +
+ + + + + + + +
+
+ + + + + diff --git a/old/style.css b/old/style.css new file mode 100644 index 0000000..030147b --- /dev/null +++ b/old/style.css @@ -0,0 +1,43 @@ +html, body, #map { + height: 100%; + margin: 0; + padding: 0; +} + +#controls { + position: absolute; + top: 10px; + right: 10px; + background: rgba(255,255,255,0.9); + padding: 8px 12px; + border-radius: 5px; + z-index: 1000; + font-family: Arial, sans-serif; + display: flex; + flex-wrap: wrap; /* wenn zu viele, umbrechen */ + gap: 8px; +} + +#controls label { + display: flex; + align-items: center; + gap: 4px; + font-size: 12px; + cursor: pointer; +} + +.leaflet-marker-icon { + transition: transform 1s linear; +} + +.line-label { + padding: 2px 6px; + border-radius: 3px; + font-weight: bold; + font-size: 10px; + display: inline-block; + color: white; + margin-top: 2px; + user-select: none; + font-family: Arial, sans-serif; +}