@squawk/flightplan 0.6.3 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -8
- package/dist/resolver.d.ts +17 -3
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +4 -3
- package/dist/route-distance.d.ts +13 -3
- package/dist/route-distance.d.ts.map +1 -1
- package/dist/route-distance.js +7 -3
- package/dist/route-geometry.d.ts +10 -5
- package/dist/route-geometry.d.ts.map +1 -1
- package/dist/route-geometry.js +28 -10
- package/dist/route-timing.d.ts +3 -1
- package/dist/route-timing.d.ts.map +1 -1
- package/dist/route-timing.js +2 -1
- package/package.json +13 -13
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ const resolver = createFlightplanResolver({
|
|
|
33
33
|
procedures: createProcedureResolver({ data: usBundledProcedures.records }),
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
const route = resolver.parse('
|
|
36
|
+
const route = resolver.parse('KLAX DCT LAX J60 SAX DCT KJFK');
|
|
37
37
|
for (const element of route.elements) {
|
|
38
38
|
console.log(element.type, element.raw);
|
|
39
39
|
}
|
|
@@ -122,13 +122,19 @@ Each element has a `type` discriminant and a `raw` field with the original token
|
|
|
122
122
|
| `airport` | Resolved airport (ICAO or FAA ID) | `airport` |
|
|
123
123
|
| `sid` | Standard Instrument Departure | `procedure`, `legs` |
|
|
124
124
|
| `star` | Standard Terminal Arrival Route | `procedure`, `legs` |
|
|
125
|
-
| `airway` | Airway segment between entry and exit fix | `airway`, `entryFix`, `exitFix`, `waypoints`
|
|
125
|
+
| `airway` | Airway segment between entry and exit fix | `airway`, `entryFix`, `exitFix`, `waypoints`, `gaps` |
|
|
126
126
|
| `direct` | DCT (direct) indicator | - |
|
|
127
127
|
| `waypoint` | Resolved fix or navaid | `fix` and/or `navaid`, `lat`, `lon` |
|
|
128
128
|
| `coordinate` | Lat/lon specified in the route string | `lat`, `lon` |
|
|
129
129
|
| `speedAltitude` | Speed/altitude group (e.g. N0450F350) | `speedKt`/`speedKmPerHr`/`mach`, `flightLevel`/`altitudeFt` |
|
|
130
130
|
| `unresolved` | Token that could not be resolved | - |
|
|
131
131
|
|
|
132
|
+
An airway element's `gaps` lists any published discontinuity its expansion
|
|
133
|
+
crosses (the FAA discontinues some airways partway, such as J60 between JOT and
|
|
134
|
+
DJB). The waypoints on both sides are still returned so the route can be drawn
|
|
135
|
+
and measured, but a non-empty `gaps` means the route files the airway where it
|
|
136
|
+
is not defined and is not valid as filed.
|
|
137
|
+
|
|
132
138
|
### Coordinate formats
|
|
133
139
|
|
|
134
140
|
- `DDMMN/DDDMMEW` (e.g. `4030N07045W` for 40 deg 30 min N, 70 deg 45 min W)
|
|
@@ -173,13 +179,13 @@ to the first `byIdent` match.
|
|
|
173
179
|
Computes the total great-circle route distance and optional estimated time
|
|
174
180
|
enroute from a parsed route. Walks the same ordered point sequence as the
|
|
175
181
|
geometry helpers below, so distance and geometry stay in agreement. Airway
|
|
176
|
-
segments use FAA-published per-segment
|
|
177
|
-
to great-circle computation.
|
|
182
|
+
segments use the FAA-published per-segment distance where the data carries a
|
|
183
|
+
positive one, falling back to great-circle computation otherwise.
|
|
178
184
|
|
|
179
185
|
```typescript
|
|
180
186
|
import { computeRouteDistance } from '@squawk/flightplan';
|
|
181
187
|
|
|
182
|
-
const route = resolver.parse('
|
|
188
|
+
const route = resolver.parse('KLAX DCT LAX J60 SAX DCT KJFK');
|
|
183
189
|
const result = computeRouteDistance(route, 450);
|
|
184
190
|
console.log(result.totalDistanceNm, result.estimatedTimeEnrouteHrs);
|
|
185
191
|
```
|
|
@@ -191,7 +197,7 @@ console.log(result.totalDistanceNm, result.estimatedTimeEnrouteHrs);
|
|
|
191
197
|
|
|
192
198
|
**Returns:** `RouteDistanceResult` with:
|
|
193
199
|
|
|
194
|
-
- `legs` - ordered `RouteLeg` values, each with `from`/`to` point labels, their `fromLat`/`fromLon`/`toLat`/`toLon` coordinates in decimal degrees, `distanceNm`, and `
|
|
200
|
+
- `legs` - ordered `RouteLeg` values, each with `from`/`to` point labels, their `fromLat`/`fromLon`/`toLat`/`toLon` coordinates in decimal degrees, `distanceNm`, `cumulativeDistanceNm`, and `crossesGap`, which is true when the leg spans a published gap in the airway it came from (the leg is a straight line that counts toward the total but is not a flyable airway segment)
|
|
195
201
|
- `totalDistanceNm` - total great-circle distance in nautical miles
|
|
196
202
|
- `estimatedTimeEnrouteHrs` - ETE in hours, or `undefined` when no ground speed was given
|
|
197
203
|
- `unresolvedElements` - route elements that could not contribute coordinates
|
|
@@ -216,7 +222,7 @@ wind correction angle is zero.
|
|
|
216
222
|
```typescript
|
|
217
223
|
import { computeRouteTiming } from '@squawk/flightplan';
|
|
218
224
|
|
|
219
|
-
const route = resolver.parse('
|
|
225
|
+
const route = resolver.parse('KLAX DCT LAX J60 SAX DCT KJFK');
|
|
220
226
|
const result = computeRouteTiming(route, {
|
|
221
227
|
trueAirspeedKt: 450,
|
|
222
228
|
windProvider: (lat, lon) => ({ directionDeg: 270, speedKt: 80 }),
|
|
@@ -269,7 +275,7 @@ two drawable points, since a `LineString` requires at least two positions.
|
|
|
269
275
|
```typescript
|
|
270
276
|
import { routeToLineString } from '@squawk/flightplan';
|
|
271
277
|
|
|
272
|
-
const route = resolver.parse('
|
|
278
|
+
const route = resolver.parse('KLAX DCT LAX J60 SAX DCT KJFK');
|
|
273
279
|
const line = routeToLineString(route);
|
|
274
280
|
if (line) {
|
|
275
281
|
map.addSource('route', { type: 'geojson', data: line });
|
package/dist/resolver.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Airport, Airway, AirwayWaypoint, Fix, Navaid, Procedure, ProcedureLeg } from '@squawk/types';
|
|
1
|
+
import type { Airport, Airway, AirwayGap, AirwayWaypoint, Fix, Navaid, Procedure, ProcedureLeg } from '@squawk/types';
|
|
2
2
|
/**
|
|
3
3
|
* Minimal airport lookup interface consumed by the flightplan resolver.
|
|
4
4
|
* Structurally compatible with the `AirportResolver` shape in `@squawk/airports`.
|
|
@@ -46,10 +46,16 @@ export interface FlightplanFixLookup {
|
|
|
46
46
|
export interface FlightplanAirwayLookup {
|
|
47
47
|
/** Looks up airways by designation (e.g. "V16", "J60"). Returns an empty array if none found. */
|
|
48
48
|
byDesignation(designation: string): Airway[];
|
|
49
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Expands an airway between entry and exit fixes, returning ordered
|
|
51
|
+
* waypoints. `gaps` lists any published discontinuity the expansion crosses;
|
|
52
|
+
* a lookup that cannot report gaps may omit it, and the route then reports
|
|
53
|
+
* none.
|
|
54
|
+
*/
|
|
50
55
|
expand(designation: string, entryFix: string, exitFix: string): {
|
|
51
56
|
airway: Airway;
|
|
52
57
|
waypoints: AirwayWaypoint[];
|
|
58
|
+
gaps?: AirwayGap[];
|
|
53
59
|
} | undefined;
|
|
54
60
|
}
|
|
55
61
|
/**
|
|
@@ -118,6 +124,14 @@ export interface AirwayRouteElement {
|
|
|
118
124
|
exitFix: string;
|
|
119
125
|
/** Ordered waypoints from entry to exit fix (inclusive). */
|
|
120
126
|
waypoints: AirwayWaypoint[];
|
|
127
|
+
/**
|
|
128
|
+
* Published discontinuities the expansion crosses, in traversal order. Empty
|
|
129
|
+
* when the airway is continuous between the entry and exit fixes. A
|
|
130
|
+
* non-empty list means the route files the airway where it is not defined,
|
|
131
|
+
* so the route is not valid as filed; the waypoints are still returned so
|
|
132
|
+
* the route can be drawn and measured.
|
|
133
|
+
*/
|
|
134
|
+
gaps: AirwayGap[];
|
|
121
135
|
}
|
|
122
136
|
/**
|
|
123
137
|
* A DCT (direct) indicator between two waypoints.
|
|
@@ -263,7 +277,7 @@ export interface FlightplanResolver {
|
|
|
263
277
|
* procedures: createProcedureResolver({ data: usBundledProcedures.records }),
|
|
264
278
|
* });
|
|
265
279
|
*
|
|
266
|
-
* const route = resolver.parse('
|
|
280
|
+
* const route = resolver.parse('KLAX DCT LAX J60 SAX DCT KJFK');
|
|
267
281
|
* for (const element of route.elements) {
|
|
268
282
|
* console.log(element.type, element.raw);
|
|
269
283
|
* }
|
package/dist/resolver.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,MAAM,EACN,cAAc,EACd,GAAG,EACH,MAAM,EACN,SAAS,EACT,YAAY,EACb,MAAM,eAAe,CAAC;AAMvB;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,mEAAmE;IACnE,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC5C,sDAAsD;IACtD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CAC3C;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjC;;;;;OAKG;IACH,iBAAiB,CAAC,CAChB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,GAAG,SAAS,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,0EAA0E;IAC1E,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,CAAC;IAC9B;;;;;OAKG;IACH,iBAAiB,CAAC,CAChB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,WAAW,CAAC,EAAE,MAAM,GACnB,GAAG,GAAG,SAAS,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,iGAAiG;IACjG,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7C
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
|
package/dist/resolver.js
CHANGED
|
@@ -104,8 +104,8 @@ function tryAirport(token, airports) {
|
|
|
104
104
|
* the arrival airport - but since the route is parsed left-to-right,
|
|
105
105
|
* the most recent airport is the best available hint).
|
|
106
106
|
*
|
|
107
|
-
* Accepts both the bare CIFP identifier (e.g. `
|
|
108
|
-
* identifier-with-transition form (e.g. `
|
|
107
|
+
* Accepts both the bare CIFP identifier (e.g. `DEEZZ6`) and the dotted
|
|
108
|
+
* identifier-with-transition form (e.g. `DEEZZ6.CANDR`). When a
|
|
109
109
|
* transition is supplied it is forwarded to the procedure resolver so
|
|
110
110
|
* that the transition's legs are merged into the expansion.
|
|
111
111
|
*/
|
|
@@ -211,7 +211,7 @@ function tryNavaid(token, navaids, anchor) {
|
|
|
211
211
|
* procedures: createProcedureResolver({ data: usBundledProcedures.records }),
|
|
212
212
|
* });
|
|
213
213
|
*
|
|
214
|
-
* const route = resolver.parse('
|
|
214
|
+
* const route = resolver.parse('KLAX DCT LAX J60 SAX DCT KJFK');
|
|
215
215
|
* for (const element of route.elements) {
|
|
216
216
|
* console.log(element.type, element.raw);
|
|
217
217
|
* }
|
|
@@ -269,6 +269,7 @@ export function createFlightplanResolver(options) {
|
|
|
269
269
|
entryFix: lastWaypointIdent,
|
|
270
270
|
exitFix,
|
|
271
271
|
waypoints: expansion.waypoints,
|
|
272
|
+
gaps: expansion.gaps ?? [],
|
|
272
273
|
});
|
|
273
274
|
// The exit fix is consumed as part of the airway; update last waypoint
|
|
274
275
|
lastWaypointIdent = exitFix;
|
package/dist/route-distance.d.ts
CHANGED
|
@@ -24,6 +24,13 @@ export interface RouteLeg {
|
|
|
24
24
|
distanceNm: number;
|
|
25
25
|
/** Cumulative distance from the route start through the end of this leg in nautical miles. */
|
|
26
26
|
cumulativeDistanceNm: number;
|
|
27
|
+
/**
|
|
28
|
+
* Whether this leg spans a published gap in the airway it was expanded
|
|
29
|
+
* from. The airway is not defined between the two points, so the leg is a
|
|
30
|
+
* straight line that counts toward the total but is not a flyable airway
|
|
31
|
+
* segment, and the route is not valid as filed.
|
|
32
|
+
*/
|
|
33
|
+
crossesGap: boolean;
|
|
27
34
|
}
|
|
28
35
|
/**
|
|
29
36
|
* Result of computing route distance and estimated time enroute from a
|
|
@@ -55,14 +62,17 @@ export interface RouteDistanceResult {
|
|
|
55
62
|
* indicate which parts of the route could not contribute to the distance
|
|
56
63
|
* calculation.
|
|
57
64
|
*
|
|
58
|
-
* Airway segments use the FAA-published `distanceToNextNm`
|
|
59
|
-
*
|
|
65
|
+
* Airway segments use the FAA-published `distanceToNextNm` value where the
|
|
66
|
+
* source publishes a positive one, falling back to great-circle computation
|
|
67
|
+
* otherwise. A leg that spans a published gap in its airway is still measured
|
|
68
|
+
* as a straight line and counted, but is flagged with `crossesGap` so the
|
|
69
|
+
* caller can see that the route is not valid as filed.
|
|
60
70
|
*
|
|
61
71
|
* ```typescript
|
|
62
72
|
* import { createFlightplanResolver, computeRouteDistance } from '@squawk/flightplan';
|
|
63
73
|
*
|
|
64
74
|
* const resolver = createFlightplanResolver({ airports, navaids, fixes, airways });
|
|
65
|
-
* const route = resolver.parse('
|
|
75
|
+
* const route = resolver.parse('KLAX DCT LAX J60 SAX DCT KJFK');
|
|
66
76
|
* const result = computeRouteDistance(route, 450);
|
|
67
77
|
* console.log(result.totalDistanceNm, result.estimatedTimeEnrouteHrs);
|
|
68
78
|
* ```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-distance.d.ts","sourceRoot":"","sources":["../src/route-distance.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAO/D;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,oBAAoB,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"route-distance.d.ts","sourceRoot":"","sources":["../src/route-distance.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAO/D;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,0DAA0D;IAC1D,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,2DAA2D;IAC3D,eAAe,EAAE,MAAM,CAAC;IACxB,uFAAuF;IACvF,uBAAuB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C;;;;OAIG;IACH,kBAAkB,EAAE,YAAY,EAAE,CAAC;CACpC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,WAAW,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,mBAAmB,CAuCrB"}
|
package/dist/route-distance.js
CHANGED
|
@@ -20,14 +20,17 @@ import { extractGeoPoints } from './route-geometry.js';
|
|
|
20
20
|
* indicate which parts of the route could not contribute to the distance
|
|
21
21
|
* calculation.
|
|
22
22
|
*
|
|
23
|
-
* Airway segments use the FAA-published `distanceToNextNm`
|
|
24
|
-
*
|
|
23
|
+
* Airway segments use the FAA-published `distanceToNextNm` value where the
|
|
24
|
+
* source publishes a positive one, falling back to great-circle computation
|
|
25
|
+
* otherwise. A leg that spans a published gap in its airway is still measured
|
|
26
|
+
* as a straight line and counted, but is flagged with `crossesGap` so the
|
|
27
|
+
* caller can see that the route is not valid as filed.
|
|
25
28
|
*
|
|
26
29
|
* ```typescript
|
|
27
30
|
* import { createFlightplanResolver, computeRouteDistance } from '@squawk/flightplan';
|
|
28
31
|
*
|
|
29
32
|
* const resolver = createFlightplanResolver({ airports, navaids, fixes, airways });
|
|
30
|
-
* const route = resolver.parse('
|
|
33
|
+
* const route = resolver.parse('KLAX DCT LAX J60 SAX DCT KJFK');
|
|
31
34
|
* const result = computeRouteDistance(route, 450);
|
|
32
35
|
* console.log(result.totalDistanceNm, result.estimatedTimeEnrouteHrs);
|
|
33
36
|
* ```
|
|
@@ -57,6 +60,7 @@ export function computeRouteDistance(route, groundSpeedKt) {
|
|
|
57
60
|
toLon: to.lon,
|
|
58
61
|
distanceNm: legDistanceNm,
|
|
59
62
|
cumulativeDistanceNm: totalDistanceNm,
|
|
63
|
+
crossesGap: from.gapToNext === true,
|
|
60
64
|
});
|
|
61
65
|
}
|
|
62
66
|
const estimatedTimeEnrouteHrs = groundSpeedKt !== undefined && groundSpeedKt > 0 ? totalDistanceNm / groundSpeedKt : undefined;
|
package/dist/route-geometry.d.ts
CHANGED
|
@@ -37,14 +37,19 @@ export interface GeoPoint {
|
|
|
37
37
|
lon: number;
|
|
38
38
|
/**
|
|
39
39
|
* Pre-computed distance to the next point along an airway segment in
|
|
40
|
-
* nautical miles,
|
|
40
|
+
* nautical miles, when the source data publishes a positive value.
|
|
41
41
|
*/
|
|
42
42
|
precomputedDistanceToNextNm?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Set when the leg from this point to the next crosses a published gap in
|
|
45
|
+
* the airway it was expanded from.
|
|
46
|
+
*/
|
|
47
|
+
gapToNext?: true;
|
|
43
48
|
}
|
|
44
49
|
/**
|
|
45
50
|
* Walks the route elements and extracts an ordered array of geographic
|
|
46
|
-
* points. Duplicate consecutive points (e.g. an airway entry fix
|
|
47
|
-
*
|
|
51
|
+
* points. Duplicate consecutive points (e.g. an airway entry fix at the same
|
|
52
|
+
* position as the preceding waypoint, within about a metre) are suppressed.
|
|
48
53
|
*
|
|
49
54
|
* Also collects all `unresolved` elements encountered during the walk.
|
|
50
55
|
*
|
|
@@ -74,7 +79,7 @@ export declare function extractGeoPoints(elements: RouteElement[]): {
|
|
|
74
79
|
* import { createFlightplanResolver, extractRoutePoints } from '@squawk/flightplan';
|
|
75
80
|
*
|
|
76
81
|
* const resolver = createFlightplanResolver({ airports, navaids, fixes, airways });
|
|
77
|
-
* const route = resolver.parse('
|
|
82
|
+
* const route = resolver.parse('KLAX DCT LAX J60 SAX DCT KJFK');
|
|
78
83
|
* const points = extractRoutePoints(route);
|
|
79
84
|
* ```
|
|
80
85
|
*
|
|
@@ -94,7 +99,7 @@ export declare function extractRoutePoints(route: ParsedRoute): RoutePoint[];
|
|
|
94
99
|
* import { createFlightplanResolver, routeToLineString } from '@squawk/flightplan';
|
|
95
100
|
*
|
|
96
101
|
* const resolver = createFlightplanResolver({ airports, navaids, fixes, airways });
|
|
97
|
-
* const route = resolver.parse('
|
|
102
|
+
* const route = resolver.parse('KLAX DCT LAX J60 SAX DCT KJFK');
|
|
98
103
|
* const line = routeToLineString(route);
|
|
99
104
|
* if (line) {
|
|
100
105
|
* map.addSource('route', { type: 'geojson', data: line });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-geometry.d.ts","sourceRoot":"","sources":["../src/route-geometry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAM/D;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;CACb;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"route-geometry.d.ts","sourceRoot":"","sources":["../src/route-geometry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAM/D;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;CACb;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC;;;OAGG;IACH,SAAS,CAAC,EAAE,IAAI,CAAC;CAClB;AAuBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG;IAC1D,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,kBAAkB,EAAE,YAAY,EAAE,CAAC;CACpC,CAwFA;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,GAAG,UAAU,EAAE,CAGnE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,UAAU,GAAG,SAAS,CAS5E"}
|
package/dist/route-geometry.js
CHANGED
|
@@ -11,8 +11,15 @@
|
|
|
11
11
|
// ---------------------------------------------------------------------------
|
|
12
12
|
// Internal helpers
|
|
13
13
|
// ---------------------------------------------------------------------------
|
|
14
|
-
/**
|
|
15
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Epsilon in decimal degrees for treating two consecutive points as the same
|
|
16
|
+
* position. The data packages round coordinates to different precisions
|
|
17
|
+
* (airway waypoints to six decimals, fixes and navaids to eight), so the same
|
|
18
|
+
* fix reached through two of them can differ by up to 5e-7 degrees. 1e-5
|
|
19
|
+
* degrees is about a metre: far above that rounding noise and far below the
|
|
20
|
+
* spacing of any two distinct route points.
|
|
21
|
+
*/
|
|
22
|
+
const COORD_EPSILON = 1e-5;
|
|
16
23
|
/**
|
|
17
24
|
* Returns true if two points share the same coordinates (within epsilon).
|
|
18
25
|
*/
|
|
@@ -21,8 +28,8 @@ function samePosition(a, b) {
|
|
|
21
28
|
}
|
|
22
29
|
/**
|
|
23
30
|
* Walks the route elements and extracts an ordered array of geographic
|
|
24
|
-
* points. Duplicate consecutive points (e.g. an airway entry fix
|
|
25
|
-
*
|
|
31
|
+
* points. Duplicate consecutive points (e.g. an airway entry fix at the same
|
|
32
|
+
* position as the preceding waypoint, within about a metre) are suppressed.
|
|
26
33
|
*
|
|
27
34
|
* Also collects all `unresolved` elements encountered during the walk.
|
|
28
35
|
*
|
|
@@ -46,6 +53,11 @@ export function extractGeoPoints(elements) {
|
|
|
46
53
|
last.precomputedDistanceToNextNm === undefined) {
|
|
47
54
|
last.precomputedDistanceToNextNm = point.precomputedDistanceToNextNm;
|
|
48
55
|
}
|
|
56
|
+
// Likewise carry a gap marker, so the leg out of the merged point is
|
|
57
|
+
// still reported as crossing the gap.
|
|
58
|
+
if (point.gapToNext) {
|
|
59
|
+
last.gapToNext = true;
|
|
60
|
+
}
|
|
49
61
|
return;
|
|
50
62
|
}
|
|
51
63
|
points.push(point);
|
|
@@ -61,7 +73,8 @@ export function extractGeoPoints(elements) {
|
|
|
61
73
|
case 'coordinate':
|
|
62
74
|
emit({ label: el.raw, lat: el.lat, lon: el.lon });
|
|
63
75
|
break;
|
|
64
|
-
case 'airway':
|
|
76
|
+
case 'airway': {
|
|
77
|
+
const gapIndexes = new Set(el.gaps.map((gap) => gap.index));
|
|
65
78
|
for (let i = 0; i < el.waypoints.length; i++) {
|
|
66
79
|
const wp = el.waypoints[i];
|
|
67
80
|
const isLast = i === el.waypoints.length - 1;
|
|
@@ -70,14 +83,19 @@ export function extractGeoPoints(elements) {
|
|
|
70
83
|
lat: wp.lat,
|
|
71
84
|
lon: wp.lon,
|
|
72
85
|
};
|
|
73
|
-
// Only carry
|
|
74
|
-
//
|
|
75
|
-
|
|
86
|
+
// Only carry a published distance for non-last waypoints (the last
|
|
87
|
+
// waypoint's distanceToNextNm points beyond this segment), and only
|
|
88
|
+
// a positive one: a zero means the source published no distance.
|
|
89
|
+
if (!isLast && wp.distanceToNextNm !== undefined && wp.distanceToNextNm > 0) {
|
|
76
90
|
point.precomputedDistanceToNextNm = wp.distanceToNextNm;
|
|
77
91
|
}
|
|
92
|
+
if (!isLast && gapIndexes.has(i)) {
|
|
93
|
+
point.gapToNext = true;
|
|
94
|
+
}
|
|
78
95
|
emit(point);
|
|
79
96
|
}
|
|
80
97
|
break;
|
|
98
|
+
}
|
|
81
99
|
case 'sid':
|
|
82
100
|
case 'star':
|
|
83
101
|
for (const leg of el.legs) {
|
|
@@ -118,7 +136,7 @@ export function extractGeoPoints(elements) {
|
|
|
118
136
|
* import { createFlightplanResolver, extractRoutePoints } from '@squawk/flightplan';
|
|
119
137
|
*
|
|
120
138
|
* const resolver = createFlightplanResolver({ airports, navaids, fixes, airways });
|
|
121
|
-
* const route = resolver.parse('
|
|
139
|
+
* const route = resolver.parse('KLAX DCT LAX J60 SAX DCT KJFK');
|
|
122
140
|
* const points = extractRoutePoints(route);
|
|
123
141
|
* ```
|
|
124
142
|
*
|
|
@@ -141,7 +159,7 @@ export function extractRoutePoints(route) {
|
|
|
141
159
|
* import { createFlightplanResolver, routeToLineString } from '@squawk/flightplan';
|
|
142
160
|
*
|
|
143
161
|
* const resolver = createFlightplanResolver({ airports, navaids, fixes, airways });
|
|
144
|
-
* const route = resolver.parse('
|
|
162
|
+
* const route = resolver.parse('KLAX DCT LAX J60 SAX DCT KJFK');
|
|
145
163
|
* const line = routeToLineString(route);
|
|
146
164
|
* if (line) {
|
|
147
165
|
* map.addSource('route', { type: 'geojson', data: line });
|
package/dist/route-timing.d.ts
CHANGED
|
@@ -68,6 +68,8 @@ export interface RouteTimingLeg {
|
|
|
68
68
|
distanceNm: number;
|
|
69
69
|
/** Cumulative distance from the route start through the end of this leg in nautical miles. */
|
|
70
70
|
cumulativeDistanceNm: number;
|
|
71
|
+
/** Whether this leg spans a published gap in the airway it was expanded from, as on `RouteLeg`. */
|
|
72
|
+
crossesGap: boolean;
|
|
71
73
|
/** Initial great-circle true course for the leg in degrees (0-360). */
|
|
72
74
|
trueCourseDeg: number;
|
|
73
75
|
/** True heading to fly to hold the course given the wind, in degrees (0-360). */
|
|
@@ -152,7 +154,7 @@ export interface RouteTimingResult {
|
|
|
152
154
|
* import { createFlightplanResolver, computeRouteTiming } from '@squawk/flightplan';
|
|
153
155
|
*
|
|
154
156
|
* const resolver = createFlightplanResolver({ airports, navaids, fixes, airways });
|
|
155
|
-
* const route = resolver.parse('
|
|
157
|
+
* const route = resolver.parse('KLAX DCT LAX J60 SAX DCT KJFK');
|
|
156
158
|
* const result = computeRouteTiming(route, {
|
|
157
159
|
* trueAirspeedKt: 450,
|
|
158
160
|
* windProvider: (lat, lon) => ({ directionDeg: 270, speedKt: 80 }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-timing.d.ts","sourceRoot":"","sources":["../src/route-timing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAO/D;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,cAAc,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,oBAAoB,EAAE,MAAM,CAAC;IAC7B,uEAAuE;IACvE,aAAa,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,cAAc,EAAE,MAAM,CAAC;IACvB,6FAA6F;IAC7F,sBAAsB,EAAE,MAAM,CAAC;IAC/B,mDAAmD;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7B,mGAAmG;IACnG,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B;;;OAGG;IACH,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC;;;OAGG;IACH,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,2DAA2D;IAC3D,eAAe,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC;;;OAGG;IACH,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC;;;OAGG;IACH,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC;;;OAGG;IACH,cAAc,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC;;;OAGG;IACH,kBAAkB,EAAE,YAAY,EAAE,CAAC;CACpC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,kBAAkB,GAC1B,iBAAiB,
|
|
1
|
+
{"version":3,"file":"route-timing.d.ts","sourceRoot":"","sources":["../src/route-timing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAO/D;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,cAAc,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mGAAmG;IACnG,UAAU,EAAE,OAAO,CAAC;IACpB,uEAAuE;IACvE,aAAa,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,cAAc,EAAE,MAAM,CAAC;IACvB,6FAA6F;IAC7F,sBAAsB,EAAE,MAAM,CAAC;IAC/B,mDAAmD;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7B,mGAAmG;IACnG,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B;;;OAGG;IACH,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC;;;OAGG;IACH,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,2DAA2D;IAC3D,eAAe,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC;;;OAGG;IACH,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC;;;OAGG;IACH,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC;;;OAGG;IACH,cAAc,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC;;;OAGG;IACH,kBAAkB,EAAE,YAAY,EAAE,CAAC;CACpC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,kBAAkB,GAC1B,iBAAiB,CAyFnB"}
|
package/dist/route-timing.js
CHANGED
|
@@ -43,7 +43,7 @@ import { computeRouteDistance } from './route-distance.js';
|
|
|
43
43
|
* import { createFlightplanResolver, computeRouteTiming } from '@squawk/flightplan';
|
|
44
44
|
*
|
|
45
45
|
* const resolver = createFlightplanResolver({ airports, navaids, fixes, airways });
|
|
46
|
-
* const route = resolver.parse('
|
|
46
|
+
* const route = resolver.parse('KLAX DCT LAX J60 SAX DCT KJFK');
|
|
47
47
|
* const result = computeRouteTiming(route, {
|
|
48
48
|
* trueAirspeedKt: 450,
|
|
49
49
|
* windProvider: (lat, lon) => ({ directionDeg: 270, speedKt: 80 }),
|
|
@@ -100,6 +100,7 @@ export function computeRouteTiming(route, options) {
|
|
|
100
100
|
toLon: leg.toLon,
|
|
101
101
|
distanceNm: leg.distanceNm,
|
|
102
102
|
cumulativeDistanceNm: leg.cumulativeDistanceNm,
|
|
103
|
+
crossesGap: leg.crossesGap,
|
|
103
104
|
trueCourseDeg,
|
|
104
105
|
trueHeadingDeg: triangle.trueHeadingDeg,
|
|
105
106
|
windCorrectionAngleDeg: triangle.windCorrectionAngleDeg,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squawk/flightplan",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Flight plan route string parsing and resolution using composed navigation resolvers",
|
|
6
6
|
"author": "Neil Cochran",
|
|
@@ -43,21 +43,21 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@squawk/flight-math": "^0.5.9",
|
|
46
|
-
"@squawk/geo": "^0.5.
|
|
47
|
-
"@squawk/types": "^0.
|
|
46
|
+
"@squawk/geo": "^0.5.1",
|
|
47
|
+
"@squawk/types": "^0.11.0",
|
|
48
48
|
"@types/geojson": "^7946.0.16"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@squawk/airport-data": "^0.8.
|
|
52
|
-
"@squawk/airports": "^0.7.
|
|
53
|
-
"@squawk/airway-data": "^0.6.
|
|
54
|
-
"@squawk/airways": "^0.
|
|
55
|
-
"@squawk/fix-data": "^0.7.
|
|
56
|
-
"@squawk/fixes": "^0.5.
|
|
57
|
-
"@squawk/navaid-data": "^0.7.
|
|
58
|
-
"@squawk/navaids": "^0.6.
|
|
59
|
-
"@squawk/procedure-data": "^0.8.
|
|
60
|
-
"@squawk/procedures": "^0.7.
|
|
51
|
+
"@squawk/airport-data": "^0.8.3",
|
|
52
|
+
"@squawk/airports": "^0.7.4",
|
|
53
|
+
"@squawk/airway-data": "^0.6.4",
|
|
54
|
+
"@squawk/airways": "^0.6.0",
|
|
55
|
+
"@squawk/fix-data": "^0.7.3",
|
|
56
|
+
"@squawk/fixes": "^0.5.4",
|
|
57
|
+
"@squawk/navaid-data": "^0.7.3",
|
|
58
|
+
"@squawk/navaids": "^0.6.4",
|
|
59
|
+
"@squawk/procedure-data": "^0.8.3",
|
|
60
|
+
"@squawk/procedures": "^0.7.3",
|
|
61
61
|
"@types/node": "^26.6.4"
|
|
62
62
|
},
|
|
63
63
|
"keywords": [
|