This repository was archived by the owner on Oct 14, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathgenerator.ts
125 lines (99 loc) · 3.81 KB
/
generator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import fs from 'fs';
import path from 'path';
import { airports } from './airports';
import { IAirport, IFlight } from '../src/types';
const airportIds = airports.map((a) => a.id);
const currentDate = Date.now();
const minutes = 60 * 1000;
const fiveMinutes = 5 * minutes;
const hours = 60 * minutes;
export const generateFlights = (daysSimulated: number, outputFolder: string) => {
const flights = [];
for (let i = 0; i < daysSimulated * 288; i++) {
flights.push(generateFlight(i));
}
const flightsAsJson = JSON.stringify(flights, null, 2);
const outputPath = path.join(outputFolder, 'flights.json');
fs.writeFile(outputPath, flightsAsJson, (err) => {
if (err) {
console.error(err);
} else {
console.log('flights data generated successfully');
}
});
};
export const generateAirports = (outputFolder: string) => {
const airportStats: IAirport[] = airports;
const airportStatsAsJSON = JSON.stringify(airportStats, null, 2);
const outputPath = path.join(outputFolder, 'airports.json');
fs.writeFile(outputPath, airportStatsAsJSON, (err) => {
if (err) {
console.error(err);
} else {
console.log('airport data generated successfully');
}
});
};
const generateFlight = (index: number): IFlight => {
const [fromAirport, toAirport] = getFlightDestinationPair();
const flightTime = calculateFlightTime(fromAirport, toAirport);
const numberOfSeats = randBetween(100, 250);
const numberOfPassengers = randBetween(50, numberOfSeats);
const seatUtilizationPercentage = Math.trunc((numberOfPassengers / numberOfSeats) * 100);
const departureTime = roundTo(currentDate + index * fiveMinutes, fiveMinutes);
const arrivalTime = departureTime + flightTime;
return {
id: randBetween(10e6, 20e7).toString(36).toUpperCase(),
departureAirportId: fromAirport.id,
arrivalAirportId: toAirport.id,
seats: numberOfSeats,
passengers: numberOfPassengers,
seatUtilizationPercentage,
departureTime: new Date(departureTime),
arrivalTime: new Date(arrivalTime),
flightTimeMinutes: Math.floor(flightTime / minutes),
};
};
const getFlightDestinationPair = (): [IAirport, IAirport] => {
const fromOrdinal = randBetween(0, airportIds.length);
const jump = randBetween(1, airportIds.length);
const toOrdinal = (fromOrdinal + jump) % airportIds.length;
return [airports[fromOrdinal], airports[toOrdinal]];
};
const calculateFlightTime = (airport1: IAirport, airport2: IAirport) => {
const distance = distanceBetween(airport1, airport2);
const timeForTakeoffAndLanding = 30 * minutes;
const avgFlightSpeed = 800; // km/h
const totalFlightTime = timeForTakeoffAndLanding + (distance / avgFlightSpeed) * hours;
return roundTo(totalFlightTime, 5 * minutes);
};
const randBetween = (min: number, max: number) => {
return Math.floor(Math.random() * (max - min) + min);
};
const toRad = (deg: number) => (deg / 180) * Math.PI;
const distanceBetween = (airport1: IAirport, airport2: IAirport) => {
const phi1 = toRad(airport1.latitude);
const phi2 = toRad(airport2.latitude);
const lambda1 = toRad(airport1.longitude);
const lambda2 = toRad(airport2.longitude);
const radius = 6371; //km
const { sin, cos, sqrt, asin } = Math;
const sinoidalAvg = (a: number, b: number) => sin(sin(Math.abs(a - b) / 2));
const haversineFactor = sinoidalAvg(phi2, phi1) + cos(phi1) * cos(phi2) * sinoidalAvg(lambda2, lambda1);
const haversineRounded = Math.min(1, haversineFactor);
const distance = 2 * radius * asin(sqrt(haversineRounded));
if (!distance) {
console.log(`Error generating data for ${airport1.id} -> ${airport2.id}`, {
phi1,
phi2,
lambda1,
lambda2,
haversineFactor,
distance,
});
}
return distance;
};
const roundTo = (n: number, accuracy: number) => {
return Math.round(n / accuracy) * accuracy;
};