Fix more CF
This commit is contained in:
parent
e9bab0306f
commit
73373420d3
@ -91,6 +91,11 @@ export const Map: FC<MapProps> = ({ airport, chart, procedures }) => {
|
|||||||
shape: 'triangle',
|
shape: 'triangle',
|
||||||
radius: 6,
|
radius: 6,
|
||||||
});
|
});
|
||||||
|
else if (properties.isInitial)
|
||||||
|
return L.shapeMarker(latlng, {
|
||||||
|
shape: 'arrowhead',
|
||||||
|
radius: 6,
|
||||||
|
});
|
||||||
|
|
||||||
return L.shapeMarker(latlng, {
|
return L.shapeMarker(latlng, {
|
||||||
shape: 'star-4',
|
shape: 'star-4',
|
||||||
|
|||||||
@ -145,10 +145,12 @@ export const ProcedureSelect: FC<ProcedureSelectProps> = ({
|
|||||||
key={terminal.ID}
|
key={terminal.ID}
|
||||||
className="cursor-pointer rounded border border-gray-300 bg-gray-300 px-2 py-1 font-semibold focus:outline-2 focus-visible:outline-2 disabled:bg-gray-100"
|
className="cursor-pointer rounded border border-gray-300 bg-gray-300 px-2 py-1 font-semibold focus:outline-2 focus-visible:outline-2 disabled:bg-gray-100"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
setInFlight(terminal.ID);
|
||||||
parser.loadTerminal(terminal.ID).then(() => {
|
parser.loadTerminal(terminal.ID).then(() => {
|
||||||
setSelectedTerminal(terminal);
|
setSelectedTerminal(terminal);
|
||||||
const transitions = new Set(parser.procedures.map((proc) => proc.Transition));
|
const transitions = new Set(parser.procedures.map((proc) => proc.Transition));
|
||||||
handleSelection(Array.from(transitions), terminal);
|
handleSelection(Array.from(transitions), terminal);
|
||||||
|
setInFlight(undefined);
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
disabled={!!inFlight}
|
disabled={!!inFlight}
|
||||||
@ -167,10 +169,12 @@ export const ProcedureSelect: FC<ProcedureSelectProps> = ({
|
|||||||
key={terminal.ID}
|
key={terminal.ID}
|
||||||
className="cursor-pointer rounded border border-gray-300 bg-gray-300 px-2 py-1 font-semibold focus:outline-2 focus-visible:outline-2 disabled:bg-gray-100"
|
className="cursor-pointer rounded border border-gray-300 bg-gray-300 px-2 py-1 font-semibold focus:outline-2 focus-visible:outline-2 disabled:bg-gray-100"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
setInFlight(terminal.ID);
|
||||||
parser.loadTerminal(terminal.ID).then(() => {
|
parser.loadTerminal(terminal.ID).then(() => {
|
||||||
setSelectedTerminal(terminal);
|
setSelectedTerminal(terminal);
|
||||||
const transitions = new Set(parser.procedures.map((proc) => proc.Transition));
|
const transitions = new Set(parser.procedures.map((proc) => proc.Transition));
|
||||||
handleSelection(Array.from(transitions), terminal);
|
handleSelection(Array.from(transitions), terminal);
|
||||||
|
setInFlight(undefined);
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
disabled={!!inFlight}
|
disabled={!!inFlight}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import computeDestinationPoint from 'geolib/es/computeDestinationPoint';
|
import computeDestinationPoint from 'geolib/es/computeDestinationPoint';
|
||||||
|
import getGreatCircleBearing from 'geolib/es/getGreatCircleBearing';
|
||||||
import getPreciseDistance from 'geolib/es/getPreciseDistance';
|
import getPreciseDistance from 'geolib/es/getPreciseDistance';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -6,7 +7,8 @@ import getPreciseDistance from 'geolib/es/getPreciseDistance';
|
|||||||
* @param crsIntoOrigin Course into arc origin point
|
* @param crsIntoOrigin Course into arc origin point
|
||||||
* @param start Arc origin point
|
* @param start Arc origin point
|
||||||
* @param center Arc center point
|
* @param center Arc center point
|
||||||
* @param turnDir
|
* @param end Arc end point
|
||||||
|
* @param turnDir Turn Direction
|
||||||
* @returns Line segments
|
* @returns Line segments
|
||||||
*/
|
*/
|
||||||
export const generateRFArc = (
|
export const generateRFArc = (
|
||||||
@ -14,6 +16,7 @@ export const generateRFArc = (
|
|||||||
crsIntoOrigin: number,
|
crsIntoOrigin: number,
|
||||||
start: NavFix,
|
start: NavFix,
|
||||||
center: NavFix,
|
center: NavFix,
|
||||||
|
end: NavFix,
|
||||||
turnDir: TurnDirection
|
turnDir: TurnDirection
|
||||||
) => {
|
) => {
|
||||||
const line: LineSegment[] = [[start.longitude, start.latitude]];
|
const line: LineSegment[] = [[start.longitude, start.latitude]];
|
||||||
@ -26,20 +29,10 @@ export const generateRFArc = (
|
|||||||
turnDir = prov > 0 ? 'L' : 'R';
|
turnDir = prov > 0 ? 'L' : 'R';
|
||||||
}
|
}
|
||||||
|
|
||||||
let crsOrthogonalOnOrigin;
|
let crsOrthogonalOnOrigin = getGreatCircleBearing(center, start);
|
||||||
let crsOrthogonalOnEndpoint;
|
const crsOrthogonalOnEndpoint = getGreatCircleBearing(center, end);
|
||||||
if (turnDir === 'R') {
|
|
||||||
crsOrthogonalOnOrigin = (crsIntoOrigin + 90).normaliseDegrees();
|
|
||||||
crsOrthogonalOnEndpoint = (crsIntoEndpoint + 90).normaliseDegrees();
|
|
||||||
} else {
|
|
||||||
crsOrthogonalOnOrigin = (crsIntoOrigin - 90).normaliseDegrees();
|
|
||||||
crsOrthogonalOnEndpoint = (crsIntoEndpoint - 90).normaliseDegrees();
|
|
||||||
}
|
|
||||||
|
|
||||||
const arcRad = getPreciseDistance(center, start);
|
const arcRad = getPreciseDistance(center, start);
|
||||||
|
|
||||||
crsOrthogonalOnOrigin = crsOrthogonalOnOrigin.reciprocalCourse();
|
|
||||||
crsOrthogonalOnEndpoint = crsOrthogonalOnEndpoint.reciprocalCourse();
|
|
||||||
// Start turn immediately
|
// Start turn immediately
|
||||||
if (turnDir === 'R') {
|
if (turnDir === 'R') {
|
||||||
crsOrthogonalOnOrigin += crsOrthogonalOnOrigin < 1 ? crsOrthogonalOnOrigin : 1;
|
crsOrthogonalOnOrigin += crsOrthogonalOnOrigin < 1 ? crsOrthogonalOnOrigin : 1;
|
||||||
|
|||||||
@ -63,7 +63,7 @@ export const generateTangentArc = (
|
|||||||
intcArcOnCrsIntoEndpoint,
|
intcArcOnCrsIntoEndpoint,
|
||||||
crsOrthogonalOnEndpoint
|
crsOrthogonalOnEndpoint
|
||||||
);
|
);
|
||||||
if (Math.abs(crsOrthogonalOnEndpoint - crsOrthogonalOnOrigin) <= 0.1 && arcCenter)
|
if (!crsOrthogonalOnEndpoint.equal(crsOrthogonalOnOrigin) && arcCenter)
|
||||||
arcRad = getPreciseDistance(arcCenter, start);
|
arcRad = getPreciseDistance(arcCenter, start);
|
||||||
else {
|
else {
|
||||||
arcRad = getPreciseDistance(start, end) / 2;
|
arcRad = getPreciseDistance(start, end) / 2;
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import getGreatCircleBearing from 'geolib/es/getGreatCircleBearing';
|
|||||||
import getPreciseDistance from 'geolib/es/getPreciseDistance';
|
import getPreciseDistance from 'geolib/es/getPreciseDistance';
|
||||||
import Parser from '../parser';
|
import Parser from '../parser';
|
||||||
import { generateTangentArc } from '../pathGenerators/generateTangentArc';
|
import { generateTangentArc } from '../pathGenerators/generateTangentArc';
|
||||||
|
import { computeIntersection } from '../utils/computeIntersection';
|
||||||
import { computeSpeed } from '../utils/computeSpeed';
|
import { computeSpeed } from '../utils/computeSpeed';
|
||||||
import { computeTurnRate } from '../utils/computeTurnRate';
|
import { computeTurnRate } from '../utils/computeTurnRate';
|
||||||
|
|
||||||
@ -28,7 +29,6 @@ export const TerminatorsCF = (
|
|||||||
IsFAF: leg.IsFAF,
|
IsFAF: leg.IsFAF,
|
||||||
IsMAP: leg.IsMAP,
|
IsMAP: leg.IsMAP,
|
||||||
};
|
};
|
||||||
const crsToIntercept = leg.Course.toTrue(targetFix);
|
|
||||||
|
|
||||||
// Compute overfly arc
|
// Compute overfly arc
|
||||||
let arc1: LineSegment[] | null = null;
|
let arc1: LineSegment[] | null = null;
|
||||||
@ -59,7 +59,13 @@ export const TerminatorsCF = (
|
|||||||
if (endDist <= 25 || (endCrs <= crsIntoEndpoint + 1 && endCrs >= crsIntoEndpoint - 1)) arc = arc1;
|
if (endDist <= 25 || (endCrs <= crsIntoEndpoint + 1 && endCrs >= crsIntoEndpoint - 1)) arc = arc1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arc && previousFix.isFlyOver && (!lastCourse.equal(crsIntoEndpoint) || !lastCourse.equal(crsToIntercept))) {
|
const intercept = computeIntersection(previousFix, lastCourse, targetFix, crsIntoEndpoint.reciprocalCourse());
|
||||||
|
if (
|
||||||
|
!arc &&
|
||||||
|
previousFix.isFlyOver &&
|
||||||
|
(!lastCourse.equal(crsIntoEndpoint) || !lastCourse.equal(crsIntoEndpoint)) &&
|
||||||
|
!(intercept?.latitude === targetFix.latitude && intercept.longitude === targetFix.longitude)
|
||||||
|
) {
|
||||||
const turnRate = computeTurnRate(speed, Parser.AC_BANK);
|
const turnRate = computeTurnRate(speed, Parser.AC_BANK);
|
||||||
let updatedCrsToIntercept = getGreatCircleBearing(previousFix, targetFix);
|
let updatedCrsToIntercept = getGreatCircleBearing(previousFix, targetFix);
|
||||||
|
|
||||||
@ -72,19 +78,26 @@ export const TerminatorsCF = (
|
|||||||
|
|
||||||
// Generate arc
|
// Generate arc
|
||||||
let lastDistance = getPreciseDistance(previousFix, targetFix);
|
let lastDistance = getPreciseDistance(previousFix, targetFix);
|
||||||
while (!updatedCrsToIntercept.equal(crsToIntercept)) {
|
const reversal = Math.abs(lastCourse - crsIntoEndpoint) >= 90;
|
||||||
|
while (!updatedCrsToIntercept.equal(crsIntoEndpoint)) {
|
||||||
let interceptAngle = 0;
|
let interceptAngle = 0;
|
||||||
if (leg.TurnDir === 'R') interceptAngle = Math.abs(lastCourse - crsToIntercept);
|
if (leg.TurnDir === 'R') interceptAngle = Math.abs(lastCourse - crsIntoEndpoint);
|
||||||
else interceptAngle = Math.abs(crsToIntercept - lastCourse);
|
else interceptAngle = Math.abs(crsIntoEndpoint - lastCourse);
|
||||||
|
|
||||||
let time = 0;
|
let time = 0;
|
||||||
const increment = 0.1;
|
const increment = 0.1;
|
||||||
if (interceptAngle < 44.9 || interceptAngle >= 45.1) {
|
if (interceptAngle < 44.9 || interceptAngle >= 45.1) {
|
||||||
if (leg.TurnDir === 'R') {
|
if (leg.TurnDir === 'R') {
|
||||||
lastCourse = (lastCourse + increment).normaliseDegrees();
|
lastCourse =
|
||||||
|
reversal || updatedCrsToIntercept >= crsIntoEndpoint
|
||||||
|
? (lastCourse + increment).normaliseDegrees()
|
||||||
|
: lastCourse;
|
||||||
time = increment / turnRate;
|
time = increment / turnRate;
|
||||||
} else {
|
} else {
|
||||||
lastCourse = (lastCourse - increment).normaliseDegrees();
|
lastCourse =
|
||||||
|
reversal || updatedCrsToIntercept <= crsIntoEndpoint
|
||||||
|
? (lastCourse - increment).normaliseDegrees()
|
||||||
|
: lastCourse;
|
||||||
time = increment / turnRate;
|
time = increment / turnRate;
|
||||||
}
|
}
|
||||||
} else time = increment / turnRate;
|
} else time = increment / turnRate;
|
||||||
|
|||||||
@ -12,6 +12,7 @@ export const TerminatorsIF = (leg: IFTerminalEntry, waypoint?: Waypoint): NavFix
|
|||||||
altitudeConstraint: leg.Alt,
|
altitudeConstraint: leg.Alt,
|
||||||
IsFAF: leg.IsFAF,
|
IsFAF: leg.IsFAF,
|
||||||
IsMAP: leg.IsMAP,
|
IsMAP: leg.IsMAP,
|
||||||
|
isInitial: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
return targetFix;
|
return targetFix;
|
||||||
|
|||||||
@ -26,6 +26,7 @@ export const TerminatorsRF = (
|
|||||||
lastCourse,
|
lastCourse,
|
||||||
previousFix,
|
previousFix,
|
||||||
{ latitude: leg.CenterLat, longitude: leg.CenterLon },
|
{ latitude: leg.CenterLat, longitude: leg.CenterLon },
|
||||||
|
targetFix,
|
||||||
leg.TurnDir
|
leg.TurnDir
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -80,10 +80,12 @@ export const TerminatorsTF = (
|
|||||||
const increment = 0.1;
|
const increment = 0.1;
|
||||||
if (interceptAngle < 44.9 || interceptAngle >= 45.1) {
|
if (interceptAngle < 44.9 || interceptAngle >= 45.1) {
|
||||||
if (leg.TurnDir === 'R') {
|
if (leg.TurnDir === 'R') {
|
||||||
lastCourse = (lastCourse + increment).normaliseDegrees();
|
lastCourse =
|
||||||
|
updatedCrsToIntercept >= crsIntoEndpoint ? (lastCourse + increment).normaliseDegrees() : lastCourse;
|
||||||
time = increment / turnRate;
|
time = increment / turnRate;
|
||||||
} else {
|
} else {
|
||||||
lastCourse = (lastCourse - increment).normaliseDegrees();
|
lastCourse =
|
||||||
|
updatedCrsToIntercept >= crsIntoEndpoint ? (lastCourse - increment).normaliseDegrees() : lastCourse;
|
||||||
time = increment / turnRate;
|
time = increment / turnRate;
|
||||||
}
|
}
|
||||||
} else time = increment / turnRate;
|
} else time = increment / turnRate;
|
||||||
|
|||||||
@ -38,16 +38,16 @@ Number.prototype.toTrue = function (fix) {
|
|||||||
|
|
||||||
let lowerLatLowerLonMagVar = (magVarTable[lowerLatLowerLonOffset + 1] << 8) + magVarTable[lowerLatLowerLonOffset];
|
let lowerLatLowerLonMagVar = (magVarTable[lowerLatLowerLonOffset + 1] << 8) + magVarTable[lowerLatLowerLonOffset];
|
||||||
lowerLatLowerLonMagVar = (lowerLatLowerLonMagVar * 0x168) / 0x10000;
|
lowerLatLowerLonMagVar = (lowerLatLowerLonMagVar * 0x168) / 0x10000;
|
||||||
lowerLatLowerLonMagVar = lowerLatLowerLonMagVar > 180 ? lowerLatLowerLonMagVar - 460 : lowerLatLowerLonMagVar;
|
lowerLatLowerLonMagVar = lowerLatLowerLonMagVar > 180 ? lowerLatLowerLonMagVar - 360 : lowerLatLowerLonMagVar;
|
||||||
let lowerLatUpperLonMagVar = (magVarTable[lowerLatUpperLonOffset + 1] << 8) + magVarTable[lowerLatUpperLonOffset];
|
let lowerLatUpperLonMagVar = (magVarTable[lowerLatUpperLonOffset + 1] << 8) + magVarTable[lowerLatUpperLonOffset];
|
||||||
lowerLatUpperLonMagVar = (lowerLatUpperLonMagVar * 0x168) / 0x10000;
|
lowerLatUpperLonMagVar = (lowerLatUpperLonMagVar * 0x168) / 0x10000;
|
||||||
lowerLatUpperLonMagVar = lowerLatUpperLonMagVar > 180 ? lowerLatUpperLonMagVar - 460 : lowerLatUpperLonMagVar;
|
lowerLatUpperLonMagVar = lowerLatUpperLonMagVar > 180 ? lowerLatUpperLonMagVar - 360 : lowerLatUpperLonMagVar;
|
||||||
let upperLatLowerLonMagVar = (magVarTable[upperLatLowerLonOffset + 1] << 8) + magVarTable[upperLatLowerLonOffset];
|
let upperLatLowerLonMagVar = (magVarTable[upperLatLowerLonOffset + 1] << 8) + magVarTable[upperLatLowerLonOffset];
|
||||||
upperLatLowerLonMagVar = (upperLatLowerLonMagVar * 0x168) / 0x10000;
|
upperLatLowerLonMagVar = (upperLatLowerLonMagVar * 0x168) / 0x10000;
|
||||||
upperLatLowerLonMagVar = upperLatLowerLonMagVar > 180 ? upperLatLowerLonMagVar - 460 : upperLatLowerLonMagVar;
|
upperLatLowerLonMagVar = upperLatLowerLonMagVar > 180 ? upperLatLowerLonMagVar - 360 : upperLatLowerLonMagVar;
|
||||||
let upperLatUpperLonMagVar = (magVarTable[upperLatUpperLonOffset + 1] << 8) + magVarTable[upperLatUpperLonOffset];
|
let upperLatUpperLonMagVar = (magVarTable[upperLatUpperLonOffset + 1] << 8) + magVarTable[upperLatUpperLonOffset];
|
||||||
upperLatUpperLonMagVar = (upperLatUpperLonMagVar * 0x168) / 0x10000;
|
upperLatUpperLonMagVar = (upperLatUpperLonMagVar * 0x168) / 0x10000;
|
||||||
upperLatUpperLonMagVar = upperLatUpperLonMagVar > 180 ? upperLatUpperLonMagVar - 460 : upperLatUpperLonMagVar;
|
upperLatUpperLonMagVar = upperLatUpperLonMagVar > 180 ? upperLatUpperLonMagVar - 360 : upperLatUpperLonMagVar;
|
||||||
|
|
||||||
const lowerLatRatioLon = lowerLatLowerLonMagVar + ratioLon * (lowerLatUpperLonMagVar - lowerLatLowerLonMagVar);
|
const lowerLatRatioLon = lowerLatLowerLonMagVar + ratioLon * (lowerLatUpperLonMagVar - lowerLatLowerLonMagVar);
|
||||||
const upperLatRatioLon = upperLatLowerLonMagVar + ratioLon * (upperLatUpperLonMagVar - upperLatLowerLonMagVar);
|
const upperLatRatioLon = upperLatLowerLonMagVar + ratioLon * (upperLatUpperLonMagVar - upperLatLowerLonMagVar);
|
||||||
@ -60,7 +60,7 @@ Number.prototype.toMetre = function () {
|
|||||||
return (this as number) * 1852.0;
|
return (this as number) * 1852.0;
|
||||||
};
|
};
|
||||||
Number.prototype.equal = function (other: number) {
|
Number.prototype.equal = function (other: number) {
|
||||||
return Math.abs((this as number) - other) < 0.1;
|
return Math.abs((this as number) - other) <= 0.1;
|
||||||
};
|
};
|
||||||
|
|
||||||
String.prototype.parseAltitude = function () {
|
String.prototype.parseAltitude = function () {
|
||||||
|
|||||||
1
md11-nav-data/src/types/navdata.d.ts
vendored
1
md11-nav-data/src/types/navdata.d.ts
vendored
@ -91,6 +91,7 @@ export declare global {
|
|||||||
IsMAP?: boolean;
|
IsMAP?: boolean;
|
||||||
// For map
|
// For map
|
||||||
isIntersection?: boolean;
|
isIntersection?: boolean;
|
||||||
|
isInitial?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type LineSegment = [number, number];
|
type LineSegment = [number, number];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user