kopia lustrzana https://github.com/glidernet/ogn-python
Speed up takeoff / landing detection
rodzic
b5f111c257
commit
dbda5a9c4b
|
@ -1,4 +1,4 @@
|
||||||
from datetime import datetime, timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from celery.utils.log import get_task_logger
|
from celery.utils.log import get_task_logger
|
||||||
from ogn.collect.celery import app
|
from ogn.collect.celery import app
|
||||||
|
@ -16,24 +16,33 @@ logger = get_task_logger(__name__)
|
||||||
def compute_takeoff_and_landing():
|
def compute_takeoff_and_landing():
|
||||||
logger.info("Compute takeoffs and landings.")
|
logger.info("Compute takeoffs and landings.")
|
||||||
|
|
||||||
takeoff_speed = 30
|
# takeoff / landing detection is based on 3 consecutive points
|
||||||
landing_speed = 30
|
takeoff_speed = 55 # takeoff detection: 1st point below, 2nd and 3rd above this limit
|
||||||
|
landing_speed = 40 # landing detection: 1st point above, 2nd and 3rd below this limit
|
||||||
|
duration = 100 # the points must not exceed this duration
|
||||||
|
radius = 0.05 # the points must not exceed this radius (degree!) around the 2nd point
|
||||||
|
|
||||||
# calculate the time where the computation starts
|
# calculate the time where the computation starts
|
||||||
last_takeoff_landing_query = app.session.query(func.max(TakeoffLanding.timestamp))
|
last_takeoff_landing_query = app.session.query(func.max(TakeoffLanding.timestamp))
|
||||||
last_takeoff_landing = last_takeoff_landing_query.one()[0]
|
begin_computation = last_takeoff_landing_query.one()[0]
|
||||||
if last_takeoff_landing is None:
|
if begin_computation is None:
|
||||||
# if the table is empty
|
# if the table is empty
|
||||||
last_takeoff_landing = datetime(2015, 1, 1, 0, 0, 0)
|
last_takeoff_landing_query = app.session.query(func.min(AircraftBeacon.timestamp))
|
||||||
|
begin_computation = last_takeoff_landing_query.one()[0]
|
||||||
|
if begin_computation is None:
|
||||||
|
return 0
|
||||||
else:
|
else:
|
||||||
# we get the beacons async. to be safe we delete takeoffs/landings from last 5 minutes and recalculate from then
|
# we get the beacons async. to be safe we delete takeoffs/landings from last 24 hours and recalculate from then
|
||||||
# alternative: takeoff/landing has a primary key (timestamp,address)
|
begin_computation = begin_computation - timedelta(hours=24)
|
||||||
last_takeoff_landing = last_takeoff_landing - timedelta(minutes=5)
|
|
||||||
app.session.query(TakeoffLanding) \
|
app.session.query(TakeoffLanding) \
|
||||||
.filter(TakeoffLanding.timestamp > last_takeoff_landing) \
|
.filter(TakeoffLanding.timestamp >= begin_computation) \
|
||||||
.delete()
|
.delete()
|
||||||
|
end_computation = begin_computation + timedelta(days=30)
|
||||||
|
|
||||||
# make a query with current, previous and next position, so we can detect takeoffs and landings
|
logger.debug("Calculate takeoffs and landings between {} and {}"
|
||||||
|
.format(begin_computation, end_computation))
|
||||||
|
|
||||||
|
# make a query with current, previous and next position
|
||||||
sq = app.session.query(
|
sq = app.session.query(
|
||||||
AircraftBeacon.address,
|
AircraftBeacon.address,
|
||||||
func.lag(AircraftBeacon.address).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('address_prev'),
|
func.lag(AircraftBeacon.address).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('address_prev'),
|
||||||
|
@ -59,11 +68,12 @@ def compute_takeoff_and_landing():
|
||||||
AircraftBeacon.altitude,
|
AircraftBeacon.altitude,
|
||||||
func.lag(AircraftBeacon.altitude).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('altitude_prev'),
|
func.lag(AircraftBeacon.altitude).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('altitude_prev'),
|
||||||
func.lead(AircraftBeacon.altitude).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('altitude_next')) \
|
func.lead(AircraftBeacon.altitude).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('altitude_next')) \
|
||||||
.filter(AircraftBeacon.timestamp > last_takeoff_landing) \
|
.filter(AircraftBeacon.timestamp >= begin_computation) \
|
||||||
|
.filter(AircraftBeacon.timestamp <= end_computation) \
|
||||||
.order_by(func.date(AircraftBeacon.timestamp), AircraftBeacon.address, AircraftBeacon.timestamp) \
|
.order_by(func.date(AircraftBeacon.timestamp), AircraftBeacon.address, AircraftBeacon.timestamp) \
|
||||||
.subquery()
|
.subquery()
|
||||||
|
|
||||||
# find takeoffs and landings (look at the trigger_speed)
|
# find takeoffs and landings
|
||||||
takeoff_landing_query = app.session.query(
|
takeoff_landing_query = app.session.query(
|
||||||
sq.c.address,
|
sq.c.address,
|
||||||
sq.c.name,
|
sq.c.name,
|
||||||
|
@ -82,9 +92,12 @@ def compute_takeoff_and_landing():
|
||||||
and_(sq.c.ground_speed_prev > landing_speed, # landing
|
and_(sq.c.ground_speed_prev > landing_speed, # landing
|
||||||
sq.c.ground_speed < landing_speed,
|
sq.c.ground_speed < landing_speed,
|
||||||
sq.c.ground_speed_next < landing_speed))) \
|
sq.c.ground_speed_next < landing_speed))) \
|
||||||
|
.filter(sq.c.timestamp_next - sq.c.timestamp_prev < timedelta(seconds=duration)) \
|
||||||
|
.filter(and_(func.ST_DFullyWithin(sq.c.location, sq.c.location_wkt_prev, radius),
|
||||||
|
func.ST_DFullyWithin(sq.c.location, sq.c.location_wkt_next, radius))) \
|
||||||
.order_by(func.date(sq.c.timestamp), sq.c.timestamp)
|
.order_by(func.date(sq.c.timestamp), sq.c.timestamp)
|
||||||
|
|
||||||
# ... and save the
|
# ... and save them
|
||||||
ins = insert(TakeoffLanding).from_select((TakeoffLanding.address, TakeoffLanding.name, TakeoffLanding.receiver_name, TakeoffLanding.timestamp, TakeoffLanding.location_wkt, TakeoffLanding.track, TakeoffLanding.ground_speed, TakeoffLanding.altitude, TakeoffLanding.is_takeoff), takeoff_landing_query)
|
ins = insert(TakeoffLanding).from_select((TakeoffLanding.address, TakeoffLanding.name, TakeoffLanding.receiver_name, TakeoffLanding.timestamp, TakeoffLanding.location_wkt, TakeoffLanding.track, TakeoffLanding.ground_speed, TakeoffLanding.altitude, TakeoffLanding.is_takeoff), takeoff_landing_query)
|
||||||
result = app.session.execute(ins)
|
result = app.session.execute(ins)
|
||||||
counter = result.rowcount
|
counter = result.rowcount
|
||||||
|
|
Ładowanie…
Reference in New Issue