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');