def read_file(cls, filename, track_id=None, par_id=None, config=None, print=print): """Reads track file and creates a track object""" track = cls(track_file=filename, track_id=track_id, par_id=par_id) track.get_type() if track.track_type in track_formats: """file is a valid track format""" if track.track_type == "igc": """using IGC reader from aerofile library""" if config: track.flight = Flight.create_from_file(filename, config_class=config) else: track.flight = Flight.create_from_file(filename, ) # elif track.type == "kml": """using KML reader created by Antonio Golfari To be rewritten for igc_lib""" # TODO update kml reader if we are interested in reading kml track format # with open(track.filename, 'r', encoding='utf-8') as f: # flight = kml.Reader().read(f) '''Check flight is valid I'm not creating a track without a valid flight because it would miss date property.''' # TODO We could change this part if we find a way to gen non-valid flight with timestamp property if track.valid: if not par_id: track.get_pilot() # track.get_glider() # track.flight = flight # track.date = epoch_to_date(track.flight.date_timestamp) return track else: data = {'par_id': par_id, 'track_id': track_id, 'Result': 'Not Yet Processed'} print( f'IGC does not meet quality standard set by igc parsing config. Notes:{track.flight.notes}') print(json.dumps(data) + '|result') else: print(f"File {filename} (pilot ID {par_id}) is NOT a valid track file.")
def save_tracklog_map_file(self, task, flight=None, second_interval=5): """ Creates the file to be used to display pilot's track on map""" from igc_lib import Flight from pathlib import Path from Defines import MAPOBJDIR import json if self.result_type not in ('abs', 'dnf', 'mindist', 'nyp'): ID = self.par_id if not self.ID else self.ID # registration needs to check that all pilots # have a unique ID, with option to use par_id as ID for all pilots if no ID is given print(f"{ID}. {self.name}: ({self.track_file})") if not flight: filename = Path(task.file_path, self.track_file) '''load track file''' flight = Flight.create_from_file(filename) data = create_tracklog_map_file(self, task, flight, second_interval) res_path = Path(MAPOBJDIR, 'tracks', str(task.id)) """check if directory already exists""" if not res_path.is_dir(): res_path.mkdir(mode=0o755) """creates a name for the file. par_id.track""" filename = f'{self.par_id}.track' fullname = Path(res_path, filename) """copy file""" try: with open(fullname, 'w') as f: json.dump(data, f) return fullname except: print('Error saving file:', fullname)
def verify_all_tracks(task, lib, airspace=None, print=print): """ Gets in input: task: Task object lib: Formula library module""" from igc_lib import Flight from pathlib import Path pilots = [p for p in task.pilots if p.result_type not in ('abs', 'dnf', 'mindist')] '''check if any track is missing''' if any(not Path(task.file_path, p.track_file).is_file() for p in pilots): print(f"The following tracks are missing from folder {task.file_path}:") for track in [p.track_file for p in pilots if not Path(task.file_path, p.track_file).is_file()]: print(f"{track}") return None print('getting tracks...') number_of_pilots = len(task.pilots) for track_number, pilot in enumerate(task.pilots, 1): print(f"{track_number}/{number_of_pilots}|track_counter") # print(f"type: {pilot.result_type}") if pilot.result_type not in ('abs', 'dnf', 'mindist'): print(f"{pilot.ID}. {pilot.name}: ({pilot.track_file})") filename = Path(task.file_path, pilot.track_file) '''load track file''' flight = Flight.create_from_file(filename) if flight: pilot.flight_notes = flight.notes if flight.valid: '''check flight against task''' pilot.check_flight(flight, task, airspace_obj=airspace, print=print) '''create map file''' pilot.save_tracklog_map_file(task, flight) elif flight: print(f'Error in parsing track: {[x for x in flight.notes]}') lib.process_results(task)
def process_igc(task_id: int, par_id: int, tracklog): from pilot.track import create_igc_filename, igc_parsing_config_from_yaml from calcUtils import epoch_to_date from airspace import AirspaceCheck from igc_lib import Flight from task import Task from pilot.flightresult import FlightResult, save_track pilot = FlightResult.read(par_id, task_id) if pilot.name: task = Task.read(task_id) fullname = create_igc_filename(task.file_path, task.date, pilot.name) tracklog.save(fullname) pilot.track_file = Path(fullname).name else: return None, None """import track""" # track = Track(track_file=fullname, par_id=pilot.par_id) FlightParsingConfig = igc_parsing_config_from_yaml(task.igc_config_file) flight = Flight.create_from_file(fullname, config_class=FlightParsingConfig) """check result""" if not flight: error = f"for {pilot.name} - Track is not a valid track file" return None, error elif not epoch_to_date(flight.date_timestamp) == task.date: error = f"for {pilot.name} - Track has a different date from task date" return None, error else: print( f"pilot {pilot.par_id} associated with track {pilot.track_file} \n" ) """checking track against task""" if task.airspace_check: airspace = AirspaceCheck.from_task(task) else: airspace = None pilot.check_flight(flight, task, airspace_obj=airspace) print(f"track verified with task {task.task_id}\n") '''create map file''' pilot.save_tracklog_map_file(task, flight) """adding track to db""" # pilot.to_db() save_track(pilot, task.id) time = '' data = {'par_id': pilot.par_id, 'track_id': pilot.track_id} if pilot.goal_time: time = sec_to_time(pilot.ss_time) if pilot.result_type == 'goal': data['Result'] = f'Goal {time}' elif pilot.result_type == 'lo': data['Result'] = f"LO {round(pilot.distance / 1000, 2)}" if pilot.track_id: # if there is a track, make the result a link to the map # trackid = data['track_id'] parid = data['par_id'] result = data['Result'] data[ 'Result'] = f'<a href="/map/{parid}-{task.task_id}">{result}</a>' return data, None
def create_map_files(pilots: list, task: Task): from igc_lib import Flight for pilot in pilots: if pilot.result_type not in ('abs', 'dnf', 'mindist'): print(f"{pilot.ID}. {pilot.name}: ({pilot.track_file})") filename = Path(task.file_path, pilot.track_file) '''load track file''' flight = Flight.create_from_file(filename) if flight: '''create map file''' pilot.save_tracklog_map_file(task, flight)
def create_tracklog_map_result_file(par_id: int, task_id: int): from pilot import flightresult from task import Task from igc_lib import Flight from airspace import AirspaceCheck task = Task.read(task_id) airspace = None if not task.airspace_check else AirspaceCheck.from_task(task) pilot = flightresult.FlightResult.read(par_id, task_id) file = Path(task.file_path, pilot.track_file) '''load track file''' flight = Flight.create_from_file(file) pilot.check_flight(flight, task, airspace) pilot.save_tracklog_map_file(task, flight)
def read_db(cls, track_id): """Creates a Track Object from a DB Track entry""" from db.tables import TrackObjectView as T track = cls(track_id=track_id) """Read general info about the track""" with db_session() as db: # get track details. q = db.query(T).get(track_id) q.populate(track) """Creates the flight obj with fixes info""" # task_id = q.task_id full_path = get_task_fullpath(q.task_id) track.flight = Flight.create_from_file(path.join(full_path, track.track_file)) return track
def create_trackpoints_layer(file: str, offset: int = 0): from igc_lib import Flight from calcUtils import sec_to_string try: flight = Flight.create_from_file(file) points = [] for fix in flight.fixes: points.append([ fix.lon, fix.lat, fix.rawtime, fix.press_alt, fix.gnss_alt, sec_to_string(fix.rawtime), sec_to_string(fix.rawtime, offset) ]) except FileNotFoundError: print(f'Error: file not found {file}') return None except Exception: print(f'Error: cannot create trackpoints map layer from track: {file}') return None return points
def adjust_flight_results(task, lib, airspace=None): """ Called when multi-start or elapsed time task was stopped. We need to check again and adjust results of pilots that flew more than task duration""" from igc_lib import Flight maxtime = task.duration for pilot in task.pilots: if pilot.SSS_time: last_time = pilot.SSS_time + maxtime if ((not pilot.ESS_time and pilot.best_distance_time > last_time) or (pilot.ESS_time and pilot.ss_time > maxtime)): '''need to adjust pilot result''' filename = path.join(task.file_path, pilot.track_file) '''load track file''' flight = Flight.create_from_file(filename) pilot.check_flight(flight, task, airspace_obj=airspace, deadline=last_time) # pilot.result_type = adjusted.result_type '''create map file''' pilot.save_tracklog_map_file(task, flight) lib.process_results(task)
def save_livetrack_result(p: FlightResult, task: Task, airspace: AirspaceCheck = None): from igc_lib import Flight from pilot.flightresult import save_track try: flight = Flight.create_from_file(Path(task.file_path, p.track_file)) if flight.valid: print( f"flight valid. Livetracking LC: {p.fixed_LC} distance: {p.distance_flown} time: {p.ss_time}" ) # test = FlightResult() # test.check_flight(flight, task, airspace) # print(f"Calculated LC: {test.fixed_LC} distance: {test.distance_flown} time: {test.ss_time}") # print(f"Difference %: {(test.fixed_LC - p.fixed_LC) / p.fixed_LC * 100}") save_track(p, task.id) p.save_tracklog_map_file(task, flight) else: print(f"{p.track_file} is not a valid igc. Result not saved.") except: print(f"{p.track_file} Error trying to save result.")
def process_igc_background(task_id: int, par_id: int, file: Path, user: str): from pilot.track import igc_parsing_config_from_yaml from calcUtils import epoch_to_date from pilot.flightresult import FlightResult, save_track from airspace import AirspaceCheck from igc_lib import Flight from task import Task import json pilot = FlightResult.read(par_id, task_id) task = Task.read(task_id) print = partial(print_to_sse, id=par_id, channel=user) """import track""" # pilot.track = Track(track_file=filename, par_id=pilot.par_id) FlightParsingConfig = igc_parsing_config_from_yaml(task.igc_config_file) flight = Flight.create_from_file(file, config_class=FlightParsingConfig) data = { 'par_id': pilot.par_id, 'track_id': pilot.track_id, 'Result': 'Not Yet Processed' } """check result""" if not flight: print(f"for {pilot.name} - Track is not a valid track file") print(json.dumps(data) + '|result') return None if not flight.valid: print( f'IGC does not meet quality standard set by igc parsing config. Notes:{pilot.flight.notes}' ) print(json.dumps(data) + '|result') return None elif not epoch_to_date(flight.date_timestamp) == task.date: print(f"for {pilot.name} - Track has a different date from task date") print(json.dumps(data) + '|result') return None else: print(f"pilot {pilot.par_id} associated with track {file.name} \n") pilot.track_file = file.name """checking track against task""" if task.airspace_check: airspace = AirspaceCheck.from_task(task) else: airspace = None pilot.check_flight(flight, task, airspace_obj=airspace, print=print) print(f"track verified with task {task.task_id}\n") '''create map file''' pilot.save_tracklog_map_file(task, flight) """adding track to db""" # pilot.to_db() save_track(pilot, task.id) data['track_id'] = pilot.track_id time = '' if pilot.goal_time: time = sec_to_time(pilot.ESS_time - pilot.SSS_time) if pilot.result_type == 'goal': data['Result'] = f'Goal {time}' elif pilot.result_type == 'lo': data['Result'] = f"LO {round(pilot.distance / 1000, 2)}" if pilot.track_id: # if there is a track, make the result a link to the map # trackid = data['track_id'] parid = data['par_id'] result = data['Result'] data[ 'Result'] = f'<a href="/map/{parid}-{task.task_id}">{result}</a>' print(data['Result']) print(json.dumps(data) + '|result') print('***************END****************') return None