introduce a runway planner
This commit is contained in:
92
src/planner/runwayplanner.ts
Normal file
92
src/planner/runwayplanner.ts
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import { Inbound } from '../inbound/models/inbound.model';
|
||||||
|
import { Airport } from '../airport/models/airport.model';
|
||||||
|
import { WGS84 } from 'src/math';
|
||||||
|
|
||||||
|
export class RunwayPlanner {
|
||||||
|
static timeIndependentRunway(airport: Airport, inbound: Inbound): string {
|
||||||
|
if (airport.activeRunways.length === 0) return undefined;
|
||||||
|
|
||||||
|
const shallRunway: string[] = [undefined, undefined];
|
||||||
|
const shouldRunway: string[] = [undefined, undefined];
|
||||||
|
const mayRunway: string[] = [undefined, undefined];
|
||||||
|
|
||||||
|
// collect candidates based on aircraft type and assigned stand
|
||||||
|
airport.planning.assignments.forEach((assignment) => {
|
||||||
|
const aircraftTypeBound =
|
||||||
|
assignment.aircrafts.find(
|
||||||
|
(element) => element === inbound.aircraft.type,
|
||||||
|
) !== undefined;
|
||||||
|
const standBound =
|
||||||
|
assignment.assignedStands.find(
|
||||||
|
(element) => element === inbound.controllerData.plannedStand,
|
||||||
|
) !== undefined;
|
||||||
|
|
||||||
|
if (aircraftTypeBound) {
|
||||||
|
switch (assignment.type) {
|
||||||
|
case 'SHALL':
|
||||||
|
shallRunway[0] = assignment.runway;
|
||||||
|
break;
|
||||||
|
case 'SHOULD':
|
||||||
|
shouldRunway[0] = assignment.runway;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mayRunway[0] = assignment.runway;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (standBound) {
|
||||||
|
switch (assignment.type) {
|
||||||
|
case 'SHALL':
|
||||||
|
shallRunway[1] = assignment.runway;
|
||||||
|
break;
|
||||||
|
case 'SHOULD':
|
||||||
|
shouldRunway[1] = assignment.runway;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mayRunway[1] = assignment.runway;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// select based on shall-should-may order
|
||||||
|
if (shallRunway[0] !== undefined || shallRunway[1] !== undefined) {
|
||||||
|
return shallRunway[0] !== undefined ? shallRunway[0] : shallRunway[1];
|
||||||
|
} else if (shouldRunway[0] !== undefined || shouldRunway[1] !== undefined) {
|
||||||
|
return shouldRunway[0] !== undefined ? shouldRunway[0] : shouldRunway[1];
|
||||||
|
} else if (mayRunway[0] !== undefined || mayRunway[1] !== undefined) {
|
||||||
|
return mayRunway[0] !== undefined ? mayRunway[0] : mayRunway[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// as a fallback use the closest runway
|
||||||
|
let closestDistance = 10000000.0;
|
||||||
|
let closestRunway: string = undefined;
|
||||||
|
|
||||||
|
airport.activeRunways.forEach((identifier) => {
|
||||||
|
const runway = airport.runways.find(
|
||||||
|
(element) => element.identifier === identifier,
|
||||||
|
);
|
||||||
|
if (runway !== undefined) {
|
||||||
|
const distance = WGS84.distance(
|
||||||
|
{ lat: runway.threshold.latitude, lon: runway.threshold.longitude },
|
||||||
|
{
|
||||||
|
lat: inbound.flightState.position.latitude,
|
||||||
|
lon: inbound.flightState.position.longitude,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (closestDistance > distance) {
|
||||||
|
closestDistance = distance;
|
||||||
|
closestRunway = identifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (closestRunway !== undefined) {
|
||||||
|
return closestRunway;
|
||||||
|
} else if (airport.activeRunways.length !== 0) {
|
||||||
|
return airport.activeRunways[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user