SctEseFormat.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #!/usr/bin/env python
  2. import sys
  3. from aman.types.ArrivalRoute import ArrivalRoute
  4. from aman.types.Waypoint import Waypoint
  5. class SctEseFormat:
  6. def readFile(filename : str):
  7. fileBlocks = {}
  8. block = None
  9. # read the file line by line and create segments based on []-entries
  10. with open(filename) as file:
  11. for line in file:
  12. line = line.strip()
  13. # found a new segment
  14. if line.startswith('['):
  15. block = line[1:-1]
  16. fileBlocks.setdefault(block, [])
  17. # append the last backend
  18. elif None != block and 0 != len(line):
  19. fileBlocks[block].append(line)
  20. return fileBlocks
  21. def parseWaypoint(waypoint : str, nameIdx : int, latitudeIdx : int, longitudeIdx : int):
  22. split = list(filter(None, waypoint.split(' ')))
  23. if len(split) <= longitudeIdx:
  24. sys.stderr.write('Invalid waypoint format: ' + waypoint)
  25. sys.exit(-1)
  26. return Waypoint(split[nameIdx], Waypoint.dms2dd(split[latitudeIdx]), Waypoint.dms2dd(split[longitudeIdx]))
  27. def extractWaypoints(self, sctFilepath : str):
  28. config = SctEseFormat.readFile(sctFilepath)
  29. foundAirports = False
  30. foundVOR = False
  31. foundNDB = False
  32. foundFix = False
  33. for key in config:
  34. if 'VOR' == key:
  35. foundVOR = True
  36. elif 'NDB' == key:
  37. foundNDB = True
  38. elif 'FIXES' == key:
  39. foundFix = True
  40. elif 'AIRPORT' == key:
  41. foundAirports = True
  42. if False == foundVOR:
  43. sys.stderr.write('Unable to find VOR-entries in the sector file')
  44. sys.exit(-1)
  45. if False == foundNDB:
  46. sys.stderr.write('Unable to find NDB-entries in the sector file')
  47. sys.exit(-1)
  48. if False == foundFix:
  49. sys.stderr.write('Unable to find FIX-entries in the sector file')
  50. sys.exit(-1)
  51. if False == foundAirports:
  52. sys.stderr.write('Unable to find AIRPORT-entries in the sector file')
  53. sys.exit(-1)
  54. # extract all waypoints
  55. for waypoint in config['VOR']:
  56. waypoint = SctEseFormat.parseWaypoint(waypoint, 0, 2, 3)
  57. self.waypoints.setdefault(waypoint.name, []).append(waypoint)
  58. for waypoint in config['NDB']:
  59. waypoint = SctEseFormat.parseWaypoint(waypoint, 0, 1, 2)
  60. self.waypoints.setdefault(waypoint.name, []).append(waypoint)
  61. for waypoint in config['FIXES']:
  62. waypoint = SctEseFormat.parseWaypoint(waypoint, 0, 1, 2)
  63. self.waypoints.setdefault(waypoint.name, []).append(waypoint)
  64. # extract the airports
  65. for airport in config['AIRPORT']:
  66. airport = SctEseFormat.parseWaypoint(airport,0, 2, 3)
  67. self.airports.setdefault(airport.name, []).append(airport)
  68. def parseArrivalRoute(self, route : str, airport : Waypoint):
  69. # split the route and validate that it is a STAR for the airport
  70. split = route.split(':')
  71. if 5 != len(split) or 'STAR' != split[0] or split[1] != airport.name:
  72. return None
  73. # find all waypoints
  74. waypoints = []
  75. route = list(filter(None, split[4].split(' ')))
  76. for waypoint in route:
  77. # find the waypoint in the route
  78. coordinates = self.waypoints[waypoint]
  79. # no waypoint with this name defined
  80. if None == coordinates:
  81. sys.stderr.write('Unable to find waypoint ' + waypoint)
  82. sys.exit(-1)
  83. # multiple waypoints, but use Haversine distance to distinct between candidates
  84. elif 1 != len(coordinates):
  85. minDistance = sys.float_info.max
  86. nearest = None
  87. # we assume that waypoints with the same name are not close each other
  88. for coordinate in coordinates:
  89. distance = coordinate.haversine(airport)
  90. # found a closer waypoint
  91. if minDistance > distance:
  92. minDistance = distance
  93. nearest = coordinate
  94. if None == nearest:
  95. sys.stderr.write('Unable to find a close waypoint for ' + waypoint)
  96. sys.exit(-1)
  97. waypoints.append(nearest)
  98. # extend the list of waypoints
  99. else:
  100. waypoints.append(coordinates[0])
  101. # create the arrival route
  102. return ArrivalRoute(split[3], split[2], waypoints)
  103. def extractArrivalRoutes(self, eseFilepath : str, airport : str, allowedRoutes : list):
  104. config = SctEseFormat.readFile(eseFilepath)
  105. foundSidsStars = False
  106. # search the airport in the extracted list
  107. if not airport in self.airports:
  108. sys.stderr.write(airport + 'in self.airports', 'Unable to find the requested airport')
  109. sys.exit(-1)
  110. airport = self.airports[airport][0]
  111. for key in config:
  112. if 'SIDSSTARS' == key:
  113. foundSidsStars = True
  114. if False == foundSidsStars:
  115. sys.stderr.write('Unable to find SIDSSTARS-entries in the sector file')
  116. sys.exit(-1)
  117. # parse all arrival routes
  118. for line in config['SIDSSTARS']:
  119. route = self.parseArrivalRoute(line, airport)
  120. if None != route and route.name in allowedRoutes:
  121. self.arrivalRoutes.setdefault(route.runway, []).append(route)
  122. def __init__(self, sctFilepath : str, eseFilepath : str, airport : str, allowedRoutes : list):
  123. self.arrivalRoutes = {}
  124. self.waypoints = {}
  125. self.airports = {}
  126. self.extractWaypoints(sctFilepath)
  127. self.extractArrivalRoutes(eseFilepath, airport, allowedRoutes)