@squawk/airspace
Advanced tools
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAoB,MAAM,SAAS,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAiB,MAAM,eAAe,CAAC;AAIlF;;;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;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,eAAe,EAAE,CAAC;AA+F3E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,gBAAgB,CAqCzF"} | ||
| {"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;AAIlF;;;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;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,eAAe,EAAE,CAAC;AAmD3E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,gBAAgB,CAgCzF"} |
+6
-36
@@ -1,30 +0,4 @@ | ||
| import { pointInPolygon } from './point-in-polygon.js'; | ||
| import { polygon } from '@squawk/geo'; | ||
| import { altitudeMatches } from './vertical-filter.js'; | ||
| /** | ||
| * Computes an axis-aligned bounding box from a polygon exterior ring. | ||
| */ | ||
| function computeBoundingBox(ring) { | ||
| let minLon = Infinity; | ||
| let maxLon = -Infinity; | ||
| let minLat = Infinity; | ||
| let maxLat = -Infinity; | ||
| for (const coord of ring) { | ||
| const lon = coord[0]; | ||
| const lat = coord[1]; | ||
| if (lon < minLon) { | ||
| minLon = lon; | ||
| } | ||
| if (lon > maxLon) { | ||
| maxLon = lon; | ||
| } | ||
| if (lat < minLat) { | ||
| minLat = lat; | ||
| } | ||
| if (lat > maxLat) { | ||
| maxLat = lat; | ||
| } | ||
| } | ||
| return { minLon, maxLon, minLat, maxLat }; | ||
| } | ||
| /** | ||
| * Parses a GeoJSON Feature into an IndexedFeature, extracting the | ||
@@ -39,4 +13,3 @@ * AirspaceFeature properties and polygon ring. Returns null if the | ||
| } | ||
| const polygon = geom; | ||
| const ring = polygon.coordinates[0]; | ||
| const ring = geom.coordinates[0]; | ||
| if (!ring || ring.length < 4) { | ||
@@ -55,3 +28,3 @@ return null; | ||
| ceiling: props.ceiling, | ||
| boundary: polygon, | ||
| boundary: geom, | ||
| state: props.state ?? null, | ||
@@ -61,3 +34,3 @@ controllingFacility: props.controllingFacility ?? null, | ||
| }; | ||
| return { feature, ring, boundingBox: computeBoundingBox(ring) }; | ||
| return { feature, ring, boundingBox: polygon.boundingBox(ring) }; | ||
| } | ||
@@ -104,9 +77,6 @@ /** | ||
| } | ||
| if (lon < boundingBox.minLon || | ||
| lon > boundingBox.maxLon || | ||
| lat < boundingBox.minLat || | ||
| lat > boundingBox.maxLat) { | ||
| if (!polygon.pointInBoundingBox(lon, lat, boundingBox)) { | ||
| continue; | ||
| } | ||
| if (!pointInPolygon(lon, lat, ring)) { | ||
| if (!polygon.pointInPolygon(lon, lat, ring)) { | ||
| continue; | ||
@@ -113,0 +83,0 @@ } |
+2
-1
| { | ||
| "name": "@squawk/airspace", | ||
| "version": "0.2.2", | ||
| "version": "0.2.3", | ||
| "type": "module", | ||
@@ -36,2 +36,3 @@ "description": "Pure logic library for querying US airspace geometry by position and altitude", | ||
| "dependencies": { | ||
| "@squawk/geo": "*", | ||
| "@squawk/types": "*" | ||
@@ -38,0 +39,0 @@ }, |
| /** | ||
| * Tests whether a point is inside a polygon using the ray casting algorithm. | ||
| * The polygon is represented as an array of [lon, lat] coordinate pairs | ||
| * forming a closed ring (first and last points are identical). | ||
| * | ||
| * Returns true if the point is inside or on the boundary of the polygon. | ||
| */ | ||
| export declare function pointInPolygon( | ||
| /** Longitude of the test point in decimal degrees. */ | ||
| x: number, | ||
| /** Latitude of the test point in decimal degrees. */ | ||
| y: number, | ||
| /** Polygon exterior ring as [lon, lat] coordinate pairs. */ | ||
| ring: number[][]): boolean; | ||
| //# sourceMappingURL=point-in-polygon.d.ts.map |
| {"version":3,"file":"point-in-polygon.d.ts","sourceRoot":"","sources":["../src/point-in-polygon.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,cAAc;AAC5B,sDAAsD;AACtD,CAAC,EAAE,MAAM;AACT,qDAAqD;AACrD,CAAC,EAAE,MAAM;AACT,4DAA4D;AAC5D,IAAI,EAAE,MAAM,EAAE,EAAE,GACf,OAAO,CAgBT"} |
| /** | ||
| * Tests whether a point is inside a polygon using the ray casting algorithm. | ||
| * The polygon is represented as an array of [lon, lat] coordinate pairs | ||
| * forming a closed ring (first and last points are identical). | ||
| * | ||
| * Returns true if the point is inside or on the boundary of the polygon. | ||
| */ | ||
| export function pointInPolygon( | ||
| /** Longitude of the test point in decimal degrees. */ | ||
| x, | ||
| /** Latitude of the test point in decimal degrees. */ | ||
| y, | ||
| /** Polygon exterior ring as [lon, lat] coordinate pairs. */ | ||
| ring) { | ||
| let inside = false; | ||
| const len = ring.length; | ||
| for (let i = 0, j = len - 1; i < len; j = i++) { | ||
| const xi = ring[i][0]; | ||
| const yi = ring[i][1]; | ||
| const xj = ring[j][0]; | ||
| const yj = ring[j][1]; | ||
| if (yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi) { | ||
| inside = !inside; | ||
| } | ||
| } | ||
| return inside; | ||
| } |
Wildcard dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
15379
-14.16%2
100%11
-21.43%221
-24.32%3
50%+ Added
+ Added
+ Added