def _get_flight_path(flight, threshold=0.001, max_points=3000): num_levels = 4 zoom_factor = 4 zoom_levels = [0] zoom_levels.extend([ round(-math.log( 32.0 / 45.0 * (threshold * pow(zoom_factor, num_levels - i - 1)), 2)) for i in range(1, num_levels) ]) xcsoar_flight = xcsoar.Flight( files.filename_to_path(flight.igc_file.filename)) if flight.qnh: xcsoar_flight.setQNH(flight.qnh) begin = flight.takeoff_time - timedelta(seconds=2 * 60) end = flight.landing_time + timedelta(seconds=2 * 60) if begin > end: begin = datetime.min end = datetime.max xcsoar_flight.reduce( begin=begin, end=end, num_levels=num_levels, zoom_factor=zoom_factor, threshold=threshold, max_points=max_points, ) encoded_flight = xcsoar_flight.encode() points = encoded_flight["locations"] barogram_t = encoded_flight["times"] barogram_h = encoded_flight["altitude"] enl = encoded_flight["enl"] elevations_t, elevations_h = _get_elevations(flight) contest_traces = _get_contest_traces(flight) geoid_height = (egm96_height(flight.takeoff_location) if flight.takeoff_location else 0) return dict( points=points, barogram_t=barogram_t, barogram_h=barogram_h, enl=enl, contests=contest_traces, elevations_t=elevations_t, elevations_h=elevations_h, sfid=flight.id, geoid=geoid_height, )
def get_airspace_infringements(flight_path, qnh=None): # Convert the coordinate into a list of tuples coordinates = [(c.location["longitude"], c.location["latitude"]) for c in flight_path] # Create a shapely LineString object from the coordinates linestring = LineString(coordinates) bbox = from_shape(box(*linestring.bounds), srid=4326) airspaces = (db.session.query(Airspace).filter( Airspace.the_geom.intersects(bbox)).all()) if not airspaces: return dict() xcs_airspace = xcsoar.Airspaces() for airspace in airspaces: if airspace.airspace_class not in current_app.config[ "SKYLINES_AIRSPACE_CHECK"]: continue poly = list(to_shape(airspace.the_geom).exterior.coords) coords = [dict(latitude=c[1], longitude=c[0]) for c in poly] top, top_ref = airspace.extract_top base, base_ref = airspace.extract_base if top_ref == "NOTAM" or top_ref == "UNKNOWN": top_ref = "MSL" if base_ref == "NOTAM" or base_ref == "UNKNOWN": base_ref = "MSL" xcs_airspace.addPolygon( coords, str(airspace.id), airspace.airspace_class, base, base_ref.upper(), top, top_ref.upper(), ) xcs_airspace.optimise() xcs_flight = xcsoar.Flight(flight_path) if qnh: xcs_flight.setQNH(qnh) infringements = xcs_airspace.findIntrusions(xcs_flight) # Replace airspace id string with ints in returned infringements return dict((int(k), v) for k, v in infringements.items())
def processThermal(my_igc, out_dir, writer, ef_writer): flight_id = my_igc.split('/')[-1].split('.')[0] print("Processing flight {}...".format(flight_id)) flight = xcsoar.Flight(my_igc) times = flight.times() if len(times) == 0: print("Skipping file {}!".format(flight_id)) ef_writer.writerow((str(flight_id))) return for dtime in times: takeoff = dtime['takeoff'] try: release = dtime['release'] except KeyError: print("No release detected!") release = dtime['takeoff'] landing = dtime['landing'] analysis = flight.analyse(takeoff=takeoff['time'], scoring_start=release['time'], scoring_end=landing['time'], landing=landing['time']) fixes = flight.path(release['time'], landing['time']) for phase in analysis['phases']: bottom_lon = 0 bottom_lat = 0 bottom_heigth = 0 for fix in fixes: if fix[0] == phase['start_time']: bottom_fix = fix[2] bottom_lon = bottom_fix['longitude'] bottom_lat = bottom_fix['latitude'] bottom_heigth = fix[4] if fix[0] == phase['end_time']: top_fix = fix[2] top_lon = top_fix['longitude'] top_lat = top_fix['latitude'] top_heigth = fix[4] if bottom_lat < 49 and top_lat < 49 and phase[ 'alt_diff'] > 305 and phase['vario'] < 8 and phase[ 'vario'] > 0 and bottom_heigth > 0: if phase['type'] == 'circling': thermal_id = str(uuid.uuid4()) writer.writerow( (thermal_id, flight_id, bottom_lon, bottom_lat, bottom_heigth, phase['vario'], phase['alt_diff'], phase['start_time'].isoformat(' ')))
def _get_flight_path(flight, threshold=0.001, max_points=3000): num_levels = 4 zoom_factor = 4 zoom_levels = [0] zoom_levels.extend([ round(-math.log( 32.0 / 45.0 * (threshold * pow(zoom_factor, num_levels - i - 1)), 2)) for i in range(1, num_levels) ]) xcsoar_flight = xcsoar.Flight( files.filename_to_path(flight.igc_file.filename)) begin = flight.takeoff_time - timedelta(seconds=2 * 60) end = flight.landing_time + timedelta(seconds=2 * 60) if begin > end: begin = datetime.min end = datetime.max xcsoar_flight.reduce(begin=begin, end=end, num_levels=num_levels, zoom_factor=zoom_factor, threshold=threshold, max_points=max_points) encoded_flight = xcsoar_flight.encode() encoded = dict(points=encoded_flight['locations'], levels=encoded_flight['levels'], zoom_levels=zoom_levels) barogram_t = encoded_flight['times'] barogram_h = encoded_flight['altitude'] enl = encoded_flight['enl'] elevations_t, elevations_h = _get_elevations(flight) contest_traces = _get_contest_traces(flight) return dict(encoded=encoded, zoom_levels=zoom_levels, num_levels=num_levels, barogram_t=barogram_t, barogram_h=barogram_h, enl=enl, contests=contest_traces, elevations_t=elevations_t, elevations_h=elevations_h, sfid=flight.id)
def _get_flight_path(pilot, threshold=0.001, last_update=None): fp = _get_flight_path2(pilot, last_update=last_update) if not fp: return None num_levels = 4 zoom_factor = 4 zoom_levels = [0] zoom_levels.extend([ round(-log( 32.0 / 45.0 * (threshold * pow(zoom_factor, num_levels - i - 1)), 2)) for i in range(1, num_levels) ]) xcsoar_flight = xcsoar.Flight(fp) xcsoar_flight.reduce(num_levels=num_levels, zoom_factor=zoom_factor, threshold=threshold) encoded_flight = xcsoar_flight.encode() points = encoded_flight["locations"] barogram_t = encoded_flight["times"] barogram_h = encoded_flight["altitude"] enl = encoded_flight["enl"] fp_reduced = map(lambda line: FlightPathFix(*line), xcsoar_flight.path()) elevations = xcsoar.encode( [ fix.elevation if fix.elevation is not None else UNKNOWN_ELEVATION for fix in fp_reduced ], method="signed", ) geoid_height = egm96_height( Location(latitude=fp[0].location["latitude"], longitude=fp[0].location["longitude"])) return dict( points=points, barogram_t=barogram_t, barogram_h=barogram_h, enl=enl, elevations=elevations, geoid=geoid_height, )
def run_analyse_flight(flight, full=None, triangle=None, sprint=None): limits = get_limits() filename = files.filename_to_path(flight.igc_file.filename) xcsoar_flight = xcsoar.Flight( flight_path(filename, add_elevation=True, max_points=None)) analysis_times = get_analysis_times(xcsoar_flight.times()) if flight.takeoff_time: analysis_times['takeoff']['time'] = flight.takeoff_time analysis_times['takeoff']['location'][ 'latitude'] = flight.takeoff_location.latitude analysis_times['takeoff']['location'][ 'longitude'] = flight.takeoff_location.longitude if flight.scoring_start_time: analysis_times['scoring_start']['time'] = flight.scoring_start_time if flight.scoring_end_time: analysis_times['scoring_end']['time'] = flight.scoring_end_time if flight.landing_time: analysis_times['landing']['time'] = flight.landing_time analysis_times['landing']['location'][ 'latitude'] = flight.landing_location.latitude analysis_times['landing']['location'][ 'longitude'] = flight.landing_location.longitude if analysis_times: analysis = xcsoar_flight.analyse( analysis_times['takeoff']['time'], analysis_times['scoring_start']['time'] if analysis_times['scoring_start'] else None, analysis_times['scoring_end']['time'] if analysis_times['scoring_end'] else None, analysis_times['landing']['time'], full=full, triangle=triangle, sprint=sprint, max_iterations=limits['iter_limit'], max_tree_size=limits['tree_size_limit']) analysis['events'] = analysis_times return analysis else: return None
def _get_flight_path(pilot, threshold=0.001, last_update=None): fp = _get_flight_path2(pilot, last_update=last_update) if not fp: return None num_levels = 4 zoom_factor = 4 zoom_levels = [0] zoom_levels.extend([ round(-log( 32.0 / 45.0 * (threshold * pow(zoom_factor, num_levels - i - 1)), 2)) for i in range(1, num_levels) ]) xcsoar_flight = xcsoar.Flight(fp) xcsoar_flight.reduce(num_levels=num_levels, zoom_factor=zoom_factor, threshold=threshold) encoded_flight = xcsoar_flight.encode() encoded = dict(points=encoded_flight['locations'], levels=encoded_flight['levels'], zoom_levels=zoom_levels) barogram_t = encoded_flight['times'] barogram_h = encoded_flight['altitude'] enl = encoded_flight['enl'] fp_reduced = map(lambda line: FlightPathFix(*line), xcsoar_flight.path()) elevations = xcsoar.encode([ fix.elevation if fix.elevation is not None else UNKNOWN_ELEVATION for fix in fp_reduced ], method="signed") return dict(encoded=encoded, zoom_levels=zoom_levels, num_levels=num_levels, barogram_t=barogram_t, barogram_h=barogram_h, enl=enl, elevations=elevations)
def processIGC(my_igc, out_dir, thermals_kml, cruise_kml, ef_writer): flight_id = my_igc.split('/')[-1].split('.')[0] print("Processing flight {}...".format(flight_id)) flight = xcsoar.Flight(my_igc) kml = simplekml.Kml() times = flight.times() if len(times) == 0: print("Skipping file {}!".format(flight_id)) ef_writer.writerow((flight_id)) return for dtime in times: takeoff = dtime['takeoff'] try: release = dtime['release'] except KeyError: print("No release detected!") release = dtime['takeoff'] landing = dtime['landing'] analysis = flight.analyse(takeoff=takeoff['time'], scoring_start=release['time'], scoring_end=landing['time'], landing=landing['time']) fixes = flight.path(release['time'], landing['time']) for phase in analysis['phases']: bottom_lon = 0 bottom_lat = 0 bottom_heigth = 0 for fix in fixes: if fix[0] == phase['start_time']: bottom_fix = fix[2] bottom_lon = bottom_fix['longitude'] bottom_lat = bottom_fix['latitude'] bottom_heigth = fix[4] if fix[0] == phase['end_time']: top_fix = fix[2] top_lon = top_fix['longitude'] top_lat = top_fix['latitude'] top_heigth = fix[4] if bottom_lat < 49 and top_lat < 49: if phase['type'] == 'circling': kml.newpoint(description=str(phase) + "\n" + str(fix), coords=[(bottom_lon, bottom_lat, bottom_heigth)], altitudemode='absolute', extrude=True) thermals_kml.newpoint( description=str(phase) + "\n" + str(fix), coords=[(bottom_lon, bottom_lat, bottom_heigth)], altitudemode='absolute', extrude=True) if phase['type'] == 'cruise': if phase['vario'] > 0: cruise_kml.newlinestring( description=str(phase) + "\n" + str(fix), coords=[(bottom_lon, bottom_lat, bottom_heigth), (top_lon, top_lat, top_heigth)], altitudemode='absolute') kml.save('{}/{}.kml'.format(out_dir, flight_id))
def run_analyse_flight(flight, full=None, triangle=None, sprint=None, fp=None): limits = get_limits() if not fp: filename = files.filename_to_path(flight.igc_file.filename) fp = flight_path(filename, add_elevation=True, max_points=None) if len(fp) < 2: return None, None xcsoar_flight = xcsoar.Flight(fp) analysis_times = get_analysis_times(xcsoar_flight.times()) # Fallback if automated flight detection has failed - check if first and last # fix could be ok and use both of them for takeoff and landing if not analysis_times and fp[0].datetime < fp[-1].datetime: analysis_times = dict(takeoff=dict(time=fp[0].datetime, location=fp[0].location), scoring_start=None, scoring_end=None, landing=dict(time=fp[-1].datetime, location=fp[-1].location)) # Give priority to already stored takeoff and landing times if flight.takeoff_time and flight.takeoff_location: analysis_times['takeoff']['time'] = flight.takeoff_time analysis_times['takeoff']['location'] = dict(latitude=flight.takeoff_location.latitude, longitude=flight.takeoff_location.longitude) if flight.landing_time and flight.landing_location: analysis_times['landing']['time'] = flight.landing_time analysis_times['landing']['location'] = dict(latitude=flight.landing_location.latitude, longitude=flight.landing_location.longitude) # If no scoring window was found fallback to takeoff - landing if not analysis_times['scoring_start']: analysis_times['scoring_start'] = analysis_times['takeoff'].copy() if not analysis_times['scoring_end']: analysis_times['scoring_end'] = analysis_times['landing'].copy() # And give priority to already stored scoring times if flight.scoring_start_time: analysis_times['scoring_start']['time'] = flight.scoring_start_time if flight.scoring_end_time: analysis_times['scoring_end']['time'] = flight.scoring_end_time if analysis_times: analysis = xcsoar_flight.analyse(analysis_times['takeoff']['time'] - datetime.timedelta(seconds=300), analysis_times['scoring_start']['time'], analysis_times['scoring_end']['time'], analysis_times['landing']['time'] + datetime.timedelta(seconds=300), full=full, triangle=triangle, sprint=sprint, max_iterations=limits['iter_limit'], max_tree_size=limits['tree_size_limit']) analysis['events'] = analysis_times return analysis, fp else: return None, None
from __future__ import print_function import xcsoar import argparse from pprint import pprint # Parse command line parameters parser = argparse.ArgumentParser( description='Please give me a IGC file name...') parser.add_argument('file_name', type=str) args = parser.parse_args() print("Init xcsoar.Flight, don't store flight in memory") flight = xcsoar.Flight(args.file_name, False) times = flight.times() for dtime in times: takeoff = dtime['takeoff'] release = dtime['release'] landing = dtime['landing'] print("Takeoff: {}, location {}".format(takeoff['time'], takeoff['location'])) print("Release: {}, location {}".format(release['time'], release['location'])) print("Landing: {}, location {}".format(landing['time'], landing['location']))