source: src/mlx/gates.py@ 1155:35b07078c8be

python3
Last change on this file since 1155:35b07078c8be was 1155:35b07078c8be, checked in by István Váradi <ivaradi@…>, 3 weeks ago

If the gate dimension data is not yet populated from the database, no restrictions are applied (re #386).

File size: 11.7 KB
Line 
1#--------------------------------------------------------------------------------------
2
3## @package mlx.gates
4#
5# The module to handle the LHBP gate information.
6#
7
8#--------------------------------------------------------------------------------------
9
10class Gate(object):
11 """Information about a gate."""
12 def __init__(self, number, terminal, type,
13 availableFn = None, taxiThrough = False,
14 maxSpan = 0.0, maxLength = 0.0):
15 """Construct the gate with the given information.
16
17 number is the gate's number as a string (as it can contain letters).
18 terminal is the terminal the gate belongs to (not used currently).
19 type is the gate's type: G for gate, S for stand.
20 availableFn is a function that can determine if the gate is available based on
21 the statuses of other gates. Its arguments are:
22 - a collection of the gates, and
23 - a set of occupied gate numbers."""
24 self.number = number
25 self.terminal = terminal
26 self.type = type
27 self._availableFn = availableFn
28 self.taxiThrough = taxiThrough
29 self.maxSpan = maxSpan
30 self.maxLength = maxLength
31
32 def isAvailable(self, plane, gates, occupiedGateNumbers):
33 """Determine if this gate is available for the given plane and the
34 given the set of gates and occupied gate numbers."""
35 if self.number in occupiedGateNumbers:
36 return False
37 if self._availableFn is None or \
38 self._availableFn(gates, occupiedGateNumbers):
39 return plane is None or \
40 ((self.maxSpan<0.1 or plane.wingSpan <= self.maxSpan) and
41 (self.maxLength<0.1 or plane.fuselageLength <= self.maxLength))
42 else:
43 return False
44
45#--------------------------------------------------------------------------------------
46
47class Gates(object):
48 """A collection of gates."""
49 # Display info type: a gate (number)
50 DISPLAY_GATE=1
51
52 # Display info type: a space
53 DISPLAY_SPACE=2
54
55 # Display info type: a new column
56 DISPLAY_NEW_COLUMN=3
57
58 def __init__(self):
59 """Construct the gate collection."""
60 self._gates = []
61 self._displayInfos = []
62 self._numColumns = 1
63 self._numRows = 0
64 self._numRowsInColumn = 0
65
66 @property
67 def gates(self):
68 """Get an iterator over the gates."""
69 return iter(self._gates)
70
71 @property
72 def displayInfos(self):
73 """Get an iterator over the display info tuples.
74
75 Each tuple consists of
76 - a type (one of the DISPLAY_XXX constants), and
77 - an additional data (the gate for DISPLAY_GATE, None for others)."""
78 return iter(self._displayInfos)
79
80 @property
81 def numRows(self):
82 """Get the number of rows."""
83 return self._numRows
84
85 @property
86 def numColumns(self):
87 """Get the number of columns."""
88 return self._numColumns
89
90 def add(self, gate):
91 """Add a gate to the collection."""
92 self._gates.append(gate)
93 self._displayInfos.append((Gates.DISPLAY_GATE, gate))
94 self._addRow()
95
96 def find(self, gateNumber):
97 """Find a gate by its number."""
98 for gate in self._gates:
99 if gate.number == gateNumber:
100 return gate
101
102 def addSpace(self):
103 """Add a space between subsequent gates."""
104 self._displayInfos.append((Gates.DISPLAY_SPACE, None))
105 self._addRow()
106
107 def addNewColumn(self):
108 """Start a new column of gates."""
109 self._displayInfos.append((Gates.DISPLAY_NEW_COLUMN, None))
110 self._numRowsInColumn = 0
111 self._numColumns += 1
112
113 def merge(self, otherGates):
114 """Merge the information from the given gate list (retrieved from the
115 MAVA server) into this gate list."""
116 for otherGate in otherGates.gates:
117 gate = self.find(otherGate.number)
118 if gate is None:
119 print("Received data for gate %s, but it does not exist locally!" %
120 (otherGate.number,))
121 else:
122 if gate.terminal != otherGate.terminal:
123 print("The terminal for gate %s is received as: %s" %
124 (gate.number, otherGate.terminal))
125 gate.terminal = otherGate.terminal
126 if gate.type != otherGate.type:
127 print("The type for gate %s is received as: %s" %
128 (gate.number, otherGate.type))
129 gate.type = otherGate.type
130
131 gate.maxSpan = otherGate.maxSpan
132 gate.maxLength = otherGate.maxLength
133
134 for gate in self.gates:
135 if gate.maxSpan==0.0 or gate.maxLength==0.0:
136 print("Gate %s has no maximal dimensions from the database" %
137 (gate.number,))
138
139 def _addRow(self):
140 """Add a new row."""
141 self._numRowsInColumn += 1
142 if self._numRowsInColumn > self._numRows:
143 self._numRows = self._numRowsInColumn
144
145#--------------------------------------------------------------------------------------
146
147def availableIf(occupiedGateNumbers, othersAvailable = []):
148 """Determine if a gate is available.
149
150 othersAvailable is a list of numbers of gates, that must be available so
151 that the one we are considering is available."""
152 for otherNumber in othersAvailable:
153 if otherNumber in occupiedGateNumbers:
154 return False
155 return True
156
157#--------------------------------------------------------------------------------------
158
159def getAvailableIf(othersAvailable = []):
160 """Get a function that determines if a gate is available based on the
161 statuses of other gates."""
162 return lambda gates, occupiedGateNumbers: availableIf(occupiedGateNumbers,
163 othersAvailable =
164 othersAvailable)
165
166#--------------------------------------------------------------------------------------
167
168# The gates at LHBP
169lhbpGates = Gates()
170
171lhbpGates.add(Gate("R101", "1", "S"))
172lhbpGates.add(Gate("R102", "1", "S"))
173lhbpGates.add(Gate("R103", "1", "S"))
174lhbpGates.add(Gate("R104", "1", "S",
175 availableFn = getAvailableIf(othersAvailable = ["R105"])))
176lhbpGates.add(Gate("R105", "1", "S",
177 availableFn = getAvailableIf(othersAvailable = ["R104", "R106"])))
178lhbpGates.add(Gate("R106", "1", "S",
179 availableFn = getAvailableIf(othersAvailable = ["R105", "R108"])))
180lhbpGates.add(Gate("R107", "1", "S",
181 availableFn = getAvailableIf(othersAvailable = ["R108"])))
182lhbpGates.add(Gate("R108", "1", "S",
183 availableFn = getAvailableIf(othersAvailable = ["R106", "R107"])))
184
185lhbpGates.addSpace()
186lhbpGates.add(Gate("R110", "1", "S",
187 availableFn = getAvailableIf(othersAvailable = ["R111"])))
188lhbpGates.add(Gate("R111", "1", "S",
189 availableFn = getAvailableIf(othersAvailable = ["R110", "R112"])))
190lhbpGates.add(Gate("R112", "1", "S",
191 availableFn = getAvailableIf(othersAvailable = ["R111"])))
192lhbpGates.add(Gate("R113", "1", "S",
193 availableFn = getAvailableIf(othersAvailable = ["R112", "R114"])))
194lhbpGates.add(Gate("R114", "1", "S",
195 availableFn = getAvailableIf(othersAvailable = ["R113"])))
196lhbpGates.add(Gate("R115", "1", "S"))
197lhbpGates.add(Gate("R116", "1", "S",
198 availableFn = getAvailableIf(othersAvailable = ["R117"])))
199lhbpGates.add(Gate("R117", "1", "S",
200 availableFn = getAvailableIf(othersAvailable = ["R116", "R117A"])))
201lhbpGates.add(Gate("R117A", "1", "S",
202 availableFn = getAvailableIf(othersAvailable = ["R116", "R117"])))
203lhbpGates.addNewColumn()
204
205lhbpGates.add(Gate("G150", "1", "S"))
206lhbpGates.add(Gate("G151", "1", "S"))
207lhbpGates.add(Gate("G152", "1", "S"))
208lhbpGates.add(Gate("G153", "1", "S"))
209lhbpGates.add(Gate("G154", "1", "S"))
210lhbpGates.add(Gate("G155", "1", "S"))
211
212lhbpGates.addSpace()
213lhbpGates.add(Gate("G170", "1", "S"))
214lhbpGates.add(Gate("G171", "1", "S"))
215lhbpGates.add(Gate("G172", "1", "S"))
216lhbpGates.addNewColumn()
217
218lhbpGates.add(Gate("31", "2B", "G"))
219lhbpGates.add(Gate("32", "2B", "G"))
220lhbpGates.add(Gate("33", "2B", "G"))
221lhbpGates.add(Gate("34", "2B", "G",
222 availableFn = getAvailableIf(othersAvailable = ["34L", "34R"])))
223lhbpGates.add(Gate("34L", "2B", "G",
224 availableFn = getAvailableIf(othersAvailable = ["34", "34R"])))
225lhbpGates.add(Gate("34R", "2B", "G",
226 availableFn = getAvailableIf(othersAvailable = ["34L", "34"])))
227lhbpGates.add(Gate("35", "2B", "G",
228 availableFn = getAvailableIf(othersAvailable = ["35L", "35R"])))
229lhbpGates.add(Gate("35L", "2B", "G",
230 availableFn = getAvailableIf(othersAvailable = ["35", "35R"])))
231lhbpGates.add(Gate("35R", "2B", "G",
232 availableFn = getAvailableIf(othersAvailable = ["35L", "35"])))
233lhbpGates.add(Gate("36", "2B", "G",
234 availableFn = getAvailableIf(othersAvailable = ["36L", "36R"])))
235lhbpGates.add(Gate("36L", "2B", "G",
236 availableFn = getAvailableIf(othersAvailable = ["36", "36R"])))
237lhbpGates.add(Gate("36R", "2B", "G",
238 availableFn = getAvailableIf(othersAvailable = ["36L", "36"])))
239lhbpGates.addSpace()
240
241lhbpGates.add(Gate("37", "2B", "G"))
242lhbpGates.add(Gate("38", "2B", "G"))
243lhbpGates.add(Gate("39", "2B", "G",
244 availableFn = getAvailableIf(othersAvailable = ["37L", "37R"])))
245lhbpGates.add(Gate("39L", "2B", "G",
246 availableFn = getAvailableIf(othersAvailable = ["37", "37R"])))
247lhbpGates.add(Gate("39R", "2B", "G",
248 availableFn = getAvailableIf(othersAvailable = ["37L", "37"])))
249lhbpGates.addNewColumn()
250
251lhbpGates.add(Gate("42", "2A", "G"))
252lhbpGates.add(Gate("43", "2A", "G"))
253lhbpGates.add(Gate("44", "2A", "G"))
254lhbpGates.add(Gate("45", "2A", "G"))
255lhbpGates.addSpace()
256
257lhbpGates.add(Gate("R210", "2A", "S",
258 availableFn = getAvailableIf(othersAvailable = ["R212A"]),
259 taxiThrough = True))
260lhbpGates.add(Gate("R211", "2A", "S",
261 availableFn = getAvailableIf(othersAvailable = ["R212A"]),
262 taxiThrough = True))
263lhbpGates.add(Gate("R212", "2A", "S",
264 availableFn = getAvailableIf(othersAvailable = ["R212A"]),
265 taxiThrough = True))
266lhbpGates.add(Gate("R212A", "2A", "S",
267 availableFn = getAvailableIf(othersAvailable = ["R210", "R211", "R212"]),
268 taxiThrough = True))
269lhbpGates.addSpace()
270
271lhbpGates.add(Gate("R220", "2B", "S"))
272lhbpGates.add(Gate("R221", "2B", "S"))
273lhbpGates.add(Gate("R222", "2B", "S"))
274lhbpGates.add(Gate("R223", "2B", "S"))
275lhbpGates.addSpace()
276
277lhbpGates.add(Gate("R224", "2A", "S"))
278lhbpGates.add(Gate("R225", "2A", "S"))
279lhbpGates.add(Gate("R226", "2A", "S"))
280lhbpGates.add(Gate("R227", "2A", "S"))
281lhbpGates.addNewColumn()
282
283lhbpGates.add(Gate("R270", "2A", "S"))
284lhbpGates.add(Gate("R271", "2A", "S"))
285lhbpGates.add(Gate("R272", "2A", "S"))
286lhbpGates.add(Gate("R273", "2A", "S"))
287lhbpGates.add(Gate("R274", "2A", "S"))
288lhbpGates.add(Gate("R275", "2A", "S"))
289lhbpGates.add(Gate("R276", "2A", "S"))
290lhbpGates.add(Gate("R277", "2A", "S"))
291lhbpGates.add(Gate("R278", "2A", "S",
292 availableFn = getAvailableIf(othersAvailable = ["R278A"]),
293 taxiThrough = True))
294lhbpGates.add(Gate("R278A", "2A", "S",
295 availableFn = getAvailableIf(othersAvailable = ["R278", "R279"]),
296 taxiThrough = True))
297lhbpGates.add(Gate("R279", "2A", "S",
298 availableFn = getAvailableIf(othersAvailable = ["R278A"]),
299 taxiThrough = True))
Note: See TracBrowser for help on using the repository browser.