diff --git a/chasemapper/__init__.py b/chasemapper/__init__.py index 03e9cb7..4226042 100644 --- a/chasemapper/__init__.py +++ b/chasemapper/__init__.py @@ -8,4 +8,4 @@ # Now using Semantic Versioning (https://semver.org/) MAJOR.MINOR.PATCH -__version__ = "1.3.1" +__version__ = "1.3.2" diff --git a/chasemapper/bearings.py b/chasemapper/bearings.py index 221bb35..810c8fb 100644 --- a/chasemapper/bearings.py +++ b/chasemapper/bearings.py @@ -44,6 +44,8 @@ class Bearings(object): # } self.bearings = {} + self.bearing_sources = [] + self.bearing_lock = Lock() # Internal record of the chase car position, which is updated with incoming GPS data. @@ -183,6 +185,10 @@ class Bearings(object): "source": _source, } + # Allow override of the heading valid calculations if a hearing_override field is supplied + if "heading_override" in bearing: + _new_bearing["heading_valid"] = bearing["heading_override"] + elif bearing["bearing_type"] == "absolute": # Absolute bearing - use the provided data as-is @@ -213,6 +219,10 @@ class Bearings(object): self.bearings["%.4f" % _arrival_time] = _new_bearing + if _source not in self.bearing_sources: + self.bearing_sources.append(_source) + logging.info(f"Bearing Handler - New source of bearings: {_source}") + # Now we need to do a clean-up of our bearing list. # At this point, we should always have at least 2 bearings in our store if len(self.bearings) == 1: diff --git a/static/js/bearings.js b/static/js/bearings.js index 8b64125..5c6e926 100644 --- a/static/js/bearings.js +++ b/static/js/bearings.js @@ -15,6 +15,8 @@ var bearing_store = {}; +var bearing_sources = []; + var bearings_on = true; var bearings_only_mode = false; @@ -67,6 +69,7 @@ function destroyAllBearings(){ }); bearing_store = {}; + bearing_sources = []; } @@ -86,6 +89,11 @@ function bearingValid(bearing){ } } + // Disable showing of this bearing if the source is not selected + if (!document.getElementById("bearing_source_" + bearing.source).checked){ + _show_bearing = false; + } + return _show_bearing; } @@ -106,6 +114,18 @@ function addBearing(timestamp, bearing, live){ bearing_store[timestamp] = bearing; + if ( !bearing_sources.includes(bearing.source)){ + bearing_sources.push(bearing.source); + _new_bearing_div_name = "bearing_source_" + bearing.source; + bearing_sources_div = "
Source: " + bearing.source + "
"; + $("#bearing_source_selector").append(bearing_sources_div); + $("#"+_new_bearing_div_name).prop('checked',true); + + $("#"+_new_bearing_div_name).change(function(){ + redrawBearings(); + }); + } + // Calculate the end position. var _end = calculateDestination(L.latLng([bearing_store[timestamp].lat, bearing_store[timestamp].lon]), bearing_store[timestamp].true_bearing, bearing_length); diff --git a/templates/index.html b/templates/index.html index 86fbd5b..ffcb1e3 100644 --- a/templates/index.html +++ b/templates/index.html @@ -898,7 +898,6 @@ Show Stationary Bearings -

@@ -906,6 +905,9 @@
+

Bearing Sources

+
+

Bearing Style

Bearing Length (km)
diff --git a/utils/bearing_o_clock.py b/utils/bearing_o_clock.py new file mode 100644 index 0000000..fa6d3bd --- /dev/null +++ b/utils/bearing_o_clock.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# +# ChaseMapper - Bearing o'Clock +# +# Add bearings based on O'Clock position (1 through 12) +# Run with: python bearing_o_clock.py bearing_source_name +# +# Copyright (C) 2019 Mark Jessop +# Released under GNU GPL v3 or later +# +# +import json +import socket +import sys +import time +import datetime +import traceback + + +def send_relative_bearing(bearing, source, heading_override=False, udp_port=55672): + """ + Send a basic relative bearing + """ + packet = { + 'type' : 'BEARING', + 'bearing' : bearing, + 'bearing_type': 'relative', + 'source': source + } + + if heading_override: + packet["heading_override"] = True + + # Set up our UDP socket + s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) + s.settimeout(1) + # Set up socket for broadcast, and allow re-use of the address + s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + try: + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + except: + pass + s.bind(('',udp_port)) + try: + s.sendto(json.dumps(packet).encode('ascii'), ('', udp_port)) + except socket.error: + s.sendto(json.dumps(packet).encode('ascii'), ('127.0.0.1', udp_port)) + + +if __name__ == "__main__": + if len(sys.argv) > 1: + _source = sys.argv[1] + else: + _source = "o_clock_entry" + + try: + while True: + + print("Enter O-Clock Bearing (1-12):") + _val = input() + + try: + _val_int = int(_val) + + _bearing = (_val_int%12)*30 + + print(f"Sending Relative Bearing: {_bearing}") + + send_relative_bearing(_bearing, _source, heading_override=True) + except Exception as e: + print(f"Error handling input: {str(e)}") + except KeyboardInterrupt: + sys.exit(0) + +