kopia lustrzana https://github.com/glidernet/ogn-python
Add (slow) [radius, theta, phi] calculation
rodzic
88406a31d0
commit
6cc6378496
|
@ -1,8 +1,13 @@
|
||||||
import os
|
import os
|
||||||
import importlib
|
import importlib
|
||||||
from sqlalchemy import create_engine
|
|
||||||
|
from sqlalchemy import create_engine, and_, desc
|
||||||
|
from sqlalchemy.sql import null
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
|
||||||
|
from ogn.model import AircraftBeacon, ReceiverBeacon
|
||||||
|
from ogn.utils import wgs84_to_sphere
|
||||||
|
|
||||||
|
|
||||||
os.environ.setdefault('OGN_CONFIG_MODULE', 'config.default')
|
os.environ.setdefault('OGN_CONFIG_MODULE', 'config.default')
|
||||||
|
|
||||||
|
@ -11,3 +16,26 @@ engine = create_engine(config.SQLALCHEMY_DATABASE_URI, echo=False)
|
||||||
|
|
||||||
Session = sessionmaker(bind=engine)
|
Session = sessionmaker(bind=engine)
|
||||||
session = Session()
|
session = Session()
|
||||||
|
|
||||||
|
|
||||||
|
def update_receiver_childs(name):
|
||||||
|
last_receiver_beacon = session.query(ReceiverBeacon) \
|
||||||
|
.filter(ReceiverBeacon.name == name) \
|
||||||
|
.order_by(desc(ReceiverBeacon.timestamp)) \
|
||||||
|
.first()
|
||||||
|
|
||||||
|
if (last_receiver_beacon is None):
|
||||||
|
return
|
||||||
|
|
||||||
|
aircraft_beacons_query = session.query(AircraftBeacon) \
|
||||||
|
.filter(and_(AircraftBeacon.timestamp > last_receiver_beacon.timestamp,
|
||||||
|
AircraftBeacon.receiver_name == name,
|
||||||
|
AircraftBeacon.radius == null()))
|
||||||
|
|
||||||
|
for aircraft_beacon in aircraft_beacons_query.all():
|
||||||
|
[radius, theta, phi] = wgs84_to_sphere(last_receiver_beacon,
|
||||||
|
aircraft_beacon)
|
||||||
|
aircraft_beacon.radius = radius
|
||||||
|
aircraft_beacon.theta = theta
|
||||||
|
aircraft_beacon.phi = phi
|
||||||
|
session.commit()
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from ogn.gateway.client import ognGateway
|
from ogn.gateway.client import ognGateway
|
||||||
from ogn.commands.dbutils import session
|
from ogn.commands.dbutils import session, update_receiver_childs
|
||||||
|
from ogn.model import ReceiverBeacon
|
||||||
|
|
||||||
from manager import Manager
|
from manager import Manager
|
||||||
|
|
||||||
manager = Manager()
|
manager = Manager()
|
||||||
|
|
||||||
logging_formatstr = '%(asctime)s - %(levelname).4s - %(name)s - %(message)s'
|
logging_formatstr = '%(asctime)s - %(levelname).4s - %(name)s - %(message)s'
|
||||||
|
@ -33,6 +35,8 @@ def run(aprs_user='anon-dev', logfile='main.log', loglevel='INFO'):
|
||||||
gateway.connect()
|
gateway.connect()
|
||||||
|
|
||||||
def process_beacon(beacon):
|
def process_beacon(beacon):
|
||||||
|
if isinstance(beacon, ReceiverBeacon):
|
||||||
|
update_receiver_childs(beacon.name)
|
||||||
session.add(beacon)
|
session.add(beacon)
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
|
|
21
ogn/utils.py
21
ogn/utils.py
|
@ -60,3 +60,24 @@ def get_country_code(latitude, longitude):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
country_code = None
|
country_code = None
|
||||||
return country_code
|
return country_code
|
||||||
|
|
||||||
|
|
||||||
|
def wgs84_to_sphere(receiver_beacon, aircraft_beacon):
|
||||||
|
from math import pi, asin, sqrt, sin, cos, atan2
|
||||||
|
deg2rad = pi / 180
|
||||||
|
rad2deg = 180 / pi
|
||||||
|
|
||||||
|
lat1 = receiver_beacon.latitude * deg2rad
|
||||||
|
lon1 = receiver_beacon.longitude * deg2rad
|
||||||
|
alt1 = receiver_beacon.altitude
|
||||||
|
|
||||||
|
lat2 = aircraft_beacon.latitude * deg2rad
|
||||||
|
lon2 = aircraft_beacon.longitude * deg2rad
|
||||||
|
alt2 = aircraft_beacon.altitude
|
||||||
|
|
||||||
|
distance = 6366000 * 2 * asin(sqrt((sin((lat1 - lat2) / 2))**2 + cos(lat1) * cos(lat2) * (sin((lon1 - lon2) / 2))**2))
|
||||||
|
theta = atan2(alt2 - alt1, distance) * rad2deg
|
||||||
|
phi = atan2(sin(lon1 - lon2) * cos(lat2), cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon1 - lon2)) * rad2deg
|
||||||
|
|
||||||
|
radius = sqrt(distance**2 + (alt2 - alt1)**2)
|
||||||
|
return radius, theta, phi
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from ogn.utils import get_ddb, get_trackable, get_country_code
|
from ogn.utils import get_ddb, get_trackable, get_country_code, wgs84_to_sphere
|
||||||
from ogn.model import AddressOrigin
|
from ogn.model import AddressOrigin, Beacon
|
||||||
|
|
||||||
|
|
||||||
class TestStringMethods(unittest.TestCase):
|
class TestStringMethods(unittest.TestCase):
|
||||||
|
@ -43,3 +43,52 @@ class TestStringMethods(unittest.TestCase):
|
||||||
longitude = -0.0009119
|
longitude = -0.0009119
|
||||||
country_code = get_country_code(latitude, longitude)
|
country_code = get_country_code(latitude, longitude)
|
||||||
self.assertEqual(country_code, None)
|
self.assertEqual(country_code, None)
|
||||||
|
|
||||||
|
def test_wgs84_to_sphere(self):
|
||||||
|
receiver_beacon = Beacon()
|
||||||
|
receiver_beacon.latitude = 0
|
||||||
|
receiver_beacon.longitude = 0
|
||||||
|
receiver_beacon.altitude = 0
|
||||||
|
|
||||||
|
# delta: one latitude degree
|
||||||
|
aircraft_beacon = Beacon()
|
||||||
|
aircraft_beacon.latitude = -1
|
||||||
|
aircraft_beacon.longitude = 0
|
||||||
|
aircraft_beacon.altitude = 0
|
||||||
|
[radius, theta, phi] = wgs84_to_sphere(receiver_beacon, aircraft_beacon)
|
||||||
|
self.assertAlmostEqual(radius, 60 * 1852, -2)
|
||||||
|
self.assertEqual(theta, 0)
|
||||||
|
self.assertEqual(phi, 180)
|
||||||
|
|
||||||
|
# delta: one longitude degree at the equator
|
||||||
|
aircraft_beacon.latitude = 0
|
||||||
|
aircraft_beacon.longitude = -1
|
||||||
|
aircraft_beacon.altitude = 0
|
||||||
|
[radius, theta, phi] = wgs84_to_sphere(receiver_beacon, aircraft_beacon)
|
||||||
|
self.assertAlmostEqual(radius, 60 * 1852, -2)
|
||||||
|
self.assertEqual(theta, 0)
|
||||||
|
self.assertEqual(phi, 90)
|
||||||
|
|
||||||
|
# delta: 1000m altitude
|
||||||
|
aircraft_beacon.latitude = 0
|
||||||
|
aircraft_beacon.longitude = 0
|
||||||
|
aircraft_beacon.altitude = 1000
|
||||||
|
[radius, theta, phi] = wgs84_to_sphere(receiver_beacon, aircraft_beacon)
|
||||||
|
self.assertAlmostEqual(radius, 1000, 3)
|
||||||
|
self.assertEqual(theta, 90)
|
||||||
|
self.assertEqual(phi, 0)
|
||||||
|
|
||||||
|
# receiver
|
||||||
|
receiver_beacon.latitude = 48.865
|
||||||
|
receiver_beacon.longitude = 9.2225
|
||||||
|
receiver_beacon.altitude = 574
|
||||||
|
|
||||||
|
# aircraft beacon
|
||||||
|
aircraft_beacon.latitude = 48.74435
|
||||||
|
aircraft_beacon.longitude = 9.578
|
||||||
|
aircraft_beacon.altitude = 929
|
||||||
|
|
||||||
|
[radius, theta, phi] = wgs84_to_sphere(receiver_beacon, aircraft_beacon)
|
||||||
|
self.assertAlmostEqual(radius, 29265.6035812215, -1)
|
||||||
|
self.assertAlmostEqual(theta, 0.694979846308314, 5)
|
||||||
|
self.assertAlmostEqual(phi, -117.1275408121, 5)
|
||||||
|
|
Ładowanie…
Reference in New Issue