export const RoverMap = { mounted() { this.stations = [] this.stops = [] this.stationMarkers = L.layerGroup() this.stopMarkers = L.layerGroup() this.routeLine = null this.terrainLines = L.layerGroup() const map = L.map(this.el, { center: [33.2, -97.1], zoom: 7, zoomControl: true, attributionControl: false }) L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { maxZoom: 19 }).addTo(map) this.map = map this.stationMarkers.addTo(map) this.stopMarkers.addTo(map) this.terrainLines.addTo(map) // Draw Maidenhead grid overlay this.drawGridOverlay() // Click to add stop map.on("click", (e) => { this.pushEvent("add_stop", { lat: e.latlng.lat, lon: e.latlng.lng }) }) // Handle server events this.handleEvent("stations_updated", ({ stations }) => { this.stations = stations this.renderStations() }) this.handleEvent("stops_updated", ({ stops }) => { this.stops = stops this.renderStops() }) this.handleEvent("stop_terrain", ({ index, reachable }) => { this.renderTerrainLines(index, reachable) }) }, renderStations() { this.stationMarkers.clearLayers() for (const s of this.stations) { const marker = L.circleMarker([s.lat, s.lon], { radius: 7, color: "#fff", weight: 2, fillColor: "#3b82f6", fillOpacity: 0.9, interactive: true }) marker.bindTooltip(s.label, { permanent: true, direction: "top", offset: [0, -10], className: "station-label" }) this.stationMarkers.addLayer(marker) } this.fitBounds() }, renderStops() { this.stopMarkers.clearLayers() this.terrainLines.clearLayers() if (this.routeLine) { this.map.removeLayer(this.routeLine) this.routeLine = null } const routeCoords = [] for (const stop of this.stops) { routeCoords.push([stop.lat, stop.lon]) const color = stop.score >= 65 ? "#00ffa3" : stop.score >= 50 ? "#ffe566" : stop.score >= 33 ? "#ff9044" : "#ff4f4f" const marker = L.circleMarker([stop.lat, stop.lon], { radius: 10, color: "#fff", weight: 3, fillColor: color, fillOpacity: 0.9, interactive: true }) // Number label const icon = L.divIcon({ html: `