New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@fboes/aerofly-patterns

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fboes/aerofly-patterns - npm Package Compare versions

Comparing version 2.1.2 to 2.2.0

9

CHANGELOG.md
# Changelog
## 2.2.0
- Added navigational aids to GeoJSON
- Improved GeoJSON output
- Added TPA configuration
- Added simple mechanism to determine right pattern
- Improved support for helipads
- Improved support for "L"/"R" runways
## 2.1.2

@@ -4,0 +13,0 @@

2

dist/index.js

@@ -27,2 +27,2 @@ #!/usr/bin/env node

await app.build(process.cwd());
console.log("✅ Done");
console.log(`✅ Done with ${app.airport?.name} (${app.airport?.id})`);

@@ -6,3 +6,3 @@ // @ts-check

import { Configuration } from "./Configuration.js";
import { FeatureCollection, Feature } from "@fboes/geojson";
import { FeatureCollection, Feature, LineString } from "@fboes/geojson";
import { Scenario } from "./Scenario.js";

@@ -100,2 +100,3 @@ import { DateYielder } from "./DateYielder.js";

"marker-symbol": "airport",
frequency: this.airport.localFrequency,
}),

@@ -107,3 +108,7 @@ ]);

title: r.id,
"marker-symbol": r === scenario.activeRunway ? "triangle" : "triangle-stroked",
"marker-symbol":
r === scenario.activeRunway ? "triangle" : r.runwayType === "H" ? "heliport" : "triangle-stroked",
alignment: r.alignment,
frequency: r.ilsFrequency,
isRightPattern: r.isRightPattern,
}),

@@ -113,2 +118,13 @@ );

this.airport.navaids.forEach((n) => {
geoJson.addFeature(
new Feature(n.position, {
title: n.id,
"marker-symbol": "communications-tower",
frequency: n.frequency,
type: n.type,
}),
);
});
geoJson.addFeature(

@@ -121,2 +137,32 @@ new Feature(scenario.aircraft.position, {

const waypoints = scenario.patternWaypoints.map((p) => {
return p.position;
});
waypoints.push(scenario.patternWaypoints[0].position);
geoJson.addFeature(
new Feature(new LineString(waypoints), {
title: "Traffic pattern",
"stroke-opacity": 0.2,
}),
);
if (scenario.activeRunway) {
geoJson.addFeature(
new Feature(
new LineString([
scenario.aircraft.position,
scenario.entryWaypoint?.position,
scenario.patternWaypoints[2].position,
scenario.patternWaypoints[3].position,
scenario.patternWaypoints[4].position,
scenario.activeRunway?.position,
]),
{
title: "Flight plan",
stroke: "#ff1493",
},
),
);
}
scenario.patternWaypoints.forEach((p) => {

@@ -300,4 +346,4 @@ geoJson.addFeature(

"",
`| No | Local date | Local time | Wind | Clouds | Visibility | Runway | Aircraft position |`,
`| :-: | ---------- | ---------: | ------------ | --------------- | ---------: | ------- | ------------------- |`,
`| No | Local date | Local time | Wind | Clouds | Visibility | Runway | Aircraft position |`,
`| :-: | ---------- | ---------: | ------------ | --------------- | ---------: | -------- | ------------------- |`,
);

@@ -322,3 +368,3 @@ this.scenarios.forEach((s, index) => {

pad(Math.round(s.weather?.visibility ?? 0), 7, true) + " SM",
pad(s.activeRunway?.id + (s.activeRunway?.isRightPattern ? " (RP)" : ""), 7),
pad(s.activeRunway?.id + (s.activeRunway?.isRightPattern ? " (RP)" : ""), 8),
Formatter.getDirectionArrow(s.aircraft.vectorFromAirport.bearing) +

@@ -325,0 +371,0 @@ " To the " +

@@ -18,3 +18,3 @@ // @ts-check

*/
constructor(airportJson, configuration) {
constructor(airportJson, configuration = null) {
this.id = airportJson.id;

@@ -30,2 +30,3 @@ this.position = new Point(airportJson.lon, airportJson.lat, airportJson.elev);

.replace(/\bRGNL\b/g, "REGIONAL")
.replace(/\bFLD\b/g, "FIELD")
.replace(/(\/)/g, " $1 ")

@@ -182,3 +183,3 @@ .toLowerCase()

* @param {import('./Configuration.js').Configuration?} configuration
* @returns {[AirportRunway, AirportRunway]}
* @returns {AirportRunway[]} both directions, or in case of helipads on single helipad
*/

@@ -205,6 +206,9 @@ buildRunways(runwayJson, airportPosition, configuration) {

// Helipads
const alignmentBase = runwayJson.alignment !== "-" ? Number(runwayJson.alignment) : 0;
/**
* @type {[number, number]} both directions
*/
const alignment = [Number(runwayJson.alignment), Degree(Number(runwayJson.alignment) + 180)];
const alignment = [alignmentBase, Degree(alignmentBase + 180)];

@@ -219,3 +223,12 @@ /**

return [
const rightPatternRunways = [
configuration && configuration.rightPatternRunways.length
? configuration.rightPatternRunways.indexOf(id[0]) !== -1
: id[0].endsWith("R"),
configuration && configuration.rightPatternRunways.length
? configuration.rightPatternRunways.indexOf(id[1]) !== -1
: id[1].endsWith("R"),
];
const runways = [
new AirportRunway(

@@ -226,14 +239,21 @@ id[0],

positions[0],
configuration?.rightPatternRunways.indexOf(id[0]) !== -1,
rightPatternRunways[0],
configuration?.preferredRunways.indexOf(id[0]) !== -1,
),
new AirportRunway(
id[1],
dimension,
alignment[1],
positions[1],
configuration?.rightPatternRunways.indexOf(id[1]) !== -1,
configuration?.preferredRunways.indexOf(id[1]) !== -1,
),
];
if (id[1] !== "") {
runways.push(
new AirportRunway(
id[1],
dimension,
alignment[1],
positions[1],
rightPatternRunways[1],
configuration?.preferredRunways.indexOf(id[1]) !== -1,
),
);
}
return runways;
}

@@ -265,6 +285,8 @@ }

const alignmentAdjustment = id.endsWith("R") ? 0.1 : 0;
/**
* @type {number}
*/
this.alignment = Degree(alignment);
this.alignment = Degree(alignment + alignmentAdjustment);

@@ -286,3 +308,3 @@ /**

const endMatch = id.match(/[SGHUW]$/);
const endMatch = id.match(/([SGUW]$)|H/);

@@ -289,0 +311,0 @@ /**

@@ -10,2 +10,3 @@ //@ts-check

this.checkMarthasVineyard();
this.checkStockton();
}

@@ -115,2 +116,61 @@

}
checkStockton() {
/** @type {import('./AviationWeatherApi.js').AviationWeatherApiAirport} */
const airportJson = {
id: "KSCK",
name: "STOCKTON/STOCKTON_METRO",
lat: 37.8944,
lon: -121.2387,
elev: 10.1,
mag_dec: "14E",
rwy_num: 3,
tower: "T",
beacon: "B",
runways: [
{
id: "11L/29R",
dimension: "10249x150",
surface: "A",
alignment: "128",
},
{
id: "11R/29L",
dimension: "4448x75",
surface: "A",
alignment: "128",
},
{
id: "H1",
dimension: "70x70",
surface: "C",
alignment: "-",
},
],
freqs: [
{
type: "ATIS",
freq: 118.25,
},
{
type: "LCL/P",
freq: 120.3,
},
],
};
const airport = new Airport(airportJson);
assert.strictEqual(airport.id, "KSCK");
assert.strictEqual(airport.hasTower, true);
assert.strictEqual(airport.hasBeacon, true);
assert.strictEqual(airport.runways.length, 5);
assert.strictEqual(airport.runways[0].id, "11L");
assert.strictEqual(airport.runways[0].isRightPattern, false);
assert.strictEqual(airport.runways[2].id, "11R");
assert.strictEqual(airport.runways[2].isRightPattern, true);
assert.strictEqual(airport.runways[4].runwayType, "H");
console.log(`✅ ${this.constructor.name}.checkStockton successful`);
}
}

@@ -36,3 +36,3 @@ // @ts-check

* @property {"A"|"C"|"G"} surface "A" Asphalt, "C" Concrete, "G" Grass
* @property {string} alignment "013"
* @property {string} alignment "013" or "-"
* @see https://aviationweather.gov/data/api/#/Data/dataAirport

@@ -39,0 +39,0 @@ */

@@ -29,3 +29,3 @@ // @ts-check

default: "0",
description: "Minimum safe altitude of aircraft, in 100ft. At least airport elevation.",
description: "Minimum safe altitude of aircraft, in 100ft MSL. At least airport elevation.",
example: "145",

@@ -41,4 +41,9 @@ },

default: "8",
description: "Initial distance from airport in Nautical Miles.",
description: "Initial aircraft distance from airport in Nautical Miles.",
},
"pattern-altitude": {
type: "string",
default: "1000",
description: "Pattern altitude in ft AGL. For MSL see `--pattern-altitude-msl`",
},
"pattern-distance": {

@@ -49,2 +54,7 @@ type: "string",

},
"pattern-final-distance": {
type: "string",
default: "1",
description: "Pattern final distance from airport runway edge in Nautical Miles.",
},
"rnd-heading": {

@@ -61,2 +71,8 @@ type: "string",

},
"pattern-altitude-msl": {
type: "boolean",
short: "m",
default: false,
description: "Pattern altitude is in MSL instead of AGL",
},
directory: {

@@ -112,5 +128,7 @@ type: "boolean",

*/
this.rightPatternRunways = String(values["right-pattern"])
.toUpperCase()
.split(/[,\s]+/);
this.rightPatternRunways = values["right-pattern"]
? String(values["right-pattern"])
.toUpperCase()
.split(/[,\s]+/)
: [];

@@ -133,2 +151,7 @@ /**

/**
* @type {number} in ft AGL (or MSL if isPatternAltitudeMsl)
*/
this.patternAltitude = Number(values["pattern-altitude"]);
/**
* @type {number} in Nautical Miles

@@ -139,2 +162,7 @@ */

/**
* @type {number} in Nautical miles
*/
this.patternFinalDistance = Number(values["pattern-final-distance"]);
/**
* @type {number} Randomized aircraft heading deviation from direct heading to airport in degree.

@@ -147,7 +175,14 @@ */

*/
this.preferredRunways = String(values["prefer-rwy"])
.toUpperCase()
.split(/[,\s]+/);
this.preferredRunways = values["prefer-rwy"]
? String(values["prefer-rwy"])
.toUpperCase()
.split(/[,\s]+/)
: [];
/**
* @type {boolean} if this.patternAltitude is in MSL instead of AGL
*/
this.isPatternAltitudeMsl = Boolean(values["pattern-altitude-msl"]);
/**
* @type {boolean} if files should be created in subfolder

@@ -154,0 +189,0 @@ */

@@ -75,2 +75,7 @@ // @ts-check

this.patternWaypoints = [];
/**
* @type {import("./AeroflyPatterns.js").AeroflyPatternsWaypointable?}
*/
this.entryWaypoint = null;
}

@@ -124,13 +129,35 @@

/**
* @type {number} in meters
*/
const exitDistance = this.configuration.patternDistance * Units.meterPerNauticalMile;
/**
* @type {number} in meters
*/
const downwindDistance = this.configuration.patternDistance * Units.meterPerNauticalMile;
const finalDistance = this.configuration.patternDistance * Units.meterPerNauticalMile;
const patternOrientation = this.activeRunway.alignment + Degree(this.activeRunway.isRightPattern ? 90 : 270);
const patternAltitude = (this.airport.position.elevation ?? 0) + 1000 / Units.feetPerMeter;
/**
* @type {number} meters to sink per 1 NM to have 3° glide slope
* @type {number} in meters
*/
const glideSlope = 319.8 / Units.feetPerMeter;
const finalDistance = this.configuration.patternFinalDistance * Units.meterPerNauticalMile;
/**
* @type {number} in degree
*/
const patternOrientation = Degree(this.activeRunway.alignment + (this.activeRunway.isRightPattern ? 90 : 270));
/**
* @type {number} in meters MSL
*/
let patternAltitude = this.configuration.patternAltitude / Units.feetPerMeter;
if (!this.configuration.isPatternAltitudeMsl && this.airport.position.elevation) {
patternAltitude += this.airport.position.elevation;
}
/**
* @type {number} meters to sink per meter distance to have 3° glide slope
*/
const glideSlope = 319.8 / Units.feetPerMeter / Units.meterPerNauticalMile;
if (this.weather?.windDirection) {

@@ -145,3 +172,3 @@ const crosswindAngle = degreeDifference(this.activeRunway.alignment, this.weather.windDirection);

);
const finalAltitude = (this.airport.position.elevation ?? 0) + this.configuration.patternDistance * glideSlope;
const finalAltitude = (this.airport.position.elevation ?? 0) + finalDistance * glideSlope;
activeRunwayFinal.elevation = Math.min(finalAltitude, patternAltitude);

@@ -151,3 +178,3 @@

const activeRunwayBase = activeRunwayFinal.getPointBy(new Vector(downwindDistance, patternOrientation));
const baseAltitude = finalAltitude + this.configuration.patternDistance * glideSlope;
const baseAltitude = finalAltitude + downwindDistance * glideSlope;
activeRunwayBase.elevation = Math.min(baseAltitude, patternAltitude);

@@ -187,2 +214,12 @@

];
this.entryWaypoint = {
id: this.activeRunway.id + "-VENTRY",
position: activeRunwayEntry.getPointBy(
new Vector(
0.5 * Units.meterPerNauticalMile,
Degree(patternOrientation + (this.activeRunway.isRightPattern ? -45 : 45)),
),
),
};
}

@@ -189,0 +226,0 @@

{
"name": "@fboes/aerofly-patterns",
"version": "2.1.2",
"version": "2.2.0",
"description": "Landegerät - Create landing pattern lessons for Aerofly FS 4.",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -35,3 +35,3 @@ # Aerofly Landegerät

Example value: 24,33
--min-altitude=.. Minimum safe altitude of aircraft, in 100ft. At least airport elevation.
--min-altitude=.. Minimum safe altitude of aircraft, in 100ft MSL. At least airport elevation.
Default value: 0

@@ -41,6 +41,10 @@ Example value: 145

Default value: 10
--distance=.. Initial distance from airport in Nautical Miles.
--distance=.. Initial aircraft distance from airport in Nautical Miles.
Default value: 8
--pattern-altitude=.. Pattern altitude in ft AGL. For MSL see `--pattern-altitude-msl`
Default value: 1000
--pattern-distance=.. Pattern distance from airport runway in Nautical Miles.
Default value: 1
--pattern-final-distance=.. Pattern final distance from airport runway edge in Nautical Miles.
Default value: 1
--rnd-heading=.. Randomized aircraft heading deviation from direct heading to airport in degree.

@@ -50,2 +54,3 @@ Default value: 0

Example value: 24,33
--pattern-altitude-msl, -m Pattern altitude is in MSL instead of AGL
--directory, -d Create files in a subdirectory instead of current directory.

@@ -52,0 +57,0 @@ --geojson, -g Create a GeoJSON file.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc