From 03fd0c045236caa113938d8fa7b72848e811c97e Mon Sep 17 00:00:00 2001 From: Liam Clark Date: Wed, 21 Jan 2026 15:16:11 +0100 Subject: [PATCH 1/2] Add route display from firehouse to active alarms Integrated Leaflet Routing Machine (OSRM) to visualize routes from the firehouse to each active alarm location on the map, excluding alarms at the firehouse itself. Updated dependencies in monitor.html and added route management logic in map.js, including route clearing and creation functions. --- monitor.html | 2 ++ src/js/map.js | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/monitor.html b/monitor.html index 0cd394a..65de06d 100644 --- a/monitor.html +++ b/monitor.html @@ -16,6 +16,7 @@ crossorigin=""/> + @@ -135,6 +136,7 @@

integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""> + diff --git a/src/js/map.js b/src/js/map.js index 0fceb1a..2d91129 100644 --- a/src/js/map.js +++ b/src/js/map.js @@ -123,6 +123,8 @@ let updateDebounceTimer = null; let firehouseCoords = null; let autoZoomEnabled = true; let lastBoundsKey = null; +let routingControl = null; +const routeLines = []; function getTooltipDirection(markerLatlng) { // Get available directions to position tooltip (top, left, right) @@ -149,6 +151,53 @@ function clearEinsatzMarkers() { einsatzMarkers.length = 0; } +function clearRoutes() { + routeLines.forEach(route => { + if (route && map.hasLayer(route)) { + map.removeLayer(route); + } + }); + routeLines.length = 0; +} + +function createRoute(fromCoords, toCoords, einsatzType) { + // Create a routing control without the UI panel + const waypoints = [ + L.latLng(fromCoords.lat, fromCoords.lon), + L.latLng(toCoords.lat, toCoords.lon) + ]; + + const router = L.Routing.control({ + waypoints: waypoints, + router: L.Routing.osrmv1({ + serviceUrl: 'https://router.project-osrm.org/route/v1', + profile: 'driving' + }), + lineOptions: { + styles: [ + { color: '#ff0000', opacity: 0.8, weight: 4 } + ], + addWaypoints: false + }, + show: false, + addWaypoints: false, + routeWhileDragging: false, + draggableWaypoints: false, + fitSelectedRoutes: false, + showAlternatives: false, + createMarker: function() { return null; } // Don't create waypoint markers + }).addTo(map); + + // Hide the routing instructions panel + const container = router.getContainer(); + if (container) { + container.style.display = 'none'; + } + + routeLines.push(router); + return router; +} + function pickDisplayedEinsätze(einsaetze) { const eligible = Array.isArray(einsaetze) ? einsaetze : []; @@ -167,6 +216,7 @@ function pickDisplayedEinsätze(einsaetze) { async function updateEinsatzMarkers(einsaetze) { clearEinsatzMarkers(); + clearRoutes(); const displayed = pickDisplayedEinsätze(einsaetze); const currentAddresses = displayed.map(e => (e.location || '').trim()); @@ -200,6 +250,18 @@ async function updateEinsatzMarkers(einsaetze) { marker.bindPopup(`${einsatz.type || 'Einsatz'}
${einsatz.description || ''}
${einsatz.location || ''}`, { maxWidth: 200, maxHeight: 150 }); markerClusterGroup.addLayer(marker); einsatzMarkers.push(marker); + + // Create route from firehouse to alarm location (only for active alarms) + const isActive = (einsatz.status || '').toLowerCase() !== 'completed'; + const firehouseForRoute = firehouseCoords || FIREHOUSE_FALLBACK_COORDS; + if (isActive && firehouseForRoute && coords) { + // Don't create route if alarm is at the firehouse + const locationText = (einsatz.location || '').toLowerCase(); + const isFirehouseLocation = Geo.isFirehouseLocation(locationText); + if (!isFirehouseLocation) { + createRoute(firehouseForRoute, coords, einsatz.type); + } + } }); // Zoom to fit all displayed markers + firehouse, or reset to default if none From 14c1622b1842322248fad79d9e99124d83a04af0 Mon Sep 17 00:00:00 2001 From: Liam Clark Date: Wed, 21 Jan 2026 15:32:41 +0100 Subject: [PATCH 2/2] Update src/js/map.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/js/map.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/map.js b/src/js/map.js index 2d91129..28a9bbc 100644 --- a/src/js/map.js +++ b/src/js/map.js @@ -254,7 +254,7 @@ async function updateEinsatzMarkers(einsaetze) { // Create route from firehouse to alarm location (only for active alarms) const isActive = (einsatz.status || '').toLowerCase() !== 'completed'; const firehouseForRoute = firehouseCoords || FIREHOUSE_FALLBACK_COORDS; - if (isActive && firehouseForRoute && coords) { + if (isActive && firehouseForRoute) { // Don't create route if alarm is at the firehouse const locationText = (einsatz.location || '').toLowerCase(); const isFirehouseLocation = Geo.isFirehouseLocation(locationText);