|
@@ -0,0 +1,237 @@
|
|
|
+import {
|
|
|
+ Body,
|
|
|
+ Controller,
|
|
|
+ Get,
|
|
|
+ Delete,
|
|
|
+ Post,
|
|
|
+ Query,
|
|
|
+ HttpException,
|
|
|
+ HttpStatus,
|
|
|
+} from '@nestjs/common';
|
|
|
+import { ApiBody, ApiQuery, ApiResponse } from '@nestjs/swagger';
|
|
|
+import { AirportService } from './airport.service';
|
|
|
+import { Airport } from './models/airport.model';
|
|
|
+import { AirportDto } from './dto/airport.dto';
|
|
|
+import { ArrivalRouteDto } from './dto/arrivalroute.dto';
|
|
|
+import { AssignmentDto } from './dto/assignment.dto';
|
|
|
+import { ConstraintDto } from './dto/constraint.dto';
|
|
|
+import { PlanningDto } from './dto/planning.dto';
|
|
|
+import { RunwaySpacingDto } from './dto/runwayspacing.dto';
|
|
|
+import { ArrivalRoute } from './models/arrivalroute.model';
|
|
|
+import { Assignment } from './models/assignment.model';
|
|
|
+import { Constraint } from './models/constraint.model';
|
|
|
+import { Planning } from './models/planning.model';
|
|
|
+import { RunwaySpacing } from './models/runwayspacing.model';
|
|
|
+
|
|
|
+@Controller('airport')
|
|
|
+export class AirportController {
|
|
|
+ constructor(private readonly airportService: AirportService) {}
|
|
|
+
|
|
|
+ private static convertConstraint<T>(
|
|
|
+ constraint: Constraint | ConstraintDto,
|
|
|
+ ): T {
|
|
|
+ return {
|
|
|
+ waypoint: constraint.waypoint,
|
|
|
+ altitude: {
|
|
|
+ constraint: constraint.altitude.constraint,
|
|
|
+ mode: constraint.altitude.mode,
|
|
|
+ },
|
|
|
+ speed: {
|
|
|
+ constraint: constraint.speed.constraint,
|
|
|
+ mode: constraint.speed.mode,
|
|
|
+ },
|
|
|
+ } as T;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static convertConstraints<T>(
|
|
|
+ constraints: Constraint[] | ConstraintDto[],
|
|
|
+ ): T[] {
|
|
|
+ const retval: T[] = [];
|
|
|
+ constraints.forEach((constraint) =>
|
|
|
+ retval.push(AirportController.convertConstraint<T>(constraint)),
|
|
|
+ );
|
|
|
+ return retval;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static convertArrivalRoutes<T, U>(
|
|
|
+ routes: ArrivalRoute[] | ArrivalRouteDto[],
|
|
|
+ ): T[] {
|
|
|
+ const retval: T[] = [];
|
|
|
+ routes.forEach((route) =>
|
|
|
+ retval.push({
|
|
|
+ arrival: route.runway,
|
|
|
+ runway: route.runway,
|
|
|
+ constraints: AirportController.convertConstraints<U>(route.constraints),
|
|
|
+ } as T),
|
|
|
+ );
|
|
|
+ return retval;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static convertRunwaySpacings<T>(
|
|
|
+ spacings: RunwaySpacing[] | RunwaySpacingDto[],
|
|
|
+ ): T[] {
|
|
|
+ const retval: T[] = [];
|
|
|
+ spacings.forEach((spacing) =>
|
|
|
+ retval.push({
|
|
|
+ runway: spacing.runway,
|
|
|
+ spacing: spacing.spacing,
|
|
|
+ } as T),
|
|
|
+ );
|
|
|
+ return retval;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static convertAssignments<T>(
|
|
|
+ assignments: Assignment[] | AssignmentDto[],
|
|
|
+ ): T[] {
|
|
|
+ const retval: T[] = [];
|
|
|
+ assignments.forEach((assignment) =>
|
|
|
+ retval.push({
|
|
|
+ runway: assignment.runway,
|
|
|
+ type: assignment.type,
|
|
|
+ aircrafts: assignment.aircrafts,
|
|
|
+ assignedStands: assignment.assignedStands,
|
|
|
+ } as T),
|
|
|
+ );
|
|
|
+ return retval;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static convertPlanning<T, U>(planning: Planning | PlanningDto): T {
|
|
|
+ return {
|
|
|
+ optimization: {
|
|
|
+ windowSize: planning.optimization.windowSize,
|
|
|
+ windowOverlap: planning.optimization.windowOverlap,
|
|
|
+ fixedBeforeInitialApproachFix:
|
|
|
+ planning.optimization.fixedBeforeInitialApproachFix,
|
|
|
+ maximumAirportDistance: planning.optimization.maximumAirportDistance,
|
|
|
+ },
|
|
|
+ assignments: AirportController.convertAssignments<U>(
|
|
|
+ planning.assignments,
|
|
|
+ ),
|
|
|
+ } as T;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static airportToAirportDto(airport: Airport): AirportDto {
|
|
|
+ if (!airport) return null;
|
|
|
+
|
|
|
+ return {
|
|
|
+ icao: airport.icao,
|
|
|
+ upperConstraints: AirportController.convertConstraints<ConstraintDto>(
|
|
|
+ airport.upperConstraints,
|
|
|
+ ),
|
|
|
+ arrivalRoutes: AirportController.convertArrivalRoutes<
|
|
|
+ ArrivalRouteDto,
|
|
|
+ ConstraintDto
|
|
|
+ >(airport.arrivalRoutes),
|
|
|
+ spacings: AirportController.convertRunwaySpacings<RunwaySpacingDto>(
|
|
|
+ airport.spacings,
|
|
|
+ ),
|
|
|
+ planning: AirportController.convertPlanning<PlanningDto, AssignmentDto>(
|
|
|
+ airport.planning,
|
|
|
+ ),
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ private static airportDtoToAirport(airport: AirportDto): Airport {
|
|
|
+ if (!airport) return null;
|
|
|
+
|
|
|
+ return {
|
|
|
+ icao: airport.icao,
|
|
|
+ upperConstraints: AirportController.convertConstraints<Constraint>(
|
|
|
+ airport.upperConstraints,
|
|
|
+ ),
|
|
|
+ arrivalRoutes: AirportController.convertArrivalRoutes<
|
|
|
+ ArrivalRoute,
|
|
|
+ Constraint
|
|
|
+ >(airport.arrivalRoutes),
|
|
|
+ spacings: AirportController.convertRunwaySpacings<RunwaySpacing>(
|
|
|
+ airport.spacings,
|
|
|
+ ),
|
|
|
+ planning: AirportController.convertPlanning<Planning, Assignment>(
|
|
|
+ airport.planning,
|
|
|
+ ),
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ @Get('/allCodes')
|
|
|
+ @ApiResponse({
|
|
|
+ status: 200,
|
|
|
+ description: 'All available airports',
|
|
|
+ type: [String],
|
|
|
+ })
|
|
|
+ async allCodes(): Promise<string[]> {
|
|
|
+ return this.airportService.airportsList();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Get('/get')
|
|
|
+ @ApiQuery({
|
|
|
+ name: 'icao',
|
|
|
+ description: 'The ICAO code of the airport',
|
|
|
+ type: String,
|
|
|
+ })
|
|
|
+ @ApiResponse({
|
|
|
+ status: 200,
|
|
|
+ description: 'The airport configuration',
|
|
|
+ type: [AirportDto],
|
|
|
+ })
|
|
|
+ @ApiResponse({
|
|
|
+ status: 404,
|
|
|
+ description: 'No airport found',
|
|
|
+ })
|
|
|
+ async get(@Query('icao') icao: string): Promise<AirportDto> {
|
|
|
+ return this.airportService.airport(icao).then((airport) => {
|
|
|
+ if (!airport) {
|
|
|
+ throw new HttpException('Airport not found', HttpStatus.NOT_FOUND);
|
|
|
+ }
|
|
|
+ return AirportController.airportToAirportDto(airport);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @Post('/register')
|
|
|
+ @ApiBody({
|
|
|
+ description: 'The airport definition',
|
|
|
+ type: AirportDto,
|
|
|
+ })
|
|
|
+ @ApiResponse({
|
|
|
+ status: 201,
|
|
|
+ description: 'The airport is registered',
|
|
|
+ })
|
|
|
+ @ApiResponse({
|
|
|
+ status: 409,
|
|
|
+ description: 'The airport is already registered',
|
|
|
+ })
|
|
|
+ async register(@Body('airport') airport: AirportDto): Promise<void> {
|
|
|
+ await this.airportService
|
|
|
+ .registerAirport(AirportController.airportDtoToAirport(airport))
|
|
|
+ .then((registered) => {
|
|
|
+ if (!registered) {
|
|
|
+ throw new HttpException(
|
|
|
+ 'Airport already available',
|
|
|
+ HttpStatus.CONFLICT,
|
|
|
+ );
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @Delete('/remove')
|
|
|
+ @ApiQuery({
|
|
|
+ name: 'icao',
|
|
|
+ description: 'The ICAO code of the airport',
|
|
|
+ type: String,
|
|
|
+ })
|
|
|
+ @ApiResponse({
|
|
|
+ status: 200,
|
|
|
+ description: 'All log entries are deleted',
|
|
|
+ })
|
|
|
+ @ApiResponse({
|
|
|
+ status: 404,
|
|
|
+ description: 'Could not find the airport',
|
|
|
+ })
|
|
|
+ async remove(@Query('icao') icao: string): Promise<void> {
|
|
|
+ await this.airportService.airport(icao).then(async (airport) => {
|
|
|
+ if (!airport) {
|
|
|
+ throw new HttpException('Airport not found', HttpStatus.NOT_FOUND);
|
|
|
+ }
|
|
|
+ await this.airportService.deleteAirport(icao);
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|