diff --git a/htdocs/map.js b/htdocs/map.js index db73f02a..953438ed 100644 --- a/htdocs/map.js +++ b/htdocs/map.js @@ -152,6 +152,7 @@ $(function(){ position: pos, title: sourceToString(update.source) }, aprsOptions, getMarkerOpacityOptions(update.lastseen) )); + marker.source = update.source; marker.lastseen = update.lastseen; marker.mode = update.mode; marker.band = update.band; @@ -520,7 +521,7 @@ $(function(){ }); Object.values(markers).forEach(function(m) { var age = now - m.lastseen; - if (age > retention_time) { + if (age > retention_time || (m.ttl && age > m.ttl)) { delete markers[sourceToKey(m.source)]; m.setMap(); return; diff --git a/owrx/adsb/modes.py b/owrx/adsb/modes.py index 8b9bc237..31888e57 100644 --- a/owrx/adsb/modes.py +++ b/owrx/adsb/modes.py @@ -1,8 +1,7 @@ -from abc import ABC - from csdr.module import PickleModule from math import sqrt, atan2, pi, floor, acos, cos -from owrx.map import LatLngLocation, IncrementalUpdate, Location, Map +from owrx.map import LatLngLocation, IncrementalUpdate, TTLUpdate, Location, Map +from datetime import timedelta import time import logging @@ -17,7 +16,7 @@ d_lat_even = 360 / (4 * nz) d_lat_odd = 360 / (4 * nz - 1) -class AirplaneLocation(LatLngLocation, IncrementalUpdate, ABC): +class AirplaneLocation(IncrementalUpdate, TTLUpdate, LatLngLocation): mapKeys = [ "icao", "lat", @@ -66,6 +65,9 @@ class AirplaneLocation(LatLngLocation, IncrementalUpdate, ABC): dict.update(self.props) return dict + def getTTL(self) -> timedelta: + return timedelta(seconds=self.ttl) + class CprCache: def __init__(self): diff --git a/owrx/map.py b/owrx/map.py index 39d56693..9a7b5d20 100644 --- a/owrx/map.py +++ b/owrx/map.py @@ -9,7 +9,6 @@ import sys import logging logger = logging.getLogger(__name__) -logger.setLevel(logging.INFO) class Location(object): @@ -121,9 +120,19 @@ class Map(object): def removeOldPositions(self): pm = Config.get() retention = timedelta(seconds=pm["map_position_retention_time"]) - cutoff = datetime.now() - retention + now = datetime.now() + cutoff = now - retention - to_be_removed = [key for (key, pos) in self.positions.items() if pos["updated"] < cutoff] + def isExpired(pos): + if pos["updated"] < cutoff: + return True + if isinstance(pos["location"], TTLUpdate): + if now - pos["location"].getTTL() > pos["updated"]: + return True + return False + + with self.positionsLock: + to_be_removed = [key for (key, pos) in self.positions.items() if isExpired(pos)] for key in to_be_removed: self.removeLocation(key) @@ -157,3 +166,14 @@ class IncrementalUpdate(Location, metaclass=ABCMeta): @abstractmethod def update(self, previousLocation: Location): pass + + +class TTLUpdate(Location, metaclass=ABCMeta): + @abstractmethod + def getTTL(self) -> timedelta: + pass + + def __dict__(self): + res = super().__dict__() + res["ttl"] = self.getTTL().total_seconds() * 1000 + return res