Added separate map display for features.
This commit is contained in:
parent
a57e1d00dc
commit
25167db8c6
|
|
@ -58,6 +58,17 @@ ul {
|
|||
border-style: solid;
|
||||
}
|
||||
|
||||
.openwebrx-map-legend li.square .feature {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 10px;
|
||||
border-width: 0;
|
||||
border-style: none;
|
||||
font-size: 24px;
|
||||
text-alignment: center;
|
||||
}
|
||||
|
||||
.openwebrx-map-legend select {
|
||||
background-color: #FFF;
|
||||
border-color: #DDD;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
function FeatureMarker() {}
|
||||
|
||||
FeatureMarker.prototype = new google.maps.OverlayView();
|
||||
|
||||
FeatureMarker.prototype.draw = function() {
|
||||
var div = this.div;
|
||||
if (!div) return;
|
||||
|
||||
div.style.color = this.color? this.color : '#000000';
|
||||
div.innerHTML = this.symbol? this.symbol : '●';
|
||||
|
||||
var point = this.getProjection().fromLatLngToDivPixel(this.position);
|
||||
if (point) {
|
||||
div.style.left = point.x - this.symWidth/2 + 'px';
|
||||
div.style.top = point.y - this.symHeight/2 + 'px';
|
||||
}
|
||||
};
|
||||
|
||||
FeatureMarker.prototype.setOptions = function(options) {
|
||||
google.maps.OverlayView.prototype.setOptions.apply(this, arguments);
|
||||
this.draw();
|
||||
};
|
||||
|
||||
FeatureMarker.prototype.onAdd = function() {
|
||||
var div = this.div = document.createElement('div');
|
||||
|
||||
// Marker size
|
||||
this.symWidth = 16;
|
||||
this.symHeight = 16;
|
||||
|
||||
div.style.position = 'absolute';
|
||||
div.style.cursor = 'pointer';
|
||||
div.style.width = this.symWidth + 'px';
|
||||
div.style.height = this.symHeight + 'px';
|
||||
div.style.textAlign = 'center';
|
||||
div.style.fontSize = this.symHeight + 'px';
|
||||
div.style.lineHeight = this.symHeight + 'px';
|
||||
|
||||
var self = this;
|
||||
google.maps.event.addDomListener(div, "click", function(event) {
|
||||
event.stopPropagation();
|
||||
google.maps.event.trigger(self, "click", event);
|
||||
});
|
||||
|
||||
var panes = this.getPanes();
|
||||
panes.overlayImage.appendChild(div);
|
||||
};
|
||||
|
||||
FeatureMarker.prototype.remove = function() {
|
||||
if (this.div) {
|
||||
this.div.parentNode.removeChild(this.div);
|
||||
this.div = null;
|
||||
}
|
||||
};
|
||||
|
||||
FeatureMarker.prototype.getAnchorPoint = function() {
|
||||
return new google.maps.Point(0, -this.symHeight/2);
|
||||
};
|
||||
|
|
@ -22,6 +22,13 @@
|
|||
<option value="off">Off</option>
|
||||
</select>
|
||||
<div class="content"></div>
|
||||
<h3>Features</h3>
|
||||
<ul class="features">
|
||||
<li class="square" data-selector="APRS"><span class="feature" style="color:#000000;">◇</span>APRS</li>
|
||||
<li class="square" data-selector="KiwiSDR"><span class="feature" style="color:#800000;">◬</span>KiwiSDR</li>
|
||||
<li class="square" data-selector="WebSDR"><span class="feature" style="color:#000080;">◬</span>WebSDR</li>
|
||||
<li class="square" data-selector="OpenWebRX"><span class="feature" style="color:#006000;">◬</span>OWRX</li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -41,6 +41,13 @@ $(function(){
|
|||
var vessel_url = null;
|
||||
var flight_url = null;
|
||||
|
||||
// colors used for features
|
||||
var featureColors = {
|
||||
'KiwiSDR' : '#800000',
|
||||
'WebSDR' : '#000080',
|
||||
'OpenWebRX' : '#006000'
|
||||
};
|
||||
|
||||
var colorKeys = {};
|
||||
var colorScale = chroma.scale(['red', 'blue', 'green']).mode('hsl');
|
||||
var getColor = function(id){
|
||||
|
|
@ -109,7 +116,7 @@ $(function(){
|
|||
}
|
||||
|
||||
var processUpdates = function(updates) {
|
||||
if (typeof(AprsMarker) == 'undefined') {
|
||||
if ((typeof(AprsMarker) == 'undefined') || (typeof(FeatureMarker) == 'undefined')) {
|
||||
updateQueue = updateQueue.concat(updates);
|
||||
return;
|
||||
}
|
||||
|
|
@ -145,7 +152,6 @@ $(function(){
|
|||
marker.mode = update.mode;
|
||||
marker.hops = update.hops;
|
||||
marker.band = update.band;
|
||||
marker.url = update.location.url;
|
||||
marker.comment = update.location.comment;
|
||||
marker.weather = update.location.weather;
|
||||
marker.altitude = update.location.altitude;
|
||||
|
|
@ -154,8 +160,6 @@ $(function(){
|
|||
marker.gain = update.location.gain;
|
||||
marker.device = update.location.device;
|
||||
marker.aircraft = update.location.aircraft;
|
||||
marker.antenna = update.location.antenna;
|
||||
marker.users = update.location.users;
|
||||
marker.directivity = update.location.directivity;
|
||||
|
||||
if (expectedCallsign && expectedCallsign == update.callsign) {
|
||||
|
|
@ -168,6 +172,49 @@ $(function(){
|
|||
showMarkerInfoWindow(infowindow.callsign, pos);
|
||||
}
|
||||
break;
|
||||
case 'feature':
|
||||
var pos = new google.maps.LatLng(update.location.lat, update.location.lon);
|
||||
var marker;
|
||||
var markerClass = google.maps.Marker;
|
||||
var options = {}
|
||||
if (update.location.symbol) {
|
||||
markerClass = FeatureMarker;
|
||||
options.symbol = update.location.symbol;
|
||||
options.color = update.mode in featureColors?
|
||||
featureColors[update.mode] : '#000000';
|
||||
}
|
||||
if (markers[update.callsign]) {
|
||||
marker = markers[update.callsign];
|
||||
} else {
|
||||
marker = new markerClass();
|
||||
marker.addListener('click', function(){
|
||||
showMarkerInfoWindow(update.callsign, pos);
|
||||
});
|
||||
markers[update.callsign] = marker;
|
||||
}
|
||||
marker.setOptions($.extend({
|
||||
position: pos,
|
||||
map: map,
|
||||
title: update.callsign
|
||||
}, options, getMarkerOpacityOptions(update.lastseen) ));
|
||||
marker.lastseen = update.lastseen;
|
||||
marker.mode = update.mode;
|
||||
marker.url = update.location.url;
|
||||
marker.comment = update.location.comment;
|
||||
marker.altitude = update.location.altitude;
|
||||
marker.device = update.location.device;
|
||||
marker.antenna = update.location.antenna;
|
||||
|
||||
if (expectedCallsign && expectedCallsign == update.callsign) {
|
||||
map.panTo(pos);
|
||||
showMarkerInfoWindow(update.callsign, pos);
|
||||
expectedCallsign = false;
|
||||
}
|
||||
|
||||
if (infowindow && infowindow.callsign && infowindow.callsign == update.callsign) {
|
||||
showMarkerInfoWindow(infowindow.callsign, pos);
|
||||
}
|
||||
break;
|
||||
case 'locator':
|
||||
var loc = update.location.locator;
|
||||
var lat = (loc.charCodeAt(1) - 65 - 9) * 10 + Number(loc[3]);
|
||||
|
|
@ -267,8 +314,16 @@ $(function(){
|
|||
setInterval(function() { nite.refresh() }, 10000); // every 10s
|
||||
});
|
||||
$.getScript('static/lib/AprsMarker.js').done(function(){
|
||||
processUpdates(updateQueue);
|
||||
updateQueue = [];
|
||||
if(typeof(FeatureMarker) != 'undefined') {
|
||||
processUpdates(updateQueue);
|
||||
updateQueue = [];
|
||||
}
|
||||
});
|
||||
$.getScript('static/lib/FeatureMarker.js').done(function(){
|
||||
if(typeof(AprsMarker) != 'undefined') {
|
||||
processUpdates(updateQueue);
|
||||
updateQueue = [];
|
||||
}
|
||||
});
|
||||
|
||||
var $legend = $(".openwebrx-map-legend");
|
||||
|
|
@ -686,6 +741,25 @@ $(function(){
|
|||
});
|
||||
}
|
||||
});
|
||||
|
||||
$content = $legend.find('.features');
|
||||
$content.on('click', 'li', function() {
|
||||
var $el = $(this);
|
||||
$lis = $content.find('li');
|
||||
if ($lis.hasClass('disabled') && !$el.hasClass('disabled')) {
|
||||
$lis.removeClass('disabled');
|
||||
// @@@ ADD CODE HERE
|
||||
} else {
|
||||
$el.removeClass('disabled');
|
||||
$lis.filter(function() {
|
||||
return this != $el[0]
|
||||
}).addClass('disabled');
|
||||
|
||||
var key = colorMode.slice(2);
|
||||
var selector = $el.data('selector');
|
||||
// @@@ ADD CODE HERE
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ class ReceiverLocation(LatLngLocation):
|
|||
def getId(self):
|
||||
return re.sub(r"^.*://(.*)[/:].*$", r"\1", self.attrs["url"])
|
||||
|
||||
def getMode(self):
|
||||
return re.sub(r"^([A-Za-z]+).*$", r"\1", self.attrs["device"])
|
||||
|
||||
def __dict__(self):
|
||||
return self.attrs
|
||||
|
||||
|
|
@ -90,6 +93,7 @@ class ReceiverDatabase(object):
|
|||
try:
|
||||
with open(file, "w") as f:
|
||||
json.dump(self, f, cls=ReceiverJSONEncoder, indent=2)
|
||||
f.close()
|
||||
except Exception as e:
|
||||
logger.debug("Exception: {0}".format(e))
|
||||
|
||||
|
|
@ -101,13 +105,13 @@ class ReceiverDatabase(object):
|
|||
logger.debug("Done refreshing receiver database.")
|
||||
self.thread = None
|
||||
|
||||
def getSymbol(self, type: str):
|
||||
def getColor(self, type: str):
|
||||
if type.startswith("KiwiSDR"):
|
||||
return getSymbolData('/', '/')
|
||||
return "#800000"
|
||||
elif type.startswith("WebSDR"):
|
||||
return getSymbolData('/', '\\')
|
||||
return "#000080"
|
||||
else:
|
||||
return getSymbolData('<', '\\')
|
||||
return "#006000"
|
||||
|
||||
def loadFromFile(self, fileName: str = None):
|
||||
# Get filename
|
||||
|
|
@ -118,6 +122,7 @@ class ReceiverDatabase(object):
|
|||
try:
|
||||
with open(fileName, "r") as f:
|
||||
content = f.read()
|
||||
f.close()
|
||||
if content:
|
||||
db = json.loads(content)
|
||||
except Exception as e:
|
||||
|
|
@ -135,7 +140,7 @@ class ReceiverDatabase(object):
|
|||
|
||||
def updateMap(self):
|
||||
for r in self.receivers.values():
|
||||
Map.getSharedInstance().updateLocation(r.getId(), r, "Internet")
|
||||
Map.getSharedInstance().updateLocation(r.getId(), r, r.getMode())
|
||||
|
||||
def scrapeOWRX(self, url: str = "https://www.receiverbook.de/map"):
|
||||
patternJson = re.compile(r"^\s*var\s+receivers\s+=\s+(\[.*\]);\s*$")
|
||||
|
|
@ -160,13 +165,14 @@ class ReceiverDatabase(object):
|
|||
else:
|
||||
dev = r["type"]
|
||||
rl = ReceiverLocation(lat, lon, {
|
||||
"type" : "latlon",
|
||||
"type" : "feature",
|
||||
"lat" : lat,
|
||||
"lon" : lon,
|
||||
"comment" : r["label"],
|
||||
"url" : r["url"],
|
||||
"device" : dev,
|
||||
"symbol" : self.getSymbol(dev)
|
||||
"symbol" : "◬",
|
||||
"color" : self.getColor(dev)
|
||||
})
|
||||
result[rl.getId()] = rl
|
||||
# Offset colocated receivers by ~500m
|
||||
|
|
@ -190,14 +196,15 @@ class ReceiverDatabase(object):
|
|||
lat = entry["lat"]
|
||||
lon = entry["lon"]
|
||||
rl = ReceiverLocation(lat, lon, {
|
||||
"type" : "latlon",
|
||||
"type" : "feature",
|
||||
"lat" : lat,
|
||||
"lon" : lon,
|
||||
"comment" : entry["desc"],
|
||||
"url" : entry["url"],
|
||||
#"users" : int(entry["users"]),
|
||||
"device" : "WebSDR",
|
||||
"symbol" : self.getSymbol("WebSDR")
|
||||
"symbol" : "◬",
|
||||
"color" : self.getColor("WebSDR")
|
||||
})
|
||||
result[rl.getId()] = rl
|
||||
|
||||
|
|
@ -231,7 +238,7 @@ class ReceiverDatabase(object):
|
|||
lat = float(m.group(1))
|
||||
lon = float(m.group(2))
|
||||
rl = ReceiverLocation(lat, lon, {
|
||||
"type" : "latlon",
|
||||
"type" : "feature",
|
||||
"lat" : lat,
|
||||
"lon" : lon,
|
||||
"comment" : entry["name"],
|
||||
|
|
@ -241,8 +248,9 @@ class ReceiverDatabase(object):
|
|||
"loc" : entry["loc"],
|
||||
"altitude": int(entry["asl"]),
|
||||
"antenna" : entry["antenna"],
|
||||
"device" : entry["sw_version"],
|
||||
"symbol" : self.getSymbol("KiwiSDR")
|
||||
"device" : re.sub("_v", " ", entry["sw_version"]),
|
||||
"symbol" : "◬",
|
||||
"color" : self.getColor("KiwiSDR")
|
||||
})
|
||||
result[rl.getId()] = rl
|
||||
# Clear current entry
|
||||
|
|
|
|||
Loading…
Reference in New Issue