From eb11d65f9281b69dc2a05df475499b7c93f68d2f Mon Sep 17 00:00:00 2001 From: Marat Fayzullin Date: Sat, 29 Jul 2023 14:01:50 -0400 Subject: [PATCH] Moved markers storage into MarkerManager. --- htdocs/lib/MarkerManager.js | 57 ++++++++++++++++++++++---- htdocs/map.js | 80 +++++++++++++++---------------------- 2 files changed, 82 insertions(+), 55 deletions(-) diff --git a/htdocs/lib/MarkerManager.js b/htdocs/lib/MarkerManager.js index 54f2f983..64756a9b 100644 --- a/htdocs/lib/MarkerManager.js +++ b/htdocs/lib/MarkerManager.js @@ -3,17 +3,20 @@ // function MarkerManager() { - // Currently known features + // Current markers + this.markers = {}; + + // Currently known marker types this.types = {}; - // Colors used for features + // Colors used for marker types this.colors = { 'KiwiSDR' : '#800000', 'WebSDR' : '#000080', 'OpenWebRX' : '#004000' }; - // Symbols used for features + // Symbols used for marker types this.symbols = { 'KiwiSDR' : '◬', 'WebSDR' : '◬', @@ -24,7 +27,7 @@ function MarkerManager() { 'HFDL' : '✈' }; - // Feature type shown/hidden status + // Marker type shown/hidden status this.enabled = { 'KiwiSDR' : false, 'WebSDR' : false, @@ -48,13 +51,13 @@ MarkerManager.prototype.isEnabled = function(type) { return type in this.enabled? this.enabled[type] : true; }; -MarkerManager.prototype.toggle = function(map, markers, type, onoff) { +MarkerManager.prototype.toggle = function(map, type, onoff) { // Keep track of each feature table being show or hidden this.enabled[type] = onoff; // Show or hide features on the map - $.each(markers, function(_, r) { - if (r.mode === type) r.setMap(onoff ? map : undefined); + $.each(this.markers, function(_, x) { + if (x.mode === type) x.setMap(onoff ? map : undefined); }); }; @@ -85,6 +88,28 @@ MarkerManager.prototype.addType = function(type) { } }; +MarkerManager.prototype.find = function(id) { + return id in this.markers? this.markers[id] : null; +}; + +MarkerManager.prototype.add = function(id, marker) { + this.markers[id] = marker; +}; + +MarkerManager.prototype.ageAll = function() { + var now = new Date().getTime(); + $.each(this.markers, function(id, x) { + if (!x.age(now - x.lastseen)) delete this.markers[id]; + }); +}; + +MarkerManager.prototype.clear = function() { + // Remove all markers from the map + $.each(this.markers, function(_, x) { x.setMap(); }); + // Delete all markers + this.markers = {}; +}; + // // Generic marker functionality // @@ -161,6 +186,14 @@ Marker.makeListItem = function(name, value) { + ''; }; +Marker.getOpacityScale = function(age) { + var scale = 1; + if (age >= retention_time / 2) { + scale = (retention_time - age) / (retention_time / 2); + } + return Math.max(0, Math.min(1, scale)); +}; + // // Feature Markers // @@ -533,6 +566,16 @@ GMarker.prototype.getAnchorPoint = function() { return new google.maps.Point(offset[0], offset[1]); }; +GMarker.prototype.age = function(age) { + if(age <= retention_time) { + this.setOptions({ opacity: Marker.getOpacityScale(age) }); + return true; + } else { + this.setMap(); + return false; + } +}; + // GoogleMaps-Specific FeatureMarker function GFeatureMarker() { $.extend(this, new FeatureMarker()); } GFeatureMarker.prototype = new GMarker(); diff --git a/htdocs/map.js b/htdocs/map.js index e8de67c1..4db1500a 100644 --- a/htdocs/map.js +++ b/htdocs/map.js @@ -1,10 +1,17 @@ -// // Marker.linkify() uses these URLs -// var callsign_url = null; var vessel_url = null; var flight_url = null; +// reasonable default; will be overriden by server +var retention_time = 2 * 60 * 60 * 1000; + +// Function to toggle legend box on/off +function toggleElement(el_name) { + var el = document.getElementById(el_name); + if (el) el.style.display = el.style.display === 'none'? 'block' : 'none'; +} + $(function(){ var query = window.location.search.replace(/^\?/, '').split('&').map(function(v){ var s = v.split('='); @@ -35,13 +42,10 @@ $(function(){ var ws_url = href + "ws/"; var map; - var markers = {}; var rectangles = {}; var receiverMarker; var updateQueue = []; - // reasonable default; will be overriden by server - var retention_time = 2 * 60 * 60 * 1000; var strokeOpacity = 0.8; var fillOpacity = 0.35; @@ -128,7 +132,7 @@ $(function(){ switch (update.location.type) { case 'latlon': var pos = new google.maps.LatLng(update.location.lat, update.location.lon); - var marker; + var marker = markmanager.find(update.callsign); var markerClass = google.maps.Marker; var aprsOptions = {} if (update.location.symbol) { @@ -137,22 +141,26 @@ $(function(){ aprsOptions.course = update.location.course; aprsOptions.speed = update.location.speed; } - if (markers[update.callsign]) { - marker = markers[update.callsign]; - } else { + + // If new item, create a new marker for it + if (!marker) { + marker = new markerClass(); markmanager.addType(update.mode); - marker = markers[update.callsign] = new markerClass(); + markmanager.add(update.callsign, marker); marker.addListener('click', function(){ showMarkerInfoWindow(update.callsign, pos); }); } + + // Apply marker options marker.setOptions($.extend({ position: pos, map: markmanager.isEnabled(update.mode)? map : undefined, title: update.callsign - }, aprsOptions, getMarkerOpacityOptions(update.lastseen) )); + }, aprsOptions)); - // Update marker attributes + // Update marker attributes and age + marker.age(new Date().getTime() - update.lastseen); marker.update(update); if (expectedCallsign && expectedCallsign == update.callsign) { @@ -167,8 +175,8 @@ $(function(){ break; case 'feature': var pos = new google.maps.LatLng(update.location.lat, update.location.lon); + var marker = markmanager.find(update.callsign); var options = {} - var marker; // If no symbol or color supplied, use defaults by type if (update.location.symbol) { @@ -182,12 +190,11 @@ $(function(){ options.color = markmanager.getColor(update.mode); } - // If new item, create a new feature marker for it - if (markers[update.callsign]) { - marker = markers[update.callsign]; - } else { + // If new item, create a new marker for it + if (!marker) { + marker = new GFeatureMarker(); markmanager.addType(update.mode); - marker = markers[update.callsign] = new GFeatureMarker(); + markmanager.add(update.callsign, marker); marker.addListener('click', function(){ showMarkerInfoWindow(update.callsign, pos); }); @@ -200,7 +207,8 @@ $(function(){ title: update.callsign }, options)); - // Update marker attributes + // Update marker attributes and age + marker.age(new Date().getTime() - update.lastseen); marker.update(update); if (expectedCallsign && expectedCallsign == update.callsign) { @@ -265,10 +273,9 @@ $(function(){ var clearMap = function(){ var reset = function(callsign, item) { item.setMap(); }; - $.each(markers, reset); - $.each(rectangles, reset); receiverMarker.setMap(); - markers = {}; + markmanager.clear(); + $.each(rectangles, reset); rectangles = {}; }; @@ -445,7 +452,7 @@ $(function(){ var showMarkerInfoWindow = function(name, pos) { var infowindow = getInfoWindow(); - var marker = markers[name]; + var marker = markmanager.find(name); infowindow.callsign = name; infowindow.setContent(marker.getInfoHTML(name, receiverMarker)); @@ -478,13 +485,6 @@ $(function(){ }; }; - var getMarkerOpacityOptions = function(lastseen) { - var scale = getScale(lastseen); - return { - opacity: scale - }; - }; - // fade out / remove positions after time setInterval(function(){ var now = new Date().getTime(); @@ -497,15 +497,7 @@ $(function(){ } m.setOptions(getRectangleOpacityOptions(m.lastseen)); }); - $.each(markers, function(callsign, m) { - var age = now - m.lastseen; - if (age > retention_time) { - delete markers[callsign]; - m.setMap(); - return; - } - m.setOptions(getMarkerOpacityOptions(m.lastseen)); - }); + markmanager.ageAll(); }, 1000); var rectangleFilter = allRectangles = function() { return true; }; @@ -548,16 +540,8 @@ $(function(){ } else { $el.addClass('disabled'); } - markmanager.toggle(map, markers, $el.data('selector'), onoff); + markmanager.toggle(map, $el.data('selector'), onoff); }); } }); - -function toggleElement(el_name) { - var el = document.getElementById(el_name); - if (el) { - el.style.display = el.style.display === 'none'? - 'block' : 'none'; - } -}