From d95af37be50324d95724d827380e83d9ac58222c Mon Sep 17 00:00:00 2001 From: Anton Roslund Date: Fri, 27 Jun 2025 11:15:52 +0200 Subject: [PATCH] Add backbone layers --- .../migration.sql | 2 + prisma/schema.prisma | 1 + src/public/index.html | 47 +++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 prisma/migrations/20250627090409_add_node_is_backbone/migration.sql diff --git a/prisma/migrations/20250627090409_add_node_is_backbone/migration.sql b/prisma/migrations/20250627090409_add_node_is_backbone/migration.sql new file mode 100644 index 0000000..e449774 --- /dev/null +++ b/prisma/migrations/20250627090409_add_node_is_backbone/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE `nodes` ADD COLUMN `is_backbone` BOOLEAN NULL; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 012e3f4..0344e71 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -52,6 +52,7 @@ model Node { mqtt_connection_state_updated_at DateTime? ok_to_mqtt Boolean? + is_backbone Boolean? created_at DateTime @default(now()) updated_at DateTime @default(now()) @updatedAt diff --git a/src/public/index.html b/src/public/index.html index afdca8c..541c298 100644 --- a/src/public/index.html +++ b/src/public/index.html @@ -2656,6 +2656,7 @@ // create layer groups var nodesLayerGroup = new L.LayerGroup(); var neighboursLayerGroup = new L.LayerGroup(); + var backboneNeighboursLayerGroup = new L.LayerGroup(); var nodeNeighboursLayerGroup = new L.LayerGroup(); var nodesClusteredLayerGroup = L.markerClusterGroup({ showCoverageOnHover: false, @@ -2665,6 +2666,7 @@ showCoverageOnHover: false, disableClusteringAtZoom: 10, // zoom level where node clustering is disabled }); + var nodesBackboneLayerGroup = new L.LayerGroup(); var waypointsLayerGroup = new L.LayerGroup(); var nodePositionHistoryLayerGroup = new L.LayerGroup(); @@ -2724,12 +2726,14 @@ "Nodes": { "All": nodesLayerGroup, "Routers": nodesRouterLayerGroup, + "Backbone": nodesBackboneLayerGroup, "Clustered": nodesClusteredLayerGroup, "None": new L.LayerGroup(), }, "Overlays": { "Legend": legendLayerGroup, "Neighbours": neighboursLayerGroup, + "Backbone Connection": backboneNeighboursLayerGroup, "Waypoints": waypointsLayerGroup, "Position History": nodePositionHistoryLayerGroup, }, @@ -2749,6 +2753,9 @@ if(enabledOverlayLayers.includes("Neighbours")){ neighboursLayerGroup.addTo(map); } + if(enabledOverlayLayers.includes("Backbone Connection")){ + backboneNeighboursLayerGroup.addTo(map); + } if(enabledOverlayLayers.includes("Waypoints")){ waypointsLayerGroup.addTo(map); } @@ -2894,10 +2901,12 @@ nodesLayerGroup.clearLayers(); nodesClusteredLayerGroup.clearLayers(); nodesRouterLayerGroup.clearLayers(); + nodesBackboneLayerGroup.clearLayers(); } function clearAllNeighbours() { neighboursLayerGroup.clearLayers(); + backboneNeighboursLayerGroup.clearLayers(); } function clearAllWaypoints() { @@ -3369,6 +3378,11 @@ nodesRouterLayerGroup.addLayer(marker); } + // add markers for backbone to layer group + if(node.is_backbone) { + nodesBackboneLayerGroup.addLayer(marker); + } + // show tooltip on desktop only if(!isMobile()){ marker.bindTooltip(getTooltipContentForNode(node), { @@ -3453,6 +3467,28 @@ offset: symmetrical ? 3 : 0, }).addTo(neighboursLayerGroup); + // additional line for backbone neighbours + const backboneNeighbourLine = L.polyline([ + currentNode.getLatLng(), + neighbourNodeMarker.getLatLng(), + ], { + color: getColourForSnr(neighbour.snr), + opacity: 0.75, + offset: symmetrical ? 3 : 0, + }).arrowheads({ + size: '10px', + fill: true, + offsets: { + start: '25px', + end: '25px', + }, + }) + + // If both nodes are backbone nodes add to layer group + if(node.is_backbone && updatedNodes.find(n => n.node_id == neighbour.node_id)?.is_backbone) { + backboneNeighbourLine.addTo(backboneNeighboursLayerGroup); + } + // default to showing distance in meters var distance = `${distanceInMeters} meters`; @@ -3482,6 +3518,17 @@ event.target.closeTooltip(); }); + backboneNeighbourLine.bindTooltip(tooltip, { + sticky: true, + opacity: 1, + interactive: true, + }) + .bindPopup(tooltip) + .on('click', function(event) { + // close tooltip on click to prevent tooltip and popup showing at same time + event.target.closeTooltip(); + }); + } }