From f8fc4ad3e1c162a808578ade2c9ceec9d405ac5e Mon Sep 17 00:00:00 2001 From: liamcottle Date: Mon, 18 Mar 2024 22:52:28 +1300 Subject: [PATCH] add waypoint markers layer to map --- src/public/index.html | 113 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 110 insertions(+), 3 deletions(-) diff --git a/src/public/index.html b/src/public/index.html index 1fb1eeb..8d3dc12 100644 --- a/src/public/index.html +++ b/src/public/index.html @@ -42,6 +42,11 @@ border: 1px solid white; } + .waypoint-label { + font-size: 26px; + background-color: transparent; + } + .link { color: #2563eb; } @@ -973,6 +978,7 @@ var nodes = []; var nodeMarkers = {}; var selectedNodeOutlineCircle = null; + var waypoints = []; // set map bounds to be a little more than full size to prevent panning off screen var bounds = [ @@ -1002,6 +1008,7 @@ showCoverageOnHover: false, disableClusteringAtZoom: 10, // zoom level where goToNode zooms to }); + var waypointsLayerGroup = new L.LayerGroup(); // create icons var iconOnline = L.divIcon({ @@ -1023,10 +1030,12 @@ var baseLayers = { "Nodes (All)": nodesLayerGroup, "Nodes (Clustered)": nodesClusteredLayerGroup, + "Nodes (Hide All)": new L.LayerGroup(), }; var overlays = { "Neighbours": neighboursLayerGroup, + "Waypoints": waypointsLayerGroup, }; // add layers to control ui @@ -1192,6 +1201,10 @@ neighboursLayerGroup.clearLayers(); } + function clearAllWaypoints() { + waypointsLayerGroup.clearLayers(); + } + function closeAllPopups() { map.eachLayer(function(layer) { if(layer.options.pane === "popupPane"){ @@ -1238,14 +1251,12 @@ closeAllTooltips(); clearAllNodes(); clearAllNeighbours(); + clearAllWaypoints(); clearNodeOutline(); } function onNodesUpdated(updatedNodes) { - // clear previous data - clearMap(); - // clear nodes cache nodes = []; @@ -1388,6 +1399,75 @@ } + function onWaypointsUpdated(updatedWaypoints) { + + // clear nodes cache + waypoints = []; + + // add nodes + for(var waypoint of updatedWaypoints){ + + // skip expired waypoints + if(waypoint.expire < Date.now() / 1000){ + continue; + } + + // skip nodes without position + if(!waypoint.latitude || !waypoint.longitude){ + continue; + } + + // fix lat long + waypoint.latitude = waypoint.latitude / 10000000; + waypoint.longitude = waypoint.longitude / 10000000; + + var hasLocation = isValidLatLng(waypoint.latitude, waypoint.longitude); + + if(hasLocation){ + + // wrap longitude for shortest path, everything to left of australia should be shown on the right + var longitude = parseFloat(waypoint.longitude); + if(longitude <= 100){ + waypoint.longitude = (longitude += 360); + } + + // determine emoji to show as marker icon + const emoji = waypoint.icon === 0 ? 128205 : waypoint.icon; + const emojiText = String.fromCodePoint(emoji) + + var tooltip = getTooltipContentForWaypoint(waypoint); + + // create waypoint marker + var marker = L.marker([waypoint.latitude, waypoint.longitude], { + icon: L.divIcon({ + className: 'waypoint-label', + iconSize: [26, 26], // increase from 12px to 26px + html: emojiText, + }), + }).bindPopup(tooltip).on('click', function(event) { + // close tooltip on click to prevent tooltip and popup showing at same time + event.target.closeTooltip(); + }); + + // show tooltip on desktop only + if(!isMobile()){ + marker.bindTooltip(tooltip, { + interactive: true, + }); + } + + // add marker to waypoints layer groups + marker.addTo(waypointsLayerGroup); + + // add to cache + waypoints.push(waypoint); + + } + + } + + } + function setLoading(loading){ var reloadButton = document.getElementById("reload-button"); if(loading){ @@ -1402,6 +1482,9 @@ // show loading setLoading(true); + // clear previous data + clearMap(); + // fetch nodes fetch('/api/v1/nodes').then(async (response) => { @@ -1419,6 +1502,15 @@ }); + // fetch waypoints + fetch('/api/v1/waypoints').then(async (response) => { + + // update waypoints + var json = await response.json(); + onWaypointsUpdated(json.waypoints); + + }); + } function getTooltipContentForNode(node) { @@ -1458,6 +1550,21 @@ } + function getTooltipContentForWaypoint(waypoint) { + + var tooltip = `${waypoint.name}` + + `
${waypoint.description}` + + `

Expires: ${moment(new Date(waypoint.expire * 1000)).fromNow()}` + + `
Lat/Lng: ${waypoint.latitude}, ${waypoint.longitude}`; + + // bottom info + tooltip += `

ID: ${waypoint.waypoint_id}`; + tooltip += `
Updated: ${moment(new Date(waypoint.updated_at)).fromNow()}`; + + return tooltip; + + } + // parse url params var queryParams = new URLSearchParams(location.search); var queryNodeId = queryParams.get('node_id');