Spaces:
Running on Zero
Running on Zero
| """Dark Bay Area map (Leaflet) with glow-orange markers for the transit mode.""" | |
| from __future__ import annotations | |
| import base64 | |
| import json | |
| _TEMPLATE = r"""<!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"/> | |
| <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/> | |
| <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> | |
| <style> | |
| html,body{margin:0;height:100%;background:#000;font-family:'Courier New',monospace;} | |
| #map{width:100%;height:100%;background:#000;} | |
| .leaflet-container{background:#000;} | |
| #hud{position:absolute;z-index:500;top:10px;left:12px;color:#FF9A1E; | |
| text-shadow:0 0 8px #FF7A00;font-size:12px;letter-spacing:1px; | |
| pointer-events:none;line-height:1.5;} | |
| .lbl{color:#FFB347;text-shadow:0 0 6px #FF7A00;font-size:11px;} | |
| </style> | |
| </head> | |
| <body> | |
| <div id="map"></div> | |
| <div id="hud">>> BAYLINE // 511 LIVE<br/><span id="sub"></span></div> | |
| <script> | |
| const DATA = /*__DATA__*/; | |
| const map = L.map('map', {zoomControl:true, attributionControl:false}) | |
| .setView([37.77,-122.30], 10); | |
| L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', | |
| {maxZoom:19}).addTo(map); | |
| const COLORS = {origin:'#FF9A1E', dest:'#19E0FF', incident:'#FF3B3B'}; | |
| // Dotted pathway between origin and destination (when both are present). | |
| const _o = (DATA.markers||[]).find(m => m.kind === 'origin'); | |
| const _d = (DATA.markers||[]).find(m => m.kind === 'dest'); | |
| if (_o && _d) { | |
| L.polyline([[_o.lat,_o.lon],[_d.lat,_d.lon]], { | |
| color:'#FF9A1E', weight:3, opacity:0.95, dashArray:'2,9', lineCap:'round' | |
| }).addTo(map); | |
| } | |
| const pts = []; | |
| (DATA.markers||[]).forEach(m => { | |
| const c = COLORS[m.kind] || '#FFB347'; | |
| const mk = L.circleMarker([m.lat, m.lon], { | |
| radius: m.kind==='incident'?6:9, color:c, weight:2, | |
| fillColor:c, fillOpacity:0.65 | |
| }).addTo(map); | |
| mk.bindTooltip(m.label||'', {className:'lbl'}); | |
| // glow ring | |
| L.circleMarker([m.lat,m.lon],{radius:(m.kind==='incident'?12:16),color:c, | |
| weight:1,opacity:0.35,fill:false}).addTo(map); | |
| pts.push([m.lat,m.lon]); | |
| }); | |
| if (pts.length===1){ map.setView(pts[0], 12); } | |
| else if (pts.length>1){ map.fitBounds(pts, {padding:[40,40]}); } | |
| document.getElementById('sub').textContent = DATA.stamp || ''; | |
| </script> | |
| </body> | |
| </html>""" | |
| def build_map_html(markers, stamp: str = "") -> str: | |
| data = {"markers": markers or [], "stamp": stamp} | |
| html = _TEMPLATE.replace("/*__DATA__*/", json.dumps(data)) | |
| b64 = base64.b64encode(html.encode("utf-8")).decode("ascii") | |
| return ( | |
| f'<iframe src="data:text/html;base64,{b64}" ' | |
| 'style="width:100%;height:560px;border:0;border-radius:10px;' | |
| 'box-shadow:0 0 24px #ff7a0055, inset 0 0 40px #00000080;"></iframe>' | |
| ) | |