kopia lustrzana https://github.com/glidernet/python-ogn-client
Added fast bearing calculation
rodzic
8dba8f7491
commit
3d36b88996
|
@ -1,7 +1,7 @@
|
|||
# CHANGELOG
|
||||
## not released
|
||||
- client: changed socket mode from blocking to timeout (fixes #89)
|
||||
- parser: Added optionally distance calculation (fixes #86)
|
||||
- parser: Added optional distance/bearing calculation (fixes #86)
|
||||
- parser: Added support for weather data from FANET ground stations
|
||||
- parser: Added support for latency in receiver messages (OGNSDR) (fixes #87)
|
||||
- parser: Added support for reference_timestamp with tzinfo (fixes #84)
|
||||
|
|
|
@ -21,7 +21,7 @@ from ogn.parser.aprs_comment.generic_parser import GenericParser
|
|||
positions = {}
|
||||
|
||||
|
||||
def parse(aprs_message, reference_timestamp=None, calculate_distances=False):
|
||||
def parse(aprs_message, reference_timestamp=None, calculate_relations=False):
|
||||
global positions
|
||||
|
||||
if reference_timestamp is None:
|
||||
|
@ -33,11 +33,12 @@ def parse(aprs_message, reference_timestamp=None, calculate_distances=False):
|
|||
dstcall=message['dstcall'],
|
||||
aprs_type=message['aprs_type']))
|
||||
|
||||
if message['aprs_type'].startswith('position') and calculate_distances is True:
|
||||
if message['aprs_type'].startswith('position') and calculate_relations is True:
|
||||
positions[message['name']] = (message['longitude'], message['latitude'])
|
||||
if message['receiver_name'] in positions:
|
||||
cheap_ruler = CheapRuler((message['latitude'] + positions[message['receiver_name']][1]) / 2.0)
|
||||
message['distance'] = cheap_ruler.distance((message['longitude'], message['latitude']), positions[message['receiver_name']])
|
||||
message['bearing'] = cheap_ruler.bearing((message['longitude'], message['latitude']), positions[message['receiver_name']])
|
||||
|
||||
return message
|
||||
|
||||
|
|
|
@ -55,11 +55,14 @@ def createTimestamp(time_string, reference_timestamp):
|
|||
return result
|
||||
|
||||
|
||||
MATH_PI = 3.14159265359
|
||||
|
||||
|
||||
class CheapRuler():
|
||||
"""Extreme fast distance calculating for distances below 500km."""
|
||||
|
||||
def __init__(self, lat):
|
||||
c = math.cos(lat * 3.14159265359 / 180)
|
||||
c = math.cos(lat * MATH_PI / 180)
|
||||
c2 = 2 * c * c - 1
|
||||
c3 = 2 * c * c2 - c
|
||||
c4 = 2 * c * c3 - c2
|
||||
|
@ -69,8 +72,18 @@ class CheapRuler():
|
|||
self.ky = 1000 * (111.13209 - 0.56605 * c2 + 0.0012 * c4) # latitude correction
|
||||
|
||||
def distance(self, a, b):
|
||||
"""Points a and b are from tuple(lon,lat)."""
|
||||
"""Distance between point a and b. A point is a tuple(lon,lat)."""
|
||||
|
||||
dx = (a[0] - b[0]) * self.kx
|
||||
dy = (a[1] - b[1]) * self.ky
|
||||
return math.sqrt(dx * dx + dy * dy)
|
||||
|
||||
def bearing(self, a, b):
|
||||
"""Returns the bearing from point a to point b."""
|
||||
|
||||
dx = (b[0] - a[0]) * self.kx
|
||||
dy = (b[1] - a[1]) * self.ky
|
||||
if dx == 0 and dy == 0:
|
||||
return 0
|
||||
else:
|
||||
return math.atan2(-dy, dx) * 180 / MATH_PI + 90
|
||||
|
|
|
@ -40,7 +40,7 @@ class TestStringMethods(unittest.TestCase):
|
|||
|
||||
self.proceed_test_data(test_data)
|
||||
|
||||
def test_cheap_ruler(self):
|
||||
def test_cheap_ruler_distance(self):
|
||||
koenigsdf = (11.465353, 47.829825)
|
||||
hochkoenig = (13.062405, 47.420516)
|
||||
|
||||
|
@ -48,6 +48,14 @@ class TestStringMethods(unittest.TestCase):
|
|||
distance = cheap_ruler.distance(koenigsdf, hochkoenig)
|
||||
self.assertAlmostEqual(distance, 128381.47612138899)
|
||||
|
||||
def test_cheap_ruler_bearing(self):
|
||||
koenigsdf = (11.465353, 47.829825)
|
||||
hochkoenig = (13.062405, 47.420516)
|
||||
|
||||
cheap_ruler = CheapRuler((koenigsdf[1] + hochkoenig[1]) / 2)
|
||||
bearing = cheap_ruler.bearing(koenigsdf, hochkoenig)
|
||||
self.assertAlmostEqual(bearing, 110.761300063515)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
Ładowanie…
Reference in New Issue