kopia lustrzana https://github.com/glidernet/ogn-python
Merged window function, this is 10% faster and looks better
rodzic
3956a11aa5
commit
5a31d902ab
|
@ -54,7 +54,22 @@ def update_takeoff_landing(session=None):
|
|||
func.lead(AircraftBeacon.id).over(order_by=wo).label('id_next'),
|
||||
AircraftBeacon.device_id,
|
||||
func.lag(AircraftBeacon.device_id).over(order_by=wo).label('device_id_prev'),
|
||||
func.lead(AircraftBeacon.device_id).over(order_by=wo).label('device_id_next')) \
|
||||
func.lead(AircraftBeacon.device_id).over(order_by=wo).label('device_id_next'),
|
||||
AircraftBeacon.timestamp,
|
||||
func.lag(AircraftBeacon.timestamp).over(order_by=wo).label('timestamp_prev'),
|
||||
func.lead(AircraftBeacon.timestamp).over(order_by=wo).label('timestamp_next'),
|
||||
AircraftBeacon.location_wkt,
|
||||
func.lag(AircraftBeacon.location_wkt).over(order_by=wo).label('location_wkt_prev'),
|
||||
func.lead(AircraftBeacon.location_wkt).over(order_by=wo).label('location_wkt_next'),
|
||||
AircraftBeacon.track,
|
||||
func.lag(AircraftBeacon.track).over(order_by=wo).label('track_prev'),
|
||||
func.lead(AircraftBeacon.track).over(order_by=wo).label('track_next'),
|
||||
AircraftBeacon.ground_speed,
|
||||
func.lag(AircraftBeacon.ground_speed).over(order_by=wo).label('ground_speed_prev'),
|
||||
func.lead(AircraftBeacon.ground_speed).over(order_by=wo).label('ground_speed_next'),
|
||||
AircraftBeacon.altitude,
|
||||
func.lag(AircraftBeacon.altitude).over(order_by=wo).label('altitude_prev'),
|
||||
func.lead(AircraftBeacon.altitude).over(order_by=wo).label('altitude_next')) \
|
||||
.filter(AircraftBeacon.id == beacon_selection.c.id) \
|
||||
.subquery()
|
||||
|
||||
|
@ -63,77 +78,48 @@ def update_takeoff_landing(session=None):
|
|||
.filter(sq.c.device_id_prev == sq.c.device_id == sq.c.device_id_next) \
|
||||
.subquery()
|
||||
|
||||
# Get timestamps, locations, tracks, ground_speeds and altitudes
|
||||
prev_ab = aliased(AircraftBeacon, name="prev_ab")
|
||||
lead_ab = aliased(AircraftBeacon, name="lead_ab")
|
||||
|
||||
# find possible takeoffs and landings
|
||||
sq3 = session.query(
|
||||
sq2.c.id,
|
||||
sq2.c.id_prev,
|
||||
sq2.c.id_next,
|
||||
sq2.c.device_id,
|
||||
sq2.c.device_id_prev,
|
||||
sq2.c.device_id_next,
|
||||
AircraftBeacon.timestamp,
|
||||
prev_ab.timestamp.label('timestamp_prev'),
|
||||
lead_ab.timestamp.label('timestamp_next'),
|
||||
AircraftBeacon.location_wkt,
|
||||
prev_ab.location_wkt.label('location_wkt_prev'),
|
||||
lead_ab.location_wkt.label('location_wkt_next'),
|
||||
AircraftBeacon.track,
|
||||
prev_ab.track.label('track_prev'),
|
||||
lead_ab.track.label('track_next'),
|
||||
AircraftBeacon.ground_speed,
|
||||
prev_ab.ground_speed.label('ground_speed_prev'),
|
||||
lead_ab.ground_speed.label('ground_speed_next'),
|
||||
AircraftBeacon.altitude,
|
||||
prev_ab.altitude.label('altitude_prev'),
|
||||
lead_ab.altitude.label('altitude_next')) \
|
||||
.filter(and_(sq2.c.id == AircraftBeacon.id, sq2.c.id_prev == prev_ab.id, sq2.c.id_next == lead_ab.id)) \
|
||||
.subquery()
|
||||
|
||||
# find possible takeoffs and landings
|
||||
sq4 = session.query(
|
||||
sq3.c.id,
|
||||
sq3.c.timestamp,
|
||||
case([(sq3.c.ground_speed > takeoff_speed, sq3.c.location_wkt_prev), # on takeoff we take the location from the previous fix because it is nearer to the airport
|
||||
(sq3.c.ground_speed < landing_speed, sq3.c.location)]).label('location'),
|
||||
case([(sq3.c.ground_speed > takeoff_speed, sq3.c.track),
|
||||
(sq3.c.ground_speed < landing_speed, sq3.c.track_prev)]).label('track'), # on landing we take the track from the previous fix because gliders tend to leave the runway quickly
|
||||
sq3.c.ground_speed,
|
||||
sq3.c.altitude,
|
||||
case([(sq3.c.ground_speed > takeoff_speed, True),
|
||||
(sq3.c.ground_speed < landing_speed, False)]).label('is_takeoff'),
|
||||
sq3.c.device_id) \
|
||||
.filter(sq3.c.timestamp_next - sq3.c.timestamp_prev < timedelta(seconds=duration)) \
|
||||
.filter(and_(func.ST_DFullyWithin(sq3.c.location, sq3.c.location_wkt_prev, radius),
|
||||
func.ST_DFullyWithin(sq3.c.location, sq3.c.location_wkt_next, radius))) \
|
||||
.filter(or_(and_(sq3.c.ground_speed_prev < takeoff_speed, # takeoff
|
||||
sq3.c.ground_speed > takeoff_speed,
|
||||
sq3.c.ground_speed_next > takeoff_speed),
|
||||
and_(sq3.c.ground_speed_prev > landing_speed, # landing
|
||||
sq3.c.ground_speed < landing_speed,
|
||||
sq3.c.ground_speed_next < landing_speed))) \
|
||||
sq2.c.timestamp,
|
||||
case([(sq2.c.ground_speed > takeoff_speed, sq2.c.location_wkt_prev), # on takeoff we take the location from the previous fix because it is nearer to the airport
|
||||
(sq2.c.ground_speed < landing_speed, sq2.c.location)]).label('location'),
|
||||
case([(sq2.c.ground_speed > takeoff_speed, sq2.c.track),
|
||||
(sq2.c.ground_speed < landing_speed, sq2.c.track_prev)]).label('track'), # on landing we take the track from the previous fix because gliders tend to leave the runway quickly
|
||||
sq2.c.ground_speed,
|
||||
sq2.c.altitude,
|
||||
case([(sq2.c.ground_speed > takeoff_speed, True),
|
||||
(sq2.c.ground_speed < landing_speed, False)]).label('is_takeoff'),
|
||||
sq2.c.device_id) \
|
||||
.filter(sq2.c.timestamp_next - sq2.c.timestamp_prev < timedelta(seconds=duration)) \
|
||||
.filter(and_(func.ST_DFullyWithin(sq2.c.location, sq2.c.location_wkt_prev, radius),
|
||||
func.ST_DFullyWithin(sq2.c.location, sq2.c.location_wkt_next, radius))) \
|
||||
.filter(or_(and_(sq2.c.ground_speed_prev < takeoff_speed, # takeoff
|
||||
sq2.c.ground_speed > takeoff_speed,
|
||||
sq2.c.ground_speed_next > takeoff_speed),
|
||||
and_(sq2.c.ground_speed_prev > landing_speed, # landing
|
||||
sq2.c.ground_speed < landing_speed,
|
||||
sq2.c.ground_speed_next < landing_speed))) \
|
||||
.subquery()
|
||||
|
||||
# consider them if they are near a airport
|
||||
sq5 = session.query(
|
||||
sq4.c.timestamp,
|
||||
sq4.c.track,
|
||||
sq4.c.is_takeoff,
|
||||
sq4.c.device_id,
|
||||
sq4 = session.query(
|
||||
sq3.c.timestamp,
|
||||
sq3.c.track,
|
||||
sq3.c.is_takeoff,
|
||||
sq3.c.device_id,
|
||||
Airport.id.label('airport_id')) \
|
||||
.filter(and_(func.ST_DFullyWithin(sq4.c.location, Airport.location_wkt, airport_radius),
|
||||
between(sq4.c.altitude, Airport.altitude - airport_delta, Airport.altitude + airport_delta))) \
|
||||
.filter(and_(func.ST_DFullyWithin(sq3.c.location, Airport.location_wkt, airport_radius),
|
||||
between(sq3.c.altitude, Airport.altitude - airport_delta, Airport.altitude + airport_delta))) \
|
||||
.filter(between(Airport.style, 2, 5)) \
|
||||
.subquery()
|
||||
|
||||
# consider them only if they are not already existing in db
|
||||
takeoff_landing_query = session.query(sq5) \
|
||||
takeoff_landing_query = session.query(sq4) \
|
||||
.filter(~exists().where(
|
||||
and_(TakeoffLanding.timestamp == sq5.c.timestamp,
|
||||
TakeoffLanding.device_id == sq5.c.device_id,
|
||||
TakeoffLanding.airport_id == sq5.c.airport_id)))
|
||||
and_(TakeoffLanding.timestamp == sq4.c.timestamp,
|
||||
TakeoffLanding.device_id == sq4.c.device_id,
|
||||
TakeoffLanding.airport_id == sq4.c.airport_id)))
|
||||
|
||||
# ... and save them
|
||||
ins = insert(TakeoffLanding).from_select((TakeoffLanding.timestamp,
|
||||
|
|
Ładowanie…
Reference in New Issue