first work on custom aprs icons
This commit is contained in:
parent
c6c4012a36
commit
3e8e0c9224
@ -107,11 +107,22 @@
|
|||||||
});
|
});
|
||||||
markers[update.callsign] = marker;
|
markers[update.callsign] = marker;
|
||||||
}
|
}
|
||||||
|
var iconOptions = {}
|
||||||
|
if (update.location.symbol) {
|
||||||
|
var index = update.location.symbol.index;
|
||||||
|
var tableId = update.location.symbol.table == '/' ? 0 : 1;
|
||||||
|
iconOptions.icon = {
|
||||||
|
url: '/aprs-symbols/aprs-symbols-24-' + tableId + '.png',
|
||||||
|
size: new google.maps.Size(24, 24),
|
||||||
|
origin: new google.maps.Point((index % 16) * 24, Math.floor(index / 16) * 24),
|
||||||
|
anchor: new google.maps.Point(12, 12),
|
||||||
|
};
|
||||||
|
}
|
||||||
marker.setOptions($.extend({
|
marker.setOptions($.extend({
|
||||||
position: pos,
|
position: pos,
|
||||||
map: map,
|
map: map,
|
||||||
title: update.callsign
|
title: update.callsign
|
||||||
}, getMarkerOpacityOptions(update.lastseen) ));
|
}, iconOptions, getMarkerOpacityOptions(update.lastseen) ));
|
||||||
marker.lastseen = update.lastseen;
|
marker.lastseen = update.lastseen;
|
||||||
marker.mode = update.mode;
|
marker.mode = update.mode;
|
||||||
marker.band = update.band;
|
marker.band = update.band;
|
||||||
|
38
owrx/aprs.py
38
owrx/aprs.py
@ -131,6 +131,21 @@ class WeatherParser(object):
|
|||||||
return self.data
|
return self.data
|
||||||
|
|
||||||
|
|
||||||
|
class AprsLocation(LatLngLocation):
|
||||||
|
def __init__(self, data):
|
||||||
|
super().__init__(data["lat"], data["lon"])
|
||||||
|
self.comment = data["comment"] if "comment" in data else None
|
||||||
|
self.symbol = data["symbol"] if "symbol" in data else None
|
||||||
|
|
||||||
|
def __dict__(self):
|
||||||
|
res = super(AprsLocation, self).__dict__()
|
||||||
|
if self.comment is not None:
|
||||||
|
res["comment"] = self.comment
|
||||||
|
if self.symbol is not None:
|
||||||
|
res["symbol"] = self.symbol
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
class AprsParser(object):
|
class AprsParser(object):
|
||||||
def __init__(self, handler):
|
def __init__(self, handler):
|
||||||
self.ax25parser = Ax25Parser()
|
self.ax25parser = Ax25Parser()
|
||||||
@ -176,7 +191,7 @@ class AprsParser(object):
|
|||||||
if "type" in mapData and mapData["type"] == "thirdparty" and "data" in mapData:
|
if "type" in mapData and mapData["type"] == "thirdparty" and "data" in mapData:
|
||||||
mapData = mapData["data"]
|
mapData = mapData["data"]
|
||||||
if "lat" in mapData and "lon" in mapData:
|
if "lat" in mapData and "lon" in mapData:
|
||||||
loc = LatLngLocation(mapData["lat"], mapData["lon"], mapData["comment"] if "comment" in mapData else None)
|
loc = AprsLocation(mapData)
|
||||||
source = mapData["source"]
|
source = mapData["source"]
|
||||||
if "type" in mapData:
|
if "type" in mapData:
|
||||||
if mapData["type"] == "item":
|
if mapData["type"] == "item":
|
||||||
@ -195,14 +210,17 @@ class AprsParser(object):
|
|||||||
lon = int(raw[9:12]) + float(raw[12:17]) / 60
|
lon = int(raw[9:12]) + float(raw[12:17]) / 60
|
||||||
if raw[17] == "W":
|
if raw[17] == "W":
|
||||||
lon *= -1
|
lon *= -1
|
||||||
return {"lat": lat, "lon": lon, "symboltable": raw[8], "symbol": raw[18]}
|
return {"lat": lat, "lon": lon, "symbol": {"table": raw[8], "symbol": raw[18], "index": ord(raw[18]) - 33}}
|
||||||
|
|
||||||
def parseCompressedCoordinates(self, raw):
|
def parseCompressedCoordinates(self, raw):
|
||||||
return {
|
return {
|
||||||
"lat": 90 - decodeBase91(raw[1:5]) / 380926,
|
"lat": 90 - decodeBase91(raw[1:5]) / 380926,
|
||||||
"lon": -180 + decodeBase91(raw[5:9]) / 190463,
|
"lon": -180 + decodeBase91(raw[5:9]) / 190463,
|
||||||
"symboltable": raw[0],
|
"symbol": {
|
||||||
"symbol": raw[9],
|
"table": raw[0],
|
||||||
|
"symbol": raw[9],
|
||||||
|
"index": ord(raw[9]) - 33
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def parseTimestamp(self, raw):
|
def parseTimestamp(self, raw):
|
||||||
@ -219,7 +237,6 @@ class AprsParser(object):
|
|||||||
ts = ts.replace(tzinfo=now.tzinfo)
|
ts = ts.replace(tzinfo=now.tzinfo)
|
||||||
else:
|
else:
|
||||||
logger.warning("invalid timezone info byte: %s", raw[6])
|
logger.warning("invalid timezone info byte: %s", raw[6])
|
||||||
logger.debug(ts)
|
|
||||||
return int(ts.timestamp() * 1000)
|
return int(ts.timestamp() * 1000)
|
||||||
|
|
||||||
def parseStatusUpate(self, raw):
|
def parseStatusUpate(self, raw):
|
||||||
@ -319,7 +336,6 @@ class AprsParser(object):
|
|||||||
def parseThirdpartyAprsData(self, information):
|
def parseThirdpartyAprsData(self, information):
|
||||||
matches = thirdpartyeRegex.match(information)
|
matches = thirdpartyeRegex.match(information)
|
||||||
if matches:
|
if matches:
|
||||||
logger.debug(matches)
|
|
||||||
path = matches.group(2).split(",")
|
path = matches.group(2).split(",")
|
||||||
destination = next((c.strip("*").upper() for c in path if c.endswith("*")), None)
|
destination = next((c.strip("*").upper() for c in path if c.endswith("*")), None)
|
||||||
data = self.parseAprsData(
|
data = self.parseAprsData(
|
||||||
@ -378,7 +394,8 @@ class AprsParser(object):
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
# aprs data extensions
|
# aprs data extensions
|
||||||
if "symbol" in aprsData and aprsData["symbol"] == "_":
|
# yes, weather stations are officially identified by their symbols. go figure...
|
||||||
|
if "symbol" in aprsData and aprsData["symbol"]["index"] == 62:
|
||||||
# weather report
|
# weather report
|
||||||
weather = {}
|
weather = {}
|
||||||
if len(comment) > 6 and comment[3] == "/":
|
if len(comment) > 6 and comment[3] == "/":
|
||||||
@ -558,6 +575,9 @@ class MicEParser(object):
|
|||||||
"course": course,
|
"course": course,
|
||||||
"device": device,
|
"device": device,
|
||||||
"type": "Mic-E",
|
"type": "Mic-E",
|
||||||
"symboltable": chr(information[8]),
|
"symbol": {
|
||||||
"symbol": chr(information[7]),
|
"table": chr(information[8]),
|
||||||
|
"symbol": chr(information[7]),
|
||||||
|
"index": information[7] - 33
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,15 +92,12 @@ class Map(object):
|
|||||||
|
|
||||||
|
|
||||||
class LatLngLocation(Location):
|
class LatLngLocation(Location):
|
||||||
def __init__(self, lat: float, lon: float, comment=None):
|
def __init__(self, lat: float, lon: float):
|
||||||
self.lat = lat
|
self.lat = lat
|
||||||
self.lon = lon
|
self.lon = lon
|
||||||
self.comment = comment
|
|
||||||
|
|
||||||
def __dict__(self):
|
def __dict__(self):
|
||||||
res = {"type": "latlon", "lat": self.lat, "lon": self.lon}
|
res = {"type": "latlon", "lat": self.lat, "lon": self.lon}
|
||||||
if self.comment is not None:
|
|
||||||
res["comment"] = self.comment
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user