@squawk/airspace 0.5.0 → 0.6.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 +63 -7
- package/dist/resolver.d.ts +24 -2
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +15 -2
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -12,6 +12,13 @@ Part of the [@squawk](https://www.npmjs.com/org/squawk) aviation library suite.
|
|
|
12
12
|
|
|
13
13
|
- Class B, C, D, and E controlled airspace (E2 through E7 subtypes)
|
|
14
14
|
- Special Use Airspace: MOAs, restricted, prohibited, warning, alert, and national security areas
|
|
15
|
+
- ARTCC (Air Route Traffic Control Center) lateral boundaries for every
|
|
16
|
+
US-controlled center, published per stratum: LOW/HIGH for the 20 CONUS
|
|
17
|
+
centers and Anchorage (ZAN), UTA for Oakland (ZOA) only, and oceanic
|
|
18
|
+
CTA/FIR strata for the Pacific (ZAK, ZAP), Atlantic (ZWY), and the
|
|
19
|
+
contiguous overlays on ZAN, ZHN, ZHU, ZMA, ZSU. Within-stratum sector
|
|
20
|
+
polygons and per-sector enroute frequencies are not included - the FAA
|
|
21
|
+
does not publish either data set in machine-readable form.
|
|
15
22
|
|
|
16
23
|
## Usage
|
|
17
24
|
|
|
@@ -30,6 +37,9 @@ for (const f of overhead) {
|
|
|
30
37
|
|
|
31
38
|
// Get every shell associated with an airport (for drawing the full wedding cake)
|
|
32
39
|
const laxShells = resolver.byAirport('LAX');
|
|
40
|
+
|
|
41
|
+
// Get every ARTCC center boundary (one feature per stratum)
|
|
42
|
+
const ny = resolver.byArtcc('ZNY');
|
|
33
43
|
```
|
|
34
44
|
|
|
35
45
|
Consumers who have their own GeoJSON airspace data can use this package standalone:
|
|
@@ -43,14 +53,18 @@ const resolver = createAirspaceResolver({ data: myGeoJson });
|
|
|
43
53
|
## How it works
|
|
44
54
|
|
|
45
55
|
`createAirspaceResolver` parses the GeoJSON FeatureCollection at initialization and
|
|
46
|
-
returns a resolver object with
|
|
56
|
+
returns a resolver object with three methods:
|
|
47
57
|
|
|
48
58
|
- `query(AirspaceQuery)` - returns features containing the given position and
|
|
49
59
|
altitude, via a ray casting point-in-polygon test combined with a vertical
|
|
50
60
|
floor/ceiling comparison.
|
|
51
|
-
- `byAirport(identifier, types?)` - returns every feature whose
|
|
52
|
-
matches (case-insensitive). For Class B/C/D/E2 this groups all
|
|
53
|
-
airspace around a given airport regardless of the point of
|
|
61
|
+
- `byAirport(identifier, types?)` - returns every non-ARTCC feature whose
|
|
62
|
+
`identifier` matches (case-insensitive). For Class B/C/D/E2 this groups all
|
|
63
|
+
sectors of the airspace around a given airport regardless of the point of
|
|
64
|
+
interest.
|
|
65
|
+
- `byArtcc(identifier, stratum?)` - returns every ARTCC feature for the given
|
|
66
|
+
3-letter center code (e.g. `"ZNY"`), optionally filtered to a single
|
|
67
|
+
stratum (`LOW`, `HIGH`, `UTA`, `CTA`, `FIR`, or `CTA/FIR`).
|
|
54
68
|
|
|
55
69
|
All matching features are returned as `AirspaceFeature` objects (from `@squawk/types`),
|
|
56
70
|
including the full polygon boundary coordinates.
|
|
@@ -87,8 +101,8 @@ Creates a resolver from a GeoJSON dataset.
|
|
|
87
101
|
|
|
88
102
|
- `options.data` - a GeoJSON `FeatureCollection` with airspace features
|
|
89
103
|
|
|
90
|
-
**Returns:** `AirspaceResolver` - an object exposing `query(AirspaceQuery)
|
|
91
|
-
`byAirport(identifier, types?)` methods.
|
|
104
|
+
**Returns:** `AirspaceResolver` - an object exposing `query(AirspaceQuery)`,
|
|
105
|
+
`byAirport(identifier, types?)`, and `byArtcc(identifier, stratum?)` methods.
|
|
92
106
|
|
|
93
107
|
### `AirspaceQuery`
|
|
94
108
|
|
|
@@ -111,7 +125,7 @@ const controlled = resolver.query({
|
|
|
111
125
|
|
|
112
126
|
### `resolver.byAirport(identifier, types?)`
|
|
113
127
|
|
|
114
|
-
Returns every airspace feature whose `identifier` property matches. For
|
|
128
|
+
Returns every non-ARTCC airspace feature whose `identifier` property matches. For
|
|
115
129
|
Class B/C/D/E2 this is the associated airport's FAA location identifier
|
|
116
130
|
(e.g. "JFK" for the NY Class B). For Special Use Airspace this is the NASR
|
|
117
131
|
designator (e.g. "R-2508"). Lookup is case-insensitive. ICAO-prefixed codes
|
|
@@ -124,3 +138,45 @@ const jfkShells = resolver.byAirport('JFK');
|
|
|
124
138
|
// Only the Class D for a towered field
|
|
125
139
|
const safClassD = resolver.byAirport('SAF', new Set(['CLASS_D']));
|
|
126
140
|
```
|
|
141
|
+
|
|
142
|
+
### `resolver.byArtcc(identifier, stratum?)`
|
|
143
|
+
|
|
144
|
+
Returns every ARTCC feature for the given three-letter center code
|
|
145
|
+
(e.g. `"ZNY"`, `"ZBW"`). Each US ARTCC is published as multiple features -
|
|
146
|
+
one per stratum (`LOW`, `HIGH`, plus oceanic `UTA`, `CTA`, `FIR`, or
|
|
147
|
+
`CTA/FIR` where applicable) - because the lateral extent can vary between
|
|
148
|
+
strata. Pass an optional stratum filter to narrow results.
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
// Both LOW and HIGH boundaries for the New York center
|
|
152
|
+
const zny = resolver.byArtcc('ZNY');
|
|
153
|
+
|
|
154
|
+
// Just the high-altitude boundary for the Boston center
|
|
155
|
+
const zbwHigh = resolver.byArtcc('ZBW', 'HIGH');
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### ARTCC altitude bounds
|
|
159
|
+
|
|
160
|
+
ARTCC features carry stratum-aligned floor/ceiling values for use with
|
|
161
|
+
`query()`:
|
|
162
|
+
|
|
163
|
+
| Stratum | Floor | Ceiling |
|
|
164
|
+
| --------- | ------------- | ------------- |
|
|
165
|
+
| `LOW` | SFC | 18,000 ft MSL |
|
|
166
|
+
| `HIGH` | 18,000 ft MSL | 60,000 ft MSL |
|
|
167
|
+
| `UTA` | 60,000 ft MSL | 99,999 ft MSL |
|
|
168
|
+
| `CTA` | SFC | 99,999 ft MSL |
|
|
169
|
+
| `FIR` | SFC | 99,999 ft MSL |
|
|
170
|
+
| `CTA/FIR` | SFC | 99,999 ft MSL |
|
|
171
|
+
|
|
172
|
+
These are operational stratum approximations rather than legal limits.
|
|
173
|
+
The `99,999` ceiling is a sentinel meaning "effectively unlimited" -
|
|
174
|
+
queries above FL600 will still match the relevant stratum.
|
|
175
|
+
|
|
176
|
+
Oceanic FIR boundaries that cross the 180th meridian (ZAK FIR/CTA and ZAP
|
|
177
|
+
FIR/CTA in the central Pacific) are split at the antimeridian during the
|
|
178
|
+
data build, so each emitted feature has coordinates within the standard
|
|
179
|
+
`[-180, 180]` range. A single source stratum produces two features in
|
|
180
|
+
those cases - one for the eastern sub-polygon and one for the western - but
|
|
181
|
+
both share the same `identifier` and `artccStratum`, so `byArtcc("ZAK")`
|
|
182
|
+
returns them together.
|
package/dist/resolver.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FeatureCollection } from 'geojson';
|
|
2
|
-
import type { AirspaceFeature, AirspaceType } from '@squawk/types';
|
|
2
|
+
import type { AirspaceFeature, AirspaceType, ArtccStratum } from '@squawk/types';
|
|
3
3
|
/**
|
|
4
4
|
* A query describing a geographic position and altitude to resolve
|
|
5
5
|
* against loaded airspace data.
|
|
@@ -50,12 +50,33 @@ export interface AirspaceResolver {
|
|
|
50
50
|
* only the bare identifier - ICAO-prefixed codes like "KJFK" will not
|
|
51
51
|
* match; resolve to an FAA ID first via `@squawk/airports` if needed.
|
|
52
52
|
*
|
|
53
|
+
* Note: ARTCC features share the identifier-keyed index but are typically
|
|
54
|
+
* looked up via {@link byArtcc} for clearer ergonomics. ARTCC features are
|
|
55
|
+
* excluded from `byAirport` results since their identifier is a center code
|
|
56
|
+
* (e.g. "ZNY"), not an airport identifier.
|
|
57
|
+
*
|
|
53
58
|
* @param identifier - FAA identifier or NASR designator.
|
|
54
59
|
* @param types - Optional type filter. Only features whose type is in this
|
|
55
|
-
* set are returned. When omitted, all types are
|
|
60
|
+
* set are returned. When omitted, all non-ARTCC types are
|
|
61
|
+
* returned.
|
|
56
62
|
* @returns All features whose identifier matches, or an empty array.
|
|
57
63
|
*/
|
|
58
64
|
byAirport(identifier: string, types?: ReadonlySet<AirspaceType>): AirspaceFeature[];
|
|
65
|
+
/**
|
|
66
|
+
* Returns every ARTCC feature associated with the given center identifier,
|
|
67
|
+
* independent of position or altitude. Lookup is case-insensitive.
|
|
68
|
+
*
|
|
69
|
+
* Each US ARTCC is published as multiple features - one per stratum (LOW,
|
|
70
|
+
* HIGH, UTA, CTA, FIR, CTA/FIR) - because the lateral extent can vary
|
|
71
|
+
* between strata. Pass an optional stratum filter to narrow results to a
|
|
72
|
+
* single stratum.
|
|
73
|
+
*
|
|
74
|
+
* @param identifier - Three-letter ARTCC code (e.g. "ZNY", "ZBW").
|
|
75
|
+
* @param stratum - Optional stratum filter. When provided, only features
|
|
76
|
+
* whose `artccStratum` matches are returned.
|
|
77
|
+
* @returns All matching ARTCC features, or an empty array.
|
|
78
|
+
*/
|
|
79
|
+
byArtcc(identifier: string, stratum?: ArtccStratum): AirspaceFeature[];
|
|
59
80
|
}
|
|
60
81
|
/**
|
|
61
82
|
* Creates a stateless airspace resolver. The resolver accepts a GeoJSON
|
|
@@ -81,6 +102,7 @@ export interface AirspaceResolver {
|
|
|
81
102
|
* const resolver = createAirspaceResolver({ data: usBundledAirspace });
|
|
82
103
|
* const overhead = resolver.query({ lat: 33.9425, lon: -118.4081, altitudeFt: 3000 });
|
|
83
104
|
* const laxShells = resolver.byAirport('LAX');
|
|
105
|
+
* const newYorkArtcc = resolver.byArtcc('ZNY');
|
|
84
106
|
* ```
|
|
85
107
|
*/
|
|
86
108
|
export declare function createAirspaceResolver(options: AirspaceResolverOptions): AirspaceResolver;
|
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,EAAE,iBAAiB,EAAW,MAAM,SAAS,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAiB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAW,MAAM,SAAS,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAiB,YAAY,EAAE,MAAM,eAAe,CAAC;AAIhG;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,8DAA8D;IAC9D,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,EAAE,aAAa,GAAG,eAAe,EAAE,CAAC;IAE/C;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,GAAG,eAAe,EAAE,CAAC;IAEpF;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,eAAe,EAAE,CAAC;CACxE;AAoDD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,gBAAgB,CAmEzF"}
|
package/dist/resolver.js
CHANGED
|
@@ -28,6 +28,7 @@ function parseFeature(geoFeature) {
|
|
|
28
28
|
state: props.state ?? null,
|
|
29
29
|
controllingFacility: props.controllingFacility ?? null,
|
|
30
30
|
scheduleDescription: props.scheduleDescription ?? null,
|
|
31
|
+
artccStratum: props.artccStratum ?? null,
|
|
31
32
|
};
|
|
32
33
|
return { feature, ring, boundingBox: polygon.boundingBox(ring) };
|
|
33
34
|
}
|
|
@@ -55,6 +56,7 @@ function parseFeature(geoFeature) {
|
|
|
55
56
|
* const resolver = createAirspaceResolver({ data: usBundledAirspace });
|
|
56
57
|
* const overhead = resolver.query({ lat: 33.9425, lon: -118.4081, altitudeFt: 3000 });
|
|
57
58
|
* const laxShells = resolver.byAirport('LAX');
|
|
59
|
+
* const newYorkArtcc = resolver.byArtcc('ZNY');
|
|
58
60
|
* ```
|
|
59
61
|
*/
|
|
60
62
|
export function createAirspaceResolver(options) {
|
|
@@ -103,9 +105,20 @@ export function createAirspaceResolver(options) {
|
|
|
103
105
|
return [];
|
|
104
106
|
}
|
|
105
107
|
if (types === undefined) {
|
|
106
|
-
return bucket.
|
|
108
|
+
return bucket.filter((f) => f.type !== 'ARTCC');
|
|
107
109
|
}
|
|
108
|
-
return bucket.filter((f) => types.has(f.type));
|
|
110
|
+
return bucket.filter((f) => f.type !== 'ARTCC' && types.has(f.type));
|
|
111
|
+
},
|
|
112
|
+
byArtcc(identifier, stratum) {
|
|
113
|
+
const bucket = byIdentifierMap.get(identifier.toUpperCase());
|
|
114
|
+
if (bucket === undefined) {
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
const artccFeatures = bucket.filter((f) => f.type === 'ARTCC');
|
|
118
|
+
if (stratum === undefined) {
|
|
119
|
+
return artccFeatures;
|
|
120
|
+
}
|
|
121
|
+
return artccFeatures.filter((f) => f.artccStratum === stratum);
|
|
109
122
|
},
|
|
110
123
|
};
|
|
111
124
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squawk/airspace",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Pure logic library for querying US airspace geometry by position and altitude",
|
|
6
6
|
"author": "Neil Cochran",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"lint:pack": "publint && attw --pack . --profile esm-only"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@squawk/geo": "^0.3.
|
|
38
|
-
"@squawk/types": "^0.
|
|
37
|
+
"@squawk/geo": "^0.3.2",
|
|
38
|
+
"@squawk/types": "^0.7.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@squawk/airspace-data": "^0.
|
|
41
|
+
"@squawk/airspace-data": "^0.4.0",
|
|
42
42
|
"@types/node": "^25.6.0"
|
|
43
43
|
},
|
|
44
44
|
"keywords": [
|