Airport.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #!/usr/bin/env python
  2. import configparser
  3. import glob
  4. import os
  5. import sys
  6. from aman.config.RHC import RHC
  7. from aman.config.AirportSequencing import AirportSequencing
  8. from aman.config.RunwaySequencing import RunwaySequencing
  9. from aman.formats.SctEseFormat import SctEseFormat
  10. class Airport:
  11. def findGngData(data, path):
  12. if None == data.get('gngwildcard'):
  13. return None, None
  14. # find the newest ESE file
  15. files = glob.glob(os.path.join(path, data['gngwildcard'] + '.ese'))
  16. latestEse = max(files, key=os.path.getctime)
  17. # search for the corresponding SCT file
  18. latestSct = os.path.splitext(latestEse)[0] + '.sct'
  19. # check if the files exist
  20. if False == os.path.isfile(latestEse) or False == os.path.isfile(latestSct):
  21. return None, None
  22. return latestSct, latestEse
  23. def parsePlanning(self, planning):
  24. if None == planning.get('routes'):
  25. return []
  26. return planning['routes'].split(':')
  27. def parseDefaultSequencingConfiguration(self, icao : str, planning):
  28. if None == planning.get('activearrivalrunwaydefault'):
  29. sys.stderr.write('No "activearrivalrunwaydefault" entry found!')
  30. sys.exit(-1)
  31. if None == planning.get('activearrivalmodedefault'):
  32. sys.stderr.write('No "activearrivalmodedefault" entry found!')
  33. sys.exit(-1)
  34. if None == planning.get('arrivalspacingdefault'):
  35. sys.stderr.write('No "arrivalspacingdefault" entry found!')
  36. sys.exit(-1)
  37. if not icao in self.GngData.Runways:
  38. sys.stderr.write('Unable to find' + icao + 'in the SCT data!')
  39. sys.exit(-1)
  40. # parse the default arrival mode
  41. if 'STAGGERED' == planning['activearrivalmodedefault']:
  42. staggered = True
  43. elif 'IPA' == planning['activearrivalmodedefault']:
  44. staggered = False
  45. else:
  46. sys.stderr.write('Unknown arrival mode in "" found! (STAGGERED or IPA needs to be set)')
  47. sys.exit(-1)
  48. # translate the spacing into a map
  49. ident = ''
  50. spacings = {}
  51. spacingConfig = list(filter(None, planning['arrivalspacingdefault'].split(':')))
  52. for i in range(0, len(spacingConfig)):
  53. if 0 == i % 2:
  54. ident = spacingConfig[i]
  55. elif '' != ident:
  56. spacings[ident] = int(spacingConfig[i])
  57. else:
  58. sys.stderr.write('No runway defined in "arrivalspacingdefault"!')
  59. sys.exit(-1)
  60. # create the sequencing data per runway
  61. self.DefaultSequencing = AirportSequencing(icao)
  62. for ident in list(filter(None, planning['activearrivalrunwaydefault'].split(':'))):
  63. if not ident in spacings:
  64. sys.stderr.write('Unable to find sequencing data for ' + ident + ' of ' + icao)
  65. sys.exit(-1)
  66. found = False
  67. for runway in self.GngData.Runways[icao]:
  68. if ident == runway.Name:
  69. sequence = RunwaySequencing(runway)
  70. sequence.Spacing = spacings[ident]
  71. self.DefaultSequencing.activateRunway(sequence)
  72. found = True
  73. break
  74. if False == found:
  75. sys.stderr.write('Unable to find the runway for ' + ident + ' of ' + icao + ' in SCT data!')
  76. sys.exit(-1)
  77. # create the dependencies, if needed
  78. if True == staggered:
  79. if None == planning.get('runwaydependenciesdefault'):
  80. sys.stderr.write('Unable to find the runway dependencies for staggered approaches of ' + icao + '!')
  81. sys.exit(-1)
  82. dependencies = list(filter(None, planning['runwaydependenciesdefault'].split(':')))
  83. if 0 != len(dependencies) % 2:
  84. sys.stderr.write('No valid set of runway dependencies found!')
  85. sys.exit(-1)
  86. for i in range(0, len(dependencies), 2):
  87. self.DefaultSequencing.addDependency(dependencies[i], dependencies[i + 1])
  88. def parseConstraints(self, icao : str, planning):
  89. for key in planning:
  90. if True == key.startswith('constraints'):
  91. star = key.replace('constraints', '').upper()
  92. #print(star)
  93. def __init__(self, filepath : str, icao : str):
  94. config = configparser.ConfigParser()
  95. config.read(filepath)
  96. dataConfig = None
  97. planningConfig = None
  98. rhcConfig = None
  99. # search the required sections
  100. for key in config:
  101. if 'DATA' == key:
  102. dataConfig = config['DATA']
  103. elif 'PLANNING' == key:
  104. planningConfig = config['PLANNING']
  105. elif 'RHC' == key:
  106. rhcConfig = config['RHC']
  107. # find the GNG-file data
  108. sctFile, eseFile = Airport.findGngData(dataConfig, os.path.dirname(filepath))
  109. if None == sctFile or None == eseFile:
  110. sys.stderr.write('No GNG-files found')
  111. sys.exit(-1)
  112. # parse the planning information
  113. if None == planningConfig or False == self.parsePlanning(planningConfig):
  114. sys.stderr.write('No planning configuration found')
  115. sys.exit(-1)
  116. requiredArrivalRoutes = self.parsePlanning(planningConfig)
  117. if 0 == len(requiredArrivalRoutes):
  118. sys.stderr.write('No valid planning configuration found')
  119. sys.exit(-1)
  120. # parse the RHC information
  121. if None == rhcConfig:
  122. sys.stderr.write('No RHC configuration found')
  123. sys.exit(-1)
  124. self.RecedingHorizonControl = RHC(rhcConfig)
  125. # parse the GNG data
  126. print('Used GNG-Data: ' + eseFile)
  127. self.GngData = SctEseFormat(sctFile, eseFile, icao, requiredArrivalRoutes)
  128. # get the GAFOR id
  129. if None == dataConfig.get('gaforid'):
  130. sys.stderr.write('No GAFOR-ID found!')
  131. sys.exit(-1)
  132. self.GaforId = dataConfig['gaforid']
  133. # get the default sequencing data and constraints
  134. self.parseDefaultSequencingConfiguration(icao, planningConfig)
  135. self.parseConstraints(icao, planningConfig)