123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- #!/usr/bin/env python
- import copy
- import sys
- from aman.types.ArrivalRoute import ArrivalRoute
- from aman.types.Runway import Runway
- from aman.types.Waypoint import Waypoint
- class SctEseFormat:
- def readFile(filename : str):
- fileBlocks = {}
- block = None
- # read the file line by line and create segments based on []-entries
- with open(filename) as file:
- for line in file:
- line = line.strip()
- # found a new segment
- if line.startswith('['):
- block = line[1:-1]
- fileBlocks.setdefault(block, [])
- # append the last backend
- elif None != block and 0 != len(line):
- fileBlocks[block].append(line)
- return fileBlocks
- def parseWaypoint(waypoint : str, nameIdx : int, latitudeIdx : int, longitudeIdx : int):
- split = list(filter(None, waypoint.split(' ')))
- if len(split) <= longitudeIdx:
- sys.stderr.write('Invalid waypoint format: ' + waypoint)
- sys.exit(-1)
- return Waypoint(name = split[nameIdx], latitude = split[latitudeIdx], longitude = split[longitudeIdx])
- def parseRunway(runway : str):
- split = list(filter(None, runway.split(' ')))
- if 9 != len(split) or '' == split[8]:
- return None, None, None
- waypoint0 = Waypoint(name = split[0], latitude = split[4], longitude = split[5])
- waypoint1 = Waypoint(name = split[1], latitude = split[6], longitude = split[7])
- return split[8], Runway(waypoint0, waypoint1), Runway(waypoint1, waypoint0)
- def extractSctInformation(self, sctFilepath : str):
- config = SctEseFormat.readFile(sctFilepath)
- foundAirports = False
- foundRunways = False
- foundVOR = False
- foundNDB = False
- foundFix = False
- for key in config:
- if 'VOR' == key:
- foundVOR = True
- elif 'NDB' == key:
- foundNDB = True
- elif 'FIXES' == key:
- foundFix = True
- elif 'AIRPORT' == key:
- foundAirports = True
- elif 'RUNWAY' == key:
- foundRunways = True
- if False == foundVOR:
- sys.stderr.write('Unable to find VOR-entries in the sector file')
- sys.exit(-1)
- if False == foundNDB:
- sys.stderr.write('Unable to find NDB-entries in the sector file')
- sys.exit(-1)
- if False == foundFix:
- sys.stderr.write('Unable to find FIX-entries in the sector file')
- sys.exit(-1)
- if False == foundAirports:
- sys.stderr.write('Unable to find AIRPORT-entries in the sector file')
- sys.exit(-1)
- if False == foundRunways:
- sys.stderr.write('Unable to find RUNWAY-entries in the sector file')
- sys.exit(-1)
- # extract all waypoints
- for waypoint in config['VOR']:
- waypoint = SctEseFormat.parseWaypoint(waypoint, 0, 2, 3)
- self.Waypoints.setdefault(waypoint.Name, []).append(waypoint)
- for waypoint in config['NDB']:
- waypoint = SctEseFormat.parseWaypoint(waypoint, 0, 1, 2)
- self.Waypoints.setdefault(waypoint.Name, []).append(waypoint)
- for waypoint in config['FIXES']:
- waypoint = SctEseFormat.parseWaypoint(waypoint, 0, 1, 2)
- self.Waypoints.setdefault(waypoint.Name, []).append(waypoint)
- # extract the airports
- for airport in config['AIRPORT']:
- airport = SctEseFormat.parseWaypoint(airport, 0, 2, 3)
- self.Airports.setdefault(airport.Name, []).append(airport)
- # extract the runways
- for runway in config['RUNWAY']:
- airport, runway0, runway1 = SctEseFormat.parseRunway(runway)
- if None != airport:
- if not airport in self.Runways:
- self.Runways.setdefault(airport, [])
- self.Runways[airport].append(runway0)
- self.Runways[airport].append(runway1)
- def parseArrivalRoute(self, route : str, airport : Waypoint):
- # split the route and validate that it is a STAR for the airport
- split = route.split(':')
- if 5 != len(split) or 'STAR' != split[0] or split[1] != airport.Name:
- return None
- # find all waypoints
- waypoints = []
- route = list(filter(None, split[4].split(' ')))
- for waypoint in route:
- # find the waypoint in the route
- coordinates = self.Waypoints[waypoint]
- # no waypoint with this name defined
- if None == coordinates:
- sys.stderr.write('Unable to find waypoint ' + waypoint)
- sys.exit(-1)
- # multiple waypoints, but use Haversine distance to distinct between candidates
- elif 1 != len(coordinates):
- minDistance = sys.float_info.max
- nearest = None
- # we assume that waypoints with the same name are not close each other
- for coordinate in coordinates:
- distance = coordinate.haversine(airport)
- # found a closer waypoint
- if minDistance > distance:
- minDistance = distance
- nearest = coordinate
- if None == nearest:
- sys.stderr.write('Unable to find a close waypoint for ' + waypoint)
- sys.exit(-1)
- waypoints.append(copy.deepcopy(nearest))
- # extend the list of waypoints
- else:
- waypoints.append(copy.deepcopy(coordinates[0]))
- # create the arrival route
- return ArrivalRoute(split[3], split[2], waypoints)
- def extractArrivalRoutes(self, eseFilepath : str, airport : str, allowedRoutes : list):
- config = SctEseFormat.readFile(eseFilepath)
- foundSidsStars = False
- # search the airport in the extracted list
- if not airport in self.Airports:
- sys.stderr.write('Unable to find the requested airport')
- sys.exit(-1)
- airport = self.Airports[airport][0]
- for key in config:
- if 'SIDSSTARS' == key:
- foundSidsStars = True
- if False == foundSidsStars:
- sys.stderr.write('Unable to find SIDSSTARS-entries in the sector file')
- sys.exit(-1)
- # parse all arrival routes
- for line in config['SIDSSTARS']:
- route = self.parseArrivalRoute(line, airport)
- if None != route and route.Name in allowedRoutes:
- self.ArrivalRoutes.setdefault(route.Runway, []).append(route)
- def __init__(self, sctFilepath : str, eseFilepath : str, airport : str, allowedRoutes : list):
- self.ArrivalRoutes = {}
- self.Waypoints = {}
- self.Airports = {}
- self.Runways = {}
- self.extractSctInformation(sctFilepath)
- self.extractArrivalRoutes(eseFilepath, airport, allowedRoutes)
|