define the controller and service for the airport management
This commit is contained in:
18
src/airport/airport.controller.spec.ts
Normal file
18
src/airport/airport.controller.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { AirportController } from './airport.controller';
|
||||||
|
|
||||||
|
describe('AirportController', () => {
|
||||||
|
let controller: AirportController;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
controllers: [AirportController],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
controller = module.get<AirportController>(AirportController);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(controller).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
237
src/airport/airport.controller.ts
Normal file
237
src/airport/airport.controller.ts
Normal file
@@ -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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/airport/airport.module.ts
Normal file
15
src/airport/airport.module.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { MongooseModule } from '@nestjs/mongoose';
|
||||||
|
import { AirportSchema } from './models/airport.model';
|
||||||
|
import { AirportService } from './airport.service';
|
||||||
|
import { AirportController } from './airport.controller';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
MongooseModule.forFeature([{ name: 'airport', schema: AirportSchema }]),
|
||||||
|
],
|
||||||
|
providers: [AirportService],
|
||||||
|
controllers: [AirportController],
|
||||||
|
exports: [AirportService],
|
||||||
|
})
|
||||||
|
export class AirportModule {}
|
||||||
18
src/airport/airport.service.spec.ts
Normal file
18
src/airport/airport.service.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { AirportService } from './airport.service';
|
||||||
|
|
||||||
|
describe('AirportService', () => {
|
||||||
|
let service: AirportService;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [AirportService],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
service = module.get<AirportService>(AirportService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
64
src/airport/airport.service.ts
Normal file
64
src/airport/airport.service.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { InjectModel } from '@nestjs/mongoose';
|
||||||
|
import { Model } from 'mongoose';
|
||||||
|
import { Airport, AirportDocument } from './models/airport.model';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AirportService {
|
||||||
|
constructor(
|
||||||
|
@InjectModel('airport')
|
||||||
|
private readonly airportModel: Model<AirportDocument>,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
private async airportExists(icao: string): Promise<boolean> {
|
||||||
|
return this.airportModel
|
||||||
|
.find({ icao })
|
||||||
|
.then((response) => response && response.length !== 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
async airportsList(): Promise<string[]> {
|
||||||
|
return this.airportModel.find({}).then((response) => {
|
||||||
|
const icaoCodes: string[] = [];
|
||||||
|
response.forEach((airport) => icaoCodes.push(airport.icao));
|
||||||
|
return icaoCodes;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async airport(icao: string): Promise<Airport> {
|
||||||
|
return this.airportModel.find({ icao }).then((response) => {
|
||||||
|
if (!response || response.length !== 1) return null;
|
||||||
|
return response[0];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async registerAirport(airport: Airport): Promise<boolean> {
|
||||||
|
this.airportExists(airport.icao).then(async (exists) => {
|
||||||
|
if (!exists) {
|
||||||
|
await this.airportModel.create(airport);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !exists;
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateAirport(airport: Airport): Promise<boolean> {
|
||||||
|
this.airportExists(airport.icao).then(async (exists) => {
|
||||||
|
if (exists) {
|
||||||
|
await this.airportModel.findOneAndUpdate(
|
||||||
|
{ icao: airport.icao },
|
||||||
|
airport,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return exists;
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteAirport(icao: string): Promise<void> {
|
||||||
|
this.airportModel.deleteOne({ icao });
|
||||||
|
}
|
||||||
|
}
|
||||||
39
src/airport/dto/airport.dto.ts
Normal file
39
src/airport/dto/airport.dto.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { IsNotEmpty, IsOptional } from 'class-validator';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { ConstraintDto } from './constraint.dto';
|
||||||
|
import { ArrivalRouteDto } from './arrivalroute.dto';
|
||||||
|
import { RunwaySpacingDto } from './runwayspacing.dto';
|
||||||
|
import { PlanningDto } from './planning.dto';
|
||||||
|
|
||||||
|
export class AirportDto {
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The unique ICAO code',
|
||||||
|
example: 'EDDB',
|
||||||
|
})
|
||||||
|
icao: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The constraints in upper airspaces',
|
||||||
|
})
|
||||||
|
upperConstraints: ConstraintDto[];
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The different arrival routes with potential constraints',
|
||||||
|
})
|
||||||
|
arrivalRoutes: ArrivalRouteDto[];
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The spacings for the runways',
|
||||||
|
})
|
||||||
|
spacings: RunwaySpacingDto[];
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The planning configuration',
|
||||||
|
})
|
||||||
|
planning: PlanningDto;
|
||||||
|
}
|
||||||
25
src/airport/dto/arrivalroute.dto.ts
Normal file
25
src/airport/dto/arrivalroute.dto.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { IsNotEmpty, IsOptional } from 'class-validator';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { ConstraintDto } from './constraint.dto';
|
||||||
|
|
||||||
|
export class ArrivalRouteDto {
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The arrival route identifier',
|
||||||
|
example: 'KLF25L',
|
||||||
|
})
|
||||||
|
arrival: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The runway of the arrival route',
|
||||||
|
example: '25L',
|
||||||
|
})
|
||||||
|
runway: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The constraints on the arrival route',
|
||||||
|
})
|
||||||
|
constraints: ConstraintDto[];
|
||||||
|
}
|
||||||
32
src/airport/dto/assignment.dto.ts
Normal file
32
src/airport/dto/assignment.dto.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { IsNotEmpty, IsOptional } from 'class-validator';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
export class AssignmentDto {
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The runway identifier',
|
||||||
|
example: '25L',
|
||||||
|
})
|
||||||
|
runway: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The urgency of the assignment (possible: SHALL, SHOULD, MAY)',
|
||||||
|
example: 'MAY',
|
||||||
|
})
|
||||||
|
type: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The aircrafts (ICAO codes) that require this assignment',
|
||||||
|
example: '[ "A346", "B748" ]',
|
||||||
|
})
|
||||||
|
aircrafts: string[];
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The assigned stands that require this assignment',
|
||||||
|
example: '[ "A01", "A02" ]',
|
||||||
|
})
|
||||||
|
assignedStands: string[];
|
||||||
|
}
|
||||||
26
src/airport/dto/constraint.dto.ts
Normal file
26
src/airport/dto/constraint.dto.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { IsNotEmpty, IsOptional } from 'class-validator';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { ConstraintTypeDto } from './constrainttype.dto';
|
||||||
|
|
||||||
|
export class ConstraintDto {
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The identifier of the waypoint',
|
||||||
|
example: 'AKUDI',
|
||||||
|
})
|
||||||
|
waypoint: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The altitude constraint in feet',
|
||||||
|
example: '{ constraint: 20000, mode: "BELOW" }',
|
||||||
|
})
|
||||||
|
altitude: ConstraintTypeDto;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The speed constraint in knots',
|
||||||
|
example: '{ constraint: 250, mode: "EXACT" }',
|
||||||
|
})
|
||||||
|
speed: ConstraintTypeDto;
|
||||||
|
}
|
||||||
18
src/airport/dto/constrainttype.dto.ts
Normal file
18
src/airport/dto/constrainttype.dto.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { IsNotEmpty } from 'class-validator';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
export class ConstraintTypeDto {
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The identifier of the waypoint',
|
||||||
|
example: 20000,
|
||||||
|
})
|
||||||
|
constraint: number;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The constraint mode (possible: BELOW, EXACT, ABOVE)',
|
||||||
|
example: 'EXACT',
|
||||||
|
})
|
||||||
|
mode: string;
|
||||||
|
}
|
||||||
34
src/airport/dto/optimization.dto.ts
Normal file
34
src/airport/dto/optimization.dto.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { IsNotEmpty } from 'class-validator';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
export class OptimizationDto {
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The window length in seconds',
|
||||||
|
example: 120,
|
||||||
|
})
|
||||||
|
windowSize: number;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The optimized windows for the sequence',
|
||||||
|
example: 3,
|
||||||
|
})
|
||||||
|
windowOverlap: number;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description:
|
||||||
|
'The final approach sequence before the IAF is reached in minutes',
|
||||||
|
example: 10,
|
||||||
|
})
|
||||||
|
fixedBeforeInitialApproachFix: number;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description:
|
||||||
|
'The maximum distance to the airport before the optimization is started',
|
||||||
|
example: 300,
|
||||||
|
})
|
||||||
|
maximumAirportDistance: number;
|
||||||
|
}
|
||||||
18
src/airport/dto/planning.dto.ts
Normal file
18
src/airport/dto/planning.dto.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { IsNotEmpty } from 'class-validator';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { OptimizationDto } from './optimization.dto';
|
||||||
|
import { AssignmentDto } from './assignment.dto';
|
||||||
|
|
||||||
|
export class PlanningDto {
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The optimization parameters',
|
||||||
|
})
|
||||||
|
optimization: OptimizationDto;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The runway assignments',
|
||||||
|
})
|
||||||
|
assignments: AssignmentDto[];
|
||||||
|
}
|
||||||
18
src/airport/dto/runwayspacing.dto.ts
Normal file
18
src/airport/dto/runwayspacing.dto.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { IsNotEmpty, IsOptional } from 'class-validator';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
export class RunwaySpacingDto {
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The runway identifier',
|
||||||
|
example: '25L',
|
||||||
|
})
|
||||||
|
runway: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The touch-down sequence in nautical miles',
|
||||||
|
example: 4,
|
||||||
|
})
|
||||||
|
spacing: number;
|
||||||
|
}
|
||||||
42
src/airport/models/airport.model.ts
Normal file
42
src/airport/models/airport.model.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
||||||
|
import { Document } from 'mongoose';
|
||||||
|
import { ArrivalRoute, ArrivalRouteSchema } from './arrivalroute.model';
|
||||||
|
import { Constraint, ConstraintSchema } from './constraint.model';
|
||||||
|
import { Planning, PlanningSchema } from './planning.model';
|
||||||
|
import { RunwaySpacing, RunwaySpacingSchema } from './runwayspacing.model';
|
||||||
|
|
||||||
|
export type AirportDocument = Airport & Document;
|
||||||
|
|
||||||
|
@Schema()
|
||||||
|
export class Airport {
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: String,
|
||||||
|
})
|
||||||
|
icao: string;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
type: [ConstraintSchema],
|
||||||
|
})
|
||||||
|
upperConstraints: Constraint[];
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: [ArrivalRouteSchema],
|
||||||
|
})
|
||||||
|
arrivalRoutes: ArrivalRoute[];
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: [RunwaySpacingSchema],
|
||||||
|
})
|
||||||
|
spacings: RunwaySpacing[];
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: PlanningSchema,
|
||||||
|
})
|
||||||
|
planning: Planning;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AirportSchema = SchemaFactory.createForClass(Airport);
|
||||||
27
src/airport/models/arrivalroute.model.ts
Normal file
27
src/airport/models/arrivalroute.model.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
||||||
|
import { Document } from 'mongoose';
|
||||||
|
import { Constraint, ConstraintSchema } from './constraint.model';
|
||||||
|
|
||||||
|
export type ArrivalRouteDocument = ArrivalRoute & Document;
|
||||||
|
|
||||||
|
@Schema()
|
||||||
|
export class ArrivalRoute {
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: String,
|
||||||
|
})
|
||||||
|
arrival: string;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: String,
|
||||||
|
})
|
||||||
|
runway: string;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
type: [ConstraintSchema],
|
||||||
|
})
|
||||||
|
constraints: Constraint[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ArrivalRouteSchema = SchemaFactory.createForClass(ArrivalRoute);
|
||||||
32
src/airport/models/assignment.model.ts
Normal file
32
src/airport/models/assignment.model.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
||||||
|
import { Document } from 'mongoose';
|
||||||
|
|
||||||
|
export type AssignmentDocument = Assignment & Document;
|
||||||
|
|
||||||
|
@Schema()
|
||||||
|
export class Assignment {
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: String,
|
||||||
|
})
|
||||||
|
runway: string;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: String,
|
||||||
|
enum: ['SHALL', 'SHOULD', 'MAY'],
|
||||||
|
})
|
||||||
|
type: string;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
type: [String],
|
||||||
|
})
|
||||||
|
aircrafts: string[];
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
type: [String],
|
||||||
|
})
|
||||||
|
assignedStands: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AssignmentSchema = SchemaFactory.createForClass(Assignment);
|
||||||
26
src/airport/models/constraint.model.ts
Normal file
26
src/airport/models/constraint.model.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
||||||
|
import { Document } from 'mongoose';
|
||||||
|
import { ConstraintType, ConstraintTypeSchema } from './constrainttype.model';
|
||||||
|
|
||||||
|
export type ConstraintDocument = Constraint & Document;
|
||||||
|
|
||||||
|
@Schema()
|
||||||
|
export class Constraint {
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: String,
|
||||||
|
})
|
||||||
|
waypoint: string;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
type: ConstraintTypeSchema,
|
||||||
|
})
|
||||||
|
altitude: ConstraintType;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
type: ConstraintTypeSchema,
|
||||||
|
})
|
||||||
|
speed: ConstraintType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ConstraintSchema = SchemaFactory.createForClass(Constraint);
|
||||||
22
src/airport/models/constrainttype.model.ts
Normal file
22
src/airport/models/constrainttype.model.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
||||||
|
import { Document } from 'mongoose';
|
||||||
|
|
||||||
|
export type ConstraintTypeDocument = ConstraintType & Document;
|
||||||
|
|
||||||
|
@Schema()
|
||||||
|
export class ConstraintType {
|
||||||
|
@Prop({
|
||||||
|
type: Number,
|
||||||
|
})
|
||||||
|
constraint: number;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
type: String,
|
||||||
|
default: 'EXACT',
|
||||||
|
enum: ['BELOW', 'EXACT', 'ABOVE'],
|
||||||
|
})
|
||||||
|
mode: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ConstraintTypeSchema =
|
||||||
|
SchemaFactory.createForClass(ConstraintType);
|
||||||
37
src/airport/models/optimization.model.ts
Normal file
37
src/airport/models/optimization.model.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
||||||
|
import { Document } from 'mongoose';
|
||||||
|
|
||||||
|
export type OptimizationDocument = Optimization & Document;
|
||||||
|
|
||||||
|
@Schema()
|
||||||
|
export class Optimization {
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: Number,
|
||||||
|
default: 120,
|
||||||
|
})
|
||||||
|
windowSize: number;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: Number,
|
||||||
|
default: 3,
|
||||||
|
})
|
||||||
|
windowOverlap: number;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: Number,
|
||||||
|
default: 10,
|
||||||
|
})
|
||||||
|
fixedBeforeInitialApproachFix: number;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: Number,
|
||||||
|
default: 300,
|
||||||
|
})
|
||||||
|
maximumAirportDistance: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const OptimizationSchema = SchemaFactory.createForClass(Optimization);
|
||||||
23
src/airport/models/planning.model.ts
Normal file
23
src/airport/models/planning.model.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
||||||
|
import { Document } from 'mongoose';
|
||||||
|
import { Assignment, AssignmentSchema } from './assignment.model';
|
||||||
|
import { Optimization, OptimizationSchema } from './optimization.model';
|
||||||
|
|
||||||
|
export type PlanningDocument = Planning & Document;
|
||||||
|
|
||||||
|
@Schema()
|
||||||
|
export class Planning {
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: OptimizationSchema,
|
||||||
|
})
|
||||||
|
optimization: Optimization;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: [AssignmentSchema],
|
||||||
|
})
|
||||||
|
assignments: Assignment[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PlanningSchema = SchemaFactory.createForClass(Planning);
|
||||||
21
src/airport/models/runwayspacing.model.ts
Normal file
21
src/airport/models/runwayspacing.model.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
||||||
|
import { Document } from 'mongoose';
|
||||||
|
|
||||||
|
export type RunwaySpacingDocument = RunwaySpacing & Document;
|
||||||
|
|
||||||
|
@Schema()
|
||||||
|
export class RunwaySpacing {
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: String,
|
||||||
|
})
|
||||||
|
runway: string;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
required: true,
|
||||||
|
type: Number,
|
||||||
|
})
|
||||||
|
spacing: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RunwaySpacingSchema = SchemaFactory.createForClass(RunwaySpacing);
|
||||||
@@ -4,8 +4,10 @@ import { MongooseModule } from '@nestjs/mongoose';
|
|||||||
import Configuration from './config/configuration';
|
import Configuration from './config/configuration';
|
||||||
import { VersioningModule } from './versioning/versioning.module';
|
import { VersioningModule } from './versioning/versioning.module';
|
||||||
import { PerformanceModule } from './performance/performance.module';
|
import { PerformanceModule } from './performance/performance.module';
|
||||||
|
import { AirportModule } from './airport/airport.module';
|
||||||
import { LoggingModule } from './logging/logging.module';
|
import { LoggingModule } from './logging/logging.module';
|
||||||
import { LoggingController } from './logging/logging.controller';
|
import { LoggingController } from './logging/logging.controller';
|
||||||
|
import { AirportController } from './airport/airport.controller';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -26,8 +28,9 @@ import { LoggingController } from './logging/logging.controller';
|
|||||||
}),
|
}),
|
||||||
VersioningModule,
|
VersioningModule,
|
||||||
PerformanceModule,
|
PerformanceModule,
|
||||||
|
AirportModule,
|
||||||
LoggingModule,
|
LoggingModule,
|
||||||
],
|
],
|
||||||
controllers: [LoggingController],
|
controllers: [LoggingController, AirportController],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
|||||||
Reference in New Issue
Block a user