local-risk-alert-feed 0.1.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/dist/cjs/adapters/index.js +8 -0
- package/dist/cjs/adapters/index.js.map +1 -0
- package/dist/cjs/adapters/lambda.js +143 -0
- package/dist/cjs/adapters/lambda.js.map +1 -0
- package/dist/cjs/adapters/vercel.js +119 -0
- package/dist/cjs/adapters/vercel.js.map +1 -0
- package/dist/cjs/core/alert-aggregator.js +207 -0
- package/dist/cjs/core/alert-aggregator.js.map +1 -0
- package/dist/cjs/core/alert-feed.js +236 -0
- package/dist/cjs/core/alert-feed.js.map +1 -0
- package/dist/cjs/core/index.js +22 -0
- package/dist/cjs/core/index.js.map +1 -0
- package/dist/cjs/core/plugin-registry.js +193 -0
- package/dist/cjs/core/plugin-registry.js.map +1 -0
- package/dist/cjs/core/plugin-resolver.js +121 -0
- package/dist/cjs/core/plugin-resolver.js.map +1 -0
- package/dist/cjs/core/time-range.js +67 -0
- package/dist/cjs/core/time-range.js.map +1 -0
- package/dist/cjs/errors/fetch-error.js +71 -0
- package/dist/cjs/errors/fetch-error.js.map +1 -0
- package/dist/cjs/errors/index.js +15 -0
- package/dist/cjs/errors/index.js.map +1 -0
- package/dist/cjs/errors/plugin-error.js +80 -0
- package/dist/cjs/errors/plugin-error.js.map +1 -0
- package/dist/cjs/errors/validation-error.js +49 -0
- package/dist/cjs/errors/validation-error.js.map +1 -0
- package/dist/cjs/geo/distance.js +94 -0
- package/dist/cjs/geo/distance.js.map +1 -0
- package/dist/cjs/geo/index.js +18 -0
- package/dist/cjs/geo/index.js.map +1 -0
- package/dist/cjs/geo/point-in-radius.js +86 -0
- package/dist/cjs/geo/point-in-radius.js.map +1 -0
- package/dist/cjs/index.js +90 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/plugins/air-quality/airnow.plugin.js +343 -0
- package/dist/cjs/plugins/air-quality/airnow.plugin.js.map +1 -0
- package/dist/cjs/plugins/air-quality/index.js +6 -0
- package/dist/cjs/plugins/air-quality/index.js.map +1 -0
- package/dist/cjs/plugins/base-plugin.js +213 -0
- package/dist/cjs/plugins/base-plugin.js.map +1 -0
- package/dist/cjs/plugins/events/index.js +6 -0
- package/dist/cjs/plugins/events/index.js.map +1 -0
- package/dist/cjs/plugins/events/phoenix-events.plugin.js +382 -0
- package/dist/cjs/plugins/events/phoenix-events.plugin.js.map +1 -0
- package/dist/cjs/plugins/fire-emt/index.js +6 -0
- package/dist/cjs/plugins/fire-emt/index.js.map +1 -0
- package/dist/cjs/plugins/fire-emt/phoenix-fire.plugin.js +262 -0
- package/dist/cjs/plugins/fire-emt/phoenix-fire.plugin.js.map +1 -0
- package/dist/cjs/plugins/index.js +28 -0
- package/dist/cjs/plugins/index.js.map +1 -0
- package/dist/cjs/plugins/police-blotter/index.js +6 -0
- package/dist/cjs/plugins/police-blotter/index.js.map +1 -0
- package/dist/cjs/plugins/police-blotter/phoenix-police.plugin.js +198 -0
- package/dist/cjs/plugins/police-blotter/phoenix-police.plugin.js.map +1 -0
- package/dist/cjs/plugins/pulsepoint/index.js +6 -0
- package/dist/cjs/plugins/pulsepoint/index.js.map +1 -0
- package/dist/cjs/plugins/pulsepoint/pulsepoint.plugin.js +275 -0
- package/dist/cjs/plugins/pulsepoint/pulsepoint.plugin.js.map +1 -0
- package/dist/cjs/plugins/traffic/arizona-traffic.plugin.js +391 -0
- package/dist/cjs/plugins/traffic/arizona-traffic.plugin.js.map +1 -0
- package/dist/cjs/plugins/traffic/index.js +6 -0
- package/dist/cjs/plugins/traffic/index.js.map +1 -0
- package/dist/cjs/plugins/weather/index.js +6 -0
- package/dist/cjs/plugins/weather/index.js.map +1 -0
- package/dist/cjs/plugins/weather/nws-weather.plugin.js +180 -0
- package/dist/cjs/plugins/weather/nws-weather.plugin.js.map +1 -0
- package/dist/cjs/schemas/alert.schema.js +93 -0
- package/dist/cjs/schemas/alert.schema.js.map +1 -0
- package/dist/cjs/schemas/index.js +24 -0
- package/dist/cjs/schemas/index.js.map +1 -0
- package/dist/cjs/schemas/query.schema.js +76 -0
- package/dist/cjs/schemas/query.schema.js.map +1 -0
- package/dist/cjs/types/alert.js +35 -0
- package/dist/cjs/types/alert.js.map +1 -0
- package/dist/cjs/types/config.js +13 -0
- package/dist/cjs/types/config.js.map +1 -0
- package/dist/cjs/types/geo.js +3 -0
- package/dist/cjs/types/geo.js.map +1 -0
- package/dist/cjs/types/index.js +16 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/types/plugin.js +3 -0
- package/dist/cjs/types/plugin.js.map +1 -0
- package/dist/cjs/types/query.js +28 -0
- package/dist/cjs/types/query.js.map +1 -0
- package/dist/cjs/utils/cache.js +188 -0
- package/dist/cjs/utils/cache.js.map +1 -0
- package/dist/cjs/utils/csv.js +189 -0
- package/dist/cjs/utils/csv.js.map +1 -0
- package/dist/cjs/utils/date.js +153 -0
- package/dist/cjs/utils/date.js.map +1 -0
- package/dist/cjs/utils/index.js +28 -0
- package/dist/cjs/utils/index.js.map +1 -0
- package/dist/cjs/utils/retry.js +109 -0
- package/dist/cjs/utils/retry.js.map +1 -0
- package/dist/esm/adapters/index.js +3 -0
- package/dist/esm/adapters/index.js.map +1 -0
- package/dist/esm/adapters/lambda.js +140 -0
- package/dist/esm/adapters/lambda.js.map +1 -0
- package/dist/esm/adapters/vercel.js +116 -0
- package/dist/esm/adapters/vercel.js.map +1 -0
- package/dist/esm/core/alert-aggregator.js +203 -0
- package/dist/esm/core/alert-aggregator.js.map +1 -0
- package/dist/esm/core/alert-feed.js +232 -0
- package/dist/esm/core/alert-feed.js.map +1 -0
- package/dist/esm/core/index.js +6 -0
- package/dist/esm/core/index.js.map +1 -0
- package/dist/esm/core/plugin-registry.js +189 -0
- package/dist/esm/core/plugin-registry.js.map +1 -0
- package/dist/esm/core/plugin-resolver.js +117 -0
- package/dist/esm/core/plugin-resolver.js.map +1 -0
- package/dist/esm/core/time-range.js +57 -0
- package/dist/esm/core/time-range.js.map +1 -0
- package/dist/esm/errors/fetch-error.js +67 -0
- package/dist/esm/errors/fetch-error.js.map +1 -0
- package/dist/esm/errors/index.js +4 -0
- package/dist/esm/errors/index.js.map +1 -0
- package/dist/esm/errors/plugin-error.js +71 -0
- package/dist/esm/errors/plugin-error.js.map +1 -0
- package/dist/esm/errors/validation-error.js +45 -0
- package/dist/esm/errors/validation-error.js.map +1 -0
- package/dist/esm/geo/distance.js +85 -0
- package/dist/esm/geo/distance.js.map +1 -0
- package/dist/esm/geo/index.js +3 -0
- package/dist/esm/geo/index.js.map +1 -0
- package/dist/esm/geo/point-in-radius.js +79 -0
- package/dist/esm/geo/point-in-radius.js.map +1 -0
- package/dist/esm/index.js +30 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/plugins/air-quality/airnow.plugin.js +339 -0
- package/dist/esm/plugins/air-quality/airnow.plugin.js.map +1 -0
- package/dist/esm/plugins/air-quality/index.js +2 -0
- package/dist/esm/plugins/air-quality/index.js.map +1 -0
- package/dist/esm/plugins/base-plugin.js +209 -0
- package/dist/esm/plugins/base-plugin.js.map +1 -0
- package/dist/esm/plugins/events/index.js +2 -0
- package/dist/esm/plugins/events/index.js.map +1 -0
- package/dist/esm/plugins/events/phoenix-events.plugin.js +378 -0
- package/dist/esm/plugins/events/phoenix-events.plugin.js.map +1 -0
- package/dist/esm/plugins/fire-emt/index.js +2 -0
- package/dist/esm/plugins/fire-emt/index.js.map +1 -0
- package/dist/esm/plugins/fire-emt/phoenix-fire.plugin.js +258 -0
- package/dist/esm/plugins/fire-emt/phoenix-fire.plugin.js.map +1 -0
- package/dist/esm/plugins/index.js +17 -0
- package/dist/esm/plugins/index.js.map +1 -0
- package/dist/esm/plugins/police-blotter/index.js +2 -0
- package/dist/esm/plugins/police-blotter/index.js.map +1 -0
- package/dist/esm/plugins/police-blotter/phoenix-police.plugin.js +194 -0
- package/dist/esm/plugins/police-blotter/phoenix-police.plugin.js.map +1 -0
- package/dist/esm/plugins/pulsepoint/index.js +2 -0
- package/dist/esm/plugins/pulsepoint/index.js.map +1 -0
- package/dist/esm/plugins/pulsepoint/pulsepoint.plugin.js +271 -0
- package/dist/esm/plugins/pulsepoint/pulsepoint.plugin.js.map +1 -0
- package/dist/esm/plugins/traffic/arizona-traffic.plugin.js +387 -0
- package/dist/esm/plugins/traffic/arizona-traffic.plugin.js.map +1 -0
- package/dist/esm/plugins/traffic/index.js +2 -0
- package/dist/esm/plugins/traffic/index.js.map +1 -0
- package/dist/esm/plugins/weather/index.js +2 -0
- package/dist/esm/plugins/weather/index.js.map +1 -0
- package/dist/esm/plugins/weather/nws-weather.plugin.js +176 -0
- package/dist/esm/plugins/weather/nws-weather.plugin.js.map +1 -0
- package/dist/esm/schemas/alert.schema.js +90 -0
- package/dist/esm/schemas/alert.schema.js.map +1 -0
- package/dist/esm/schemas/index.js +5 -0
- package/dist/esm/schemas/index.js.map +1 -0
- package/dist/esm/schemas/query.schema.js +72 -0
- package/dist/esm/schemas/query.schema.js.map +1 -0
- package/dist/esm/types/alert.js +32 -0
- package/dist/esm/types/alert.js.map +1 -0
- package/dist/esm/types/config.js +10 -0
- package/dist/esm/types/config.js.map +1 -0
- package/dist/esm/types/geo.js +2 -0
- package/dist/esm/types/geo.js.map +1 -0
- package/dist/esm/types/index.js +4 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/types/plugin.js +2 -0
- package/dist/esm/types/plugin.js.map +1 -0
- package/dist/esm/types/query.js +25 -0
- package/dist/esm/types/query.js.map +1 -0
- package/dist/esm/utils/cache.js +181 -0
- package/dist/esm/utils/cache.js.map +1 -0
- package/dist/esm/utils/csv.js +185 -0
- package/dist/esm/utils/csv.js.map +1 -0
- package/dist/esm/utils/date.js +142 -0
- package/dist/esm/utils/date.js.map +1 -0
- package/dist/esm/utils/index.js +5 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/retry.js +102 -0
- package/dist/esm/utils/retry.js.map +1 -0
- package/dist/types/adapters/index.d.ts +5 -0
- package/dist/types/adapters/index.d.ts.map +1 -0
- package/dist/types/adapters/lambda.d.ts +37 -0
- package/dist/types/adapters/lambda.d.ts.map +1 -0
- package/dist/types/adapters/vercel.d.ts +54 -0
- package/dist/types/adapters/vercel.d.ts.map +1 -0
- package/dist/types/core/alert-aggregator.d.ts +81 -0
- package/dist/types/core/alert-aggregator.d.ts.map +1 -0
- package/dist/types/core/alert-feed.d.ts +80 -0
- package/dist/types/core/alert-feed.d.ts.map +1 -0
- package/dist/types/core/index.d.ts +8 -0
- package/dist/types/core/index.d.ts.map +1 -0
- package/dist/types/core/plugin-registry.d.ts +91 -0
- package/dist/types/core/plugin-registry.d.ts.map +1 -0
- package/dist/types/core/plugin-resolver.d.ts +78 -0
- package/dist/types/core/plugin-resolver.d.ts.map +1 -0
- package/dist/types/core/time-range.d.ts +40 -0
- package/dist/types/core/time-range.d.ts.map +1 -0
- package/dist/types/errors/fetch-error.d.ts +46 -0
- package/dist/types/errors/fetch-error.d.ts.map +1 -0
- package/dist/types/errors/index.d.ts +5 -0
- package/dist/types/errors/index.d.ts.map +1 -0
- package/dist/types/errors/plugin-error.d.ts +42 -0
- package/dist/types/errors/plugin-error.d.ts.map +1 -0
- package/dist/types/errors/validation-error.d.ts +34 -0
- package/dist/types/errors/validation-error.d.ts.map +1 -0
- package/dist/types/geo/distance.d.ts +50 -0
- package/dist/types/geo/distance.d.ts.map +1 -0
- package/dist/types/geo/index.d.ts +3 -0
- package/dist/types/geo/index.d.ts.map +1 -0
- package/dist/types/geo/point-in-radius.d.ts +44 -0
- package/dist/types/geo/point-in-radius.d.ts.map +1 -0
- package/dist/types/index.d.ts +32 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/plugins/air-quality/airnow.plugin.d.ts +84 -0
- package/dist/types/plugins/air-quality/airnow.plugin.d.ts.map +1 -0
- package/dist/types/plugins/air-quality/index.d.ts +3 -0
- package/dist/types/plugins/air-quality/index.d.ts.map +1 -0
- package/dist/types/plugins/base-plugin.d.ts +99 -0
- package/dist/types/plugins/base-plugin.d.ts.map +1 -0
- package/dist/types/plugins/events/index.d.ts +3 -0
- package/dist/types/plugins/events/index.d.ts.map +1 -0
- package/dist/types/plugins/events/phoenix-events.plugin.d.ts +71 -0
- package/dist/types/plugins/events/phoenix-events.plugin.d.ts.map +1 -0
- package/dist/types/plugins/fire-emt/index.d.ts +3 -0
- package/dist/types/plugins/fire-emt/index.d.ts.map +1 -0
- package/dist/types/plugins/fire-emt/phoenix-fire.plugin.d.ts +47 -0
- package/dist/types/plugins/fire-emt/phoenix-fire.plugin.d.ts.map +1 -0
- package/dist/types/plugins/index.d.ts +17 -0
- package/dist/types/plugins/index.d.ts.map +1 -0
- package/dist/types/plugins/police-blotter/index.d.ts +3 -0
- package/dist/types/plugins/police-blotter/index.d.ts.map +1 -0
- package/dist/types/plugins/police-blotter/phoenix-police.plugin.d.ts +49 -0
- package/dist/types/plugins/police-blotter/phoenix-police.plugin.d.ts.map +1 -0
- package/dist/types/plugins/pulsepoint/index.d.ts +3 -0
- package/dist/types/plugins/pulsepoint/index.d.ts.map +1 -0
- package/dist/types/plugins/pulsepoint/pulsepoint.plugin.d.ts +61 -0
- package/dist/types/plugins/pulsepoint/pulsepoint.plugin.d.ts.map +1 -0
- package/dist/types/plugins/traffic/arizona-traffic.plugin.d.ts +83 -0
- package/dist/types/plugins/traffic/arizona-traffic.plugin.d.ts.map +1 -0
- package/dist/types/plugins/traffic/index.d.ts +3 -0
- package/dist/types/plugins/traffic/index.d.ts.map +1 -0
- package/dist/types/plugins/weather/index.d.ts +3 -0
- package/dist/types/plugins/weather/index.d.ts.map +1 -0
- package/dist/types/plugins/weather/nws-weather.plugin.d.ts +50 -0
- package/dist/types/plugins/weather/nws-weather.plugin.d.ts.map +1 -0
- package/dist/types/schemas/alert.schema.d.ts +266 -0
- package/dist/types/schemas/alert.schema.d.ts.map +1 -0
- package/dist/types/schemas/index.d.ts +5 -0
- package/dist/types/schemas/index.d.ts.map +1 -0
- package/dist/types/schemas/query.schema.d.ts +150 -0
- package/dist/types/schemas/query.schema.d.ts.map +1 -0
- package/dist/types/types/alert.d.ts +96 -0
- package/dist/types/types/alert.d.ts.map +1 -0
- package/dist/types/types/config.d.ts +63 -0
- package/dist/types/types/config.d.ts.map +1 -0
- package/dist/types/types/geo.d.ts +33 -0
- package/dist/types/types/geo.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +9 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/types/plugin.d.ts +125 -0
- package/dist/types/types/plugin.d.ts.map +1 -0
- package/dist/types/types/query.d.ts +86 -0
- package/dist/types/types/query.d.ts.map +1 -0
- package/dist/types/utils/cache.d.ts +112 -0
- package/dist/types/utils/cache.d.ts.map +1 -0
- package/dist/types/utils/csv.d.ts +38 -0
- package/dist/types/utils/csv.d.ts.map +1 -0
- package/dist/types/utils/date.d.ts +47 -0
- package/dist/types/utils/date.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +7 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/dist/types/utils/retry.d.ts +51 -0
- package/dist/types/utils/retry.d.ts.map +1 -0
- package/package.json +115 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Earth's radius in meters (mean radius).
|
|
3
|
+
*/
|
|
4
|
+
export const EARTH_RADIUS_METERS = 6_371_008.8;
|
|
5
|
+
/**
|
|
6
|
+
* Convert degrees to radians.
|
|
7
|
+
*/
|
|
8
|
+
export function toRadians(degrees) {
|
|
9
|
+
return degrees * (Math.PI / 180);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Convert radians to degrees.
|
|
13
|
+
*/
|
|
14
|
+
export function toDegrees(radians) {
|
|
15
|
+
return radians * (180 / Math.PI);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Calculate the Haversine distance between two geographic points.
|
|
19
|
+
*
|
|
20
|
+
* The Haversine formula calculates the great-circle distance between two points
|
|
21
|
+
* on a sphere given their latitudes and longitudes.
|
|
22
|
+
*
|
|
23
|
+
* @param point1 - First geographic point
|
|
24
|
+
* @param point2 - Second geographic point
|
|
25
|
+
* @returns Distance in meters
|
|
26
|
+
*/
|
|
27
|
+
export function haversineDistance(point1, point2) {
|
|
28
|
+
const lat1 = toRadians(point1.latitude);
|
|
29
|
+
const lat2 = toRadians(point2.latitude);
|
|
30
|
+
const deltaLat = toRadians(point2.latitude - point1.latitude);
|
|
31
|
+
const deltaLon = toRadians(point2.longitude - point1.longitude);
|
|
32
|
+
const a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
|
|
33
|
+
Math.cos(lat1) * Math.cos(lat2) * Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
|
|
34
|
+
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
35
|
+
return EARTH_RADIUS_METERS * c;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Calculate distance between two points (alias for haversineDistance).
|
|
39
|
+
*
|
|
40
|
+
* @param point1 - First geographic point
|
|
41
|
+
* @param point2 - Second geographic point
|
|
42
|
+
* @returns Distance in meters
|
|
43
|
+
*/
|
|
44
|
+
export function calculateDistance(point1, point2) {
|
|
45
|
+
return haversineDistance(point1, point2);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Calculate the bearing (direction) from one point to another.
|
|
49
|
+
*
|
|
50
|
+
* @param from - Starting point
|
|
51
|
+
* @param to - Ending point
|
|
52
|
+
* @returns Bearing in degrees (0-360, where 0 is north)
|
|
53
|
+
*/
|
|
54
|
+
export function calculateBearing(from, to) {
|
|
55
|
+
const lat1 = toRadians(from.latitude);
|
|
56
|
+
const lat2 = toRadians(to.latitude);
|
|
57
|
+
const deltaLon = toRadians(to.longitude - from.longitude);
|
|
58
|
+
const y = Math.sin(deltaLon) * Math.cos(lat2);
|
|
59
|
+
const x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(deltaLon);
|
|
60
|
+
const bearing = toDegrees(Math.atan2(y, x));
|
|
61
|
+
return (bearing + 360) % 360;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Calculate a destination point given a start point, bearing, and distance.
|
|
65
|
+
*
|
|
66
|
+
* @param start - Starting point
|
|
67
|
+
* @param bearingDegrees - Bearing in degrees (0-360)
|
|
68
|
+
* @param distanceMeters - Distance in meters
|
|
69
|
+
* @returns Destination point
|
|
70
|
+
*/
|
|
71
|
+
export function destinationPoint(start, bearingDegrees, distanceMeters) {
|
|
72
|
+
const lat1 = toRadians(start.latitude);
|
|
73
|
+
const lon1 = toRadians(start.longitude);
|
|
74
|
+
const bearing = toRadians(bearingDegrees);
|
|
75
|
+
const angularDistance = distanceMeters / EARTH_RADIUS_METERS;
|
|
76
|
+
const lat2 = Math.asin(Math.sin(lat1) * Math.cos(angularDistance) +
|
|
77
|
+
Math.cos(lat1) * Math.sin(angularDistance) * Math.cos(bearing));
|
|
78
|
+
const lon2 = lon1 +
|
|
79
|
+
Math.atan2(Math.sin(bearing) * Math.sin(angularDistance) * Math.cos(lat1), Math.cos(angularDistance) - Math.sin(lat1) * Math.sin(lat2));
|
|
80
|
+
return {
|
|
81
|
+
latitude: toDegrees(lat2),
|
|
82
|
+
longitude: toDegrees(lon2),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=distance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distance.js","sourceRoot":"","sources":["../../../src/geo/distance.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAC;AAE/C;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,OAAO,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,OAAO,OAAO,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAgB,EAAE,MAAgB;IAClE,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAEhE,MAAM,CAAC,GACL,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;IAEpF,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAEzD,OAAO,mBAAmB,GAAG,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAgB,EAAE,MAAgB;IAClE,OAAO,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAc,EAAE,EAAY;IAC3D,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IAE1D,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,CAAC,GACL,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAEzF,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5C,OAAO,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AAC/B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAe,EACf,cAAsB,EACtB,cAAsB;IAEtB,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,SAAS,CAAC,cAAc,CAAC,CAAC;IAC1C,MAAM,eAAe,GAAG,cAAc,GAAG,mBAAmB,CAAC;IAE7D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CACjE,CAAC;IAEF,MAAM,IAAI,GACR,IAAI;QACJ,IAAI,CAAC,KAAK,CACR,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAC9D,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAC5D,CAAC;IAEJ,OAAO;QACL,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC;QACzB,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { EARTH_RADIUS_METERS, toRadians, toDegrees, haversineDistance, calculateDistance, calculateBearing, destinationPoint, } from './distance';
|
|
2
|
+
export { isPointInRadius, isPointInCircle, isPointInBoundingBox, doCirclesOverlap, getBoundingBoxForRadius, } from './point-in-radius';
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/geo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { haversineDistance } from './distance';
|
|
2
|
+
/**
|
|
3
|
+
* Check if a point is within a given radius of a center point.
|
|
4
|
+
*
|
|
5
|
+
* @param point - The point to check
|
|
6
|
+
* @param center - The center point
|
|
7
|
+
* @param radiusMeters - The radius in meters
|
|
8
|
+
* @returns true if the point is within the radius
|
|
9
|
+
*/
|
|
10
|
+
export function isPointInRadius(point, center, radiusMeters) {
|
|
11
|
+
const distance = haversineDistance(point, center);
|
|
12
|
+
return distance <= radiusMeters;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Check if a point is within a GeoCircle.
|
|
16
|
+
*
|
|
17
|
+
* @param point - The point to check
|
|
18
|
+
* @param circle - The circle definition
|
|
19
|
+
* @returns true if the point is within the circle
|
|
20
|
+
*/
|
|
21
|
+
export function isPointInCircle(point, circle) {
|
|
22
|
+
return isPointInRadius(point, circle.center, circle.radiusMeters);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check if a point is within a bounding box.
|
|
26
|
+
*
|
|
27
|
+
* @param point - The point to check
|
|
28
|
+
* @param box - The bounding box
|
|
29
|
+
* @returns true if the point is within the bounding box
|
|
30
|
+
*/
|
|
31
|
+
export function isPointInBoundingBox(point, box) {
|
|
32
|
+
const { southwest, northeast } = box;
|
|
33
|
+
// Handle the case where the bounding box crosses the antimeridian
|
|
34
|
+
if (southwest.longitude > northeast.longitude) {
|
|
35
|
+
// Box crosses antimeridian
|
|
36
|
+
return (point.latitude >= southwest.latitude &&
|
|
37
|
+
point.latitude <= northeast.latitude &&
|
|
38
|
+
(point.longitude >= southwest.longitude || point.longitude <= northeast.longitude));
|
|
39
|
+
}
|
|
40
|
+
return (point.latitude >= southwest.latitude &&
|
|
41
|
+
point.latitude <= northeast.latitude &&
|
|
42
|
+
point.longitude >= southwest.longitude &&
|
|
43
|
+
point.longitude <= northeast.longitude);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Check if two circles overlap.
|
|
47
|
+
*
|
|
48
|
+
* @param circle1 - First circle
|
|
49
|
+
* @param circle2 - Second circle
|
|
50
|
+
* @returns true if the circles overlap
|
|
51
|
+
*/
|
|
52
|
+
export function doCirclesOverlap(circle1, circle2) {
|
|
53
|
+
const distance = haversineDistance(circle1.center, circle2.center);
|
|
54
|
+
return distance <= circle1.radiusMeters + circle2.radiusMeters;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Calculate a bounding box that contains a circle.
|
|
58
|
+
* This is useful for quick filtering before doing precise distance calculations.
|
|
59
|
+
*
|
|
60
|
+
* @param center - Center point of the circle
|
|
61
|
+
* @param radiusMeters - Radius in meters
|
|
62
|
+
* @returns A bounding box that contains the circle
|
|
63
|
+
*/
|
|
64
|
+
export function getBoundingBoxForRadius(center, radiusMeters) {
|
|
65
|
+
// Approximate degrees per meter at the given latitude
|
|
66
|
+
const latDelta = radiusMeters / 111_320; // ~111.32km per degree latitude
|
|
67
|
+
const lonDelta = radiusMeters / (111_320 * Math.cos((center.latitude * Math.PI) / 180));
|
|
68
|
+
return {
|
|
69
|
+
southwest: {
|
|
70
|
+
latitude: Math.max(-90, center.latitude - latDelta),
|
|
71
|
+
longitude: center.longitude - lonDelta,
|
|
72
|
+
},
|
|
73
|
+
northeast: {
|
|
74
|
+
latitude: Math.min(90, center.latitude + latDelta),
|
|
75
|
+
longitude: center.longitude + lonDelta,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=point-in-radius.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"point-in-radius.js","sourceRoot":"","sources":["../../../src/geo/point-in-radius.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,KAAe,EAAE,MAAgB,EAAE,YAAoB;IACrF,MAAM,QAAQ,GAAG,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAClD,OAAO,QAAQ,IAAI,YAAY,CAAC;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,KAAe,EAAE,MAAiB;IAChE,OAAO,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;AACpE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAe,EAAE,GAAmB;IACvE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC;IAErC,kEAAkE;IAClE,IAAI,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;QAC9C,2BAA2B;QAC3B,OAAO,CACL,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ;YACpC,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ;YACpC,CAAC,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,CAAC,CACnF,CAAC;IACJ,CAAC;IAED,OAAO,CACL,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ;QACpC,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ;QACpC,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS;QACtC,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,CACvC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAkB,EAAE,OAAkB;IACrE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACnE,OAAO,QAAQ,IAAI,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;AACjE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAgB,EAAE,YAAoB;IAC5E,sDAAsD;IACtD,MAAM,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC,CAAC,gCAAgC;IACzE,MAAM,QAAQ,GAAG,YAAY,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAExF,OAAO;QACL,SAAS,EAAE;YACT,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACnD,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,QAAQ;SACvC;QACD,SAAS,EAAE;YACT,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;YAClD,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,QAAQ;SACvC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Main AlertFeed class
|
|
2
|
+
export { AlertFeed } from './core';
|
|
3
|
+
// Core components
|
|
4
|
+
export { PluginRegistry, PluginResolver, AlertAggregator } from './core';
|
|
5
|
+
export { resolveTimeRange, normalizeTimeRange } from './core';
|
|
6
|
+
// Type constants
|
|
7
|
+
export { RISK_LEVEL_VALUES, RISK_LEVELS, ALERT_CATEGORIES, ALERT_TEMPORAL_TYPES, TIME_RANGE_PRESETS, DEFAULT_QUERY_RADIUS_METERS, DEFAULT_QUERY_LIMIT, MAX_QUERY_LIMIT, DEFAULT_CONFIG, } from './types';
|
|
8
|
+
// Schemas
|
|
9
|
+
export { AlertSchema, AlertQuerySchema, AlertQueryRequestSchema, GeoPointSchema, TimeRangeSchema, transformRequestToQuery, } from './schemas';
|
|
10
|
+
// Errors
|
|
11
|
+
export { PluginError, PluginInitializationError, PluginFetchError, PluginTimeoutError, DuplicatePluginError, PluginNotFoundError, ValidationError, FetchError, } from './errors';
|
|
12
|
+
// Geo utilities
|
|
13
|
+
export { haversineDistance, calculateDistance, calculateBearing, destinationPoint, isPointInRadius, isPointInCircle, isPointInBoundingBox, doCirclesOverlap, getBoundingBoxForRadius, } from './geo';
|
|
14
|
+
// Cache providers
|
|
15
|
+
export { InMemoryCacheProvider, VercelKVCacheProvider, DynamoDBCacheProvider, generateCacheKey, } from './utils';
|
|
16
|
+
// Utility functions
|
|
17
|
+
export { withRetry, withTimeout, sleep, TimeoutError } from './utils';
|
|
18
|
+
// Base plugin for building custom plugins
|
|
19
|
+
export { BasePlugin } from './plugins';
|
|
20
|
+
// Built-in plugins
|
|
21
|
+
export { NWSWeatherPlugin } from './plugins/weather';
|
|
22
|
+
export { PhoenixPolicePlugin } from './plugins/police-blotter';
|
|
23
|
+
export { PhoenixFirePlugin } from './plugins/fire-emt';
|
|
24
|
+
export { PulsepointPlugin } from './plugins/pulsepoint';
|
|
25
|
+
export { PhoenixEventsPlugin } from './plugins/events';
|
|
26
|
+
export { ArizonaTrafficPlugin } from './plugins/traffic';
|
|
27
|
+
export { AirNowPlugin } from './plugins/air-quality';
|
|
28
|
+
// CSV utilities (for custom plugins that need CSV parsing)
|
|
29
|
+
export { parseCSV, toCSV } from './utils';
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEnC,kBAAkB;AAClB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAwC9D,iBAAiB;AACjB,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,2BAA2B,EAC3B,mBAAmB,EACnB,eAAe,EACf,cAAc,GACf,MAAM,SAAS,CAAC;AAEjB,UAAU;AACV,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,uBAAuB,GACxB,MAAM,WAAW,CAAC;AAEnB,SAAS;AACT,OAAO,EACL,WAAW,EACX,yBAAyB,EACzB,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,UAAU,GACX,MAAM,UAAU,CAAC;AAGlB,gBAAgB;AAChB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,OAAO,CAAC;AAEf,kBAAkB;AAClB,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAEjB,oBAAoB;AACpB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGtE,0CAA0C;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGvC,mBAAmB;AACnB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAG/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAGzD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGrD,2DAA2D;AAC3D,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { BasePlugin } from '../base-plugin';
|
|
2
|
+
/**
|
|
3
|
+
* AQI Category to risk level mapping.
|
|
4
|
+
* Based on EPA AQI scale:
|
|
5
|
+
* 1: Good (0-50)
|
|
6
|
+
* 2: Moderate (51-100)
|
|
7
|
+
* 3: Unhealthy for Sensitive Groups (101-150)
|
|
8
|
+
* 4: Unhealthy (151-200)
|
|
9
|
+
* 5: Very Unhealthy (201-300)
|
|
10
|
+
* 6: Hazardous (301+)
|
|
11
|
+
*/
|
|
12
|
+
const AQI_CATEGORY_RISK_MAP = {
|
|
13
|
+
1: 'low', // Good
|
|
14
|
+
2: 'low', // Moderate
|
|
15
|
+
3: 'moderate', // Unhealthy for Sensitive Groups
|
|
16
|
+
4: 'high', // Unhealthy
|
|
17
|
+
5: 'severe', // Very Unhealthy
|
|
18
|
+
6: 'extreme', // Hazardous
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* AQI Category descriptions.
|
|
22
|
+
*/
|
|
23
|
+
const AQI_CATEGORY_DESCRIPTIONS = {
|
|
24
|
+
1: 'Good - Air quality is satisfactory and poses little or no risk.',
|
|
25
|
+
2: 'Moderate - Air quality is acceptable; some pollutants may affect unusually sensitive people.',
|
|
26
|
+
3: 'Unhealthy for Sensitive Groups - Members of sensitive groups may experience health effects.',
|
|
27
|
+
4: 'Unhealthy - Everyone may begin to experience health effects.',
|
|
28
|
+
5: 'Very Unhealthy - Health alert: everyone may experience more serious health effects.',
|
|
29
|
+
6: 'Hazardous - Health warnings of emergency conditions.',
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Plugin that fetches air quality data from AirNow API.
|
|
33
|
+
*
|
|
34
|
+
* Provides current AQI observations and forecasts for US locations.
|
|
35
|
+
* Important for Phoenix due to dust storms and air quality concerns.
|
|
36
|
+
*
|
|
37
|
+
* @see https://docs.airnowapi.org
|
|
38
|
+
*/
|
|
39
|
+
export class AirNowPlugin extends BasePlugin {
|
|
40
|
+
metadata = {
|
|
41
|
+
id: 'airnow',
|
|
42
|
+
name: 'AirNow Air Quality',
|
|
43
|
+
version: '1.0.0',
|
|
44
|
+
description: 'Air quality index (AQI) data from EPA AirNow',
|
|
45
|
+
coverage: {
|
|
46
|
+
type: 'global',
|
|
47
|
+
description: 'United States',
|
|
48
|
+
},
|
|
49
|
+
supportedTemporalTypes: ['real-time', 'scheduled'],
|
|
50
|
+
supportedCategories: ['weather'], // Air quality is weather-related
|
|
51
|
+
refreshIntervalMs: 60 * 60 * 1000, // 1 hour - AQI updates hourly
|
|
52
|
+
};
|
|
53
|
+
airNowConfig;
|
|
54
|
+
constructor(config) {
|
|
55
|
+
super(config);
|
|
56
|
+
if (!config.apiKey) {
|
|
57
|
+
throw new Error('AirNow API key is required');
|
|
58
|
+
}
|
|
59
|
+
this.airNowConfig = {
|
|
60
|
+
includeForecast: true,
|
|
61
|
+
distanceMiles: 25,
|
|
62
|
+
...config,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
async fetchAlerts(options) {
|
|
66
|
+
const { location } = options;
|
|
67
|
+
const cacheKey = this.generateCacheKey(options);
|
|
68
|
+
const warnings = [];
|
|
69
|
+
try {
|
|
70
|
+
const { data, fromCache } = await this.getCachedOrFetch(cacheKey, () => this.fetchAirQualityData(location, warnings), this.config.cacheTtlMs);
|
|
71
|
+
return {
|
|
72
|
+
alerts: data,
|
|
73
|
+
fromCache,
|
|
74
|
+
cacheKey,
|
|
75
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error('AirNow fetch error:', error);
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Fetch air quality data from AirNow API.
|
|
85
|
+
*/
|
|
86
|
+
async fetchAirQualityData(location, warnings) {
|
|
87
|
+
const allAlerts = [];
|
|
88
|
+
// Fetch current observations
|
|
89
|
+
try {
|
|
90
|
+
const observations = await this.fetchCurrentObservations(location);
|
|
91
|
+
const observationAlerts = observations.map((obs) => this.transformObservation(obs));
|
|
92
|
+
allAlerts.push(...observationAlerts);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
warnings.push(`Failed to fetch current observations: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
96
|
+
}
|
|
97
|
+
// Fetch forecasts if enabled
|
|
98
|
+
if (this.airNowConfig.includeForecast) {
|
|
99
|
+
try {
|
|
100
|
+
const forecasts = await this.fetchForecasts(location);
|
|
101
|
+
const forecastAlerts = forecasts.map((forecast) => this.transformForecast(forecast));
|
|
102
|
+
allAlerts.push(...forecastAlerts);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
warnings.push(`Failed to fetch forecasts: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Deduplicate and prioritize by AQI
|
|
109
|
+
return this.deduplicateAlerts(allAlerts);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Fetch current air quality observations.
|
|
113
|
+
*/
|
|
114
|
+
async fetchCurrentObservations(location) {
|
|
115
|
+
const url = new URL('https://www.airnowapi.org/aq/observation/latLong/current/');
|
|
116
|
+
url.searchParams.set('format', 'application/json');
|
|
117
|
+
url.searchParams.set('latitude', String(location.latitude));
|
|
118
|
+
url.searchParams.set('longitude', String(location.longitude));
|
|
119
|
+
url.searchParams.set('distance', String(this.airNowConfig.distanceMiles));
|
|
120
|
+
url.searchParams.set('API_KEY', this.airNowConfig.apiKey);
|
|
121
|
+
return this.fetchJson(url.toString());
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Fetch air quality forecasts.
|
|
125
|
+
*/
|
|
126
|
+
async fetchForecasts(location) {
|
|
127
|
+
const url = new URL('https://www.airnowapi.org/aq/forecast/latLong/');
|
|
128
|
+
url.searchParams.set('format', 'application/json');
|
|
129
|
+
url.searchParams.set('latitude', String(location.latitude));
|
|
130
|
+
url.searchParams.set('longitude', String(location.longitude));
|
|
131
|
+
url.searchParams.set('distance', String(this.airNowConfig.distanceMiles));
|
|
132
|
+
url.searchParams.set('API_KEY', this.airNowConfig.apiKey);
|
|
133
|
+
// Get next 3 days of forecasts
|
|
134
|
+
const today = new Date();
|
|
135
|
+
const endDate = new Date(today);
|
|
136
|
+
endDate.setDate(endDate.getDate() + 3);
|
|
137
|
+
url.searchParams.set('date', this.formatDate(today));
|
|
138
|
+
return this.fetchJson(url.toString());
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Transform an observation to an alert.
|
|
142
|
+
*/
|
|
143
|
+
transformObservation(obs) {
|
|
144
|
+
const riskLevel = this.mapAqiToRiskLevel(obs.AQI, obs.Category.Number);
|
|
145
|
+
// Only create alerts for notable air quality (category 3+)
|
|
146
|
+
// Or always create if the AQI is significant
|
|
147
|
+
const issued = `${obs.DateObserved}T${String(obs.HourObserved).padStart(2, '0')}:00:00`;
|
|
148
|
+
return this.createAlert({
|
|
149
|
+
id: `airnow-obs-${obs.ReportingArea}-${obs.ParameterName}-${obs.DateObserved}`,
|
|
150
|
+
externalId: `${obs.ReportingArea}-${obs.ParameterName}`,
|
|
151
|
+
title: this.buildObservationTitle(obs),
|
|
152
|
+
description: this.buildObservationDescription(obs),
|
|
153
|
+
riskLevel,
|
|
154
|
+
priority: this.riskLevelToPriority(riskLevel),
|
|
155
|
+
category: 'weather',
|
|
156
|
+
temporalType: 'real-time',
|
|
157
|
+
location: {
|
|
158
|
+
point: { latitude: obs.Latitude, longitude: obs.Longitude },
|
|
159
|
+
address: `${obs.ReportingArea}, ${obs.StateCode}`,
|
|
160
|
+
},
|
|
161
|
+
timestamps: {
|
|
162
|
+
issued,
|
|
163
|
+
eventStart: issued,
|
|
164
|
+
},
|
|
165
|
+
metadata: {
|
|
166
|
+
parameterName: obs.ParameterName,
|
|
167
|
+
aqi: obs.AQI,
|
|
168
|
+
categoryNumber: obs.Category.Number,
|
|
169
|
+
categoryName: obs.Category.Name,
|
|
170
|
+
reportingArea: obs.ReportingArea,
|
|
171
|
+
isObservation: true,
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Transform a forecast to an alert.
|
|
177
|
+
*/
|
|
178
|
+
transformForecast(forecast) {
|
|
179
|
+
const riskLevel = this.mapAqiToRiskLevel(forecast.AQI, forecast.Category.Number);
|
|
180
|
+
return this.createAlert({
|
|
181
|
+
id: `airnow-fcst-${forecast.ReportingArea}-${forecast.ParameterName}-${forecast.DateForecast}`,
|
|
182
|
+
externalId: `${forecast.ReportingArea}-${forecast.ParameterName}-${forecast.DateForecast}`,
|
|
183
|
+
title: this.buildForecastTitle(forecast),
|
|
184
|
+
description: this.buildForecastDescription(forecast),
|
|
185
|
+
riskLevel,
|
|
186
|
+
priority: this.riskLevelToPriority(riskLevel),
|
|
187
|
+
category: 'weather',
|
|
188
|
+
temporalType: 'scheduled',
|
|
189
|
+
location: {
|
|
190
|
+
point: { latitude: forecast.Latitude, longitude: forecast.Longitude },
|
|
191
|
+
address: `${forecast.ReportingArea}, ${forecast.StateCode}`,
|
|
192
|
+
},
|
|
193
|
+
timestamps: {
|
|
194
|
+
issued: forecast.DateIssue,
|
|
195
|
+
eventStart: `${forecast.DateForecast}T00:00:00`,
|
|
196
|
+
eventEnd: `${forecast.DateForecast}T23:59:59`,
|
|
197
|
+
},
|
|
198
|
+
metadata: {
|
|
199
|
+
parameterName: forecast.ParameterName,
|
|
200
|
+
aqi: forecast.AQI,
|
|
201
|
+
categoryNumber: forecast.Category.Number,
|
|
202
|
+
categoryName: forecast.Category.Name,
|
|
203
|
+
reportingArea: forecast.ReportingArea,
|
|
204
|
+
actionDay: forecast.ActionDay,
|
|
205
|
+
discussion: forecast.Discussion,
|
|
206
|
+
isForecast: true,
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Map AQI value to risk level.
|
|
212
|
+
*/
|
|
213
|
+
mapAqiToRiskLevel(aqi, categoryNumber) {
|
|
214
|
+
// Use category number if available
|
|
215
|
+
if (AQI_CATEGORY_RISK_MAP[categoryNumber]) {
|
|
216
|
+
return AQI_CATEGORY_RISK_MAP[categoryNumber];
|
|
217
|
+
}
|
|
218
|
+
// Fall back to AQI value ranges
|
|
219
|
+
if (aqi <= 50)
|
|
220
|
+
return 'low';
|
|
221
|
+
if (aqi <= 100)
|
|
222
|
+
return 'low';
|
|
223
|
+
if (aqi <= 150)
|
|
224
|
+
return 'moderate';
|
|
225
|
+
if (aqi <= 200)
|
|
226
|
+
return 'high';
|
|
227
|
+
if (aqi <= 300)
|
|
228
|
+
return 'severe';
|
|
229
|
+
return 'extreme';
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Build observation title.
|
|
233
|
+
*/
|
|
234
|
+
buildObservationTitle(obs) {
|
|
235
|
+
const pollutant = this.formatPollutant(obs.ParameterName);
|
|
236
|
+
return `Air Quality ${obs.Category.Name} - ${pollutant} AQI ${obs.AQI}`;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Build forecast title.
|
|
240
|
+
*/
|
|
241
|
+
buildForecastTitle(forecast) {
|
|
242
|
+
const pollutant = this.formatPollutant(forecast.ParameterName);
|
|
243
|
+
const dateStr = this.formatForecastDate(forecast.DateForecast);
|
|
244
|
+
const actionDay = forecast.ActionDay ? ' (Action Day)' : '';
|
|
245
|
+
return `${dateStr} Air Quality Forecast: ${pollutant} AQI ${forecast.AQI}${actionDay}`;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Format pollutant name for display.
|
|
249
|
+
*/
|
|
250
|
+
formatPollutant(parameterName) {
|
|
251
|
+
const names = {
|
|
252
|
+
O3: 'Ozone',
|
|
253
|
+
'PM2.5': 'Fine Particles (PM2.5)',
|
|
254
|
+
PM10: 'Coarse Particles (PM10)',
|
|
255
|
+
};
|
|
256
|
+
return names[parameterName] ?? parameterName;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Format forecast date.
|
|
260
|
+
*/
|
|
261
|
+
formatForecastDate(dateStr) {
|
|
262
|
+
const date = new Date(dateStr);
|
|
263
|
+
const today = new Date();
|
|
264
|
+
const tomorrow = new Date(today);
|
|
265
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
266
|
+
if (date.toDateString() === today.toDateString()) {
|
|
267
|
+
return 'Today';
|
|
268
|
+
}
|
|
269
|
+
if (date.toDateString() === tomorrow.toDateString()) {
|
|
270
|
+
return 'Tomorrow';
|
|
271
|
+
}
|
|
272
|
+
return date.toLocaleDateString('en-US', { weekday: 'long', month: 'short', day: 'numeric' });
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Build observation description.
|
|
276
|
+
*/
|
|
277
|
+
buildObservationDescription(obs) {
|
|
278
|
+
const parts = [];
|
|
279
|
+
parts.push(`${this.formatPollutant(obs.ParameterName)}: AQI ${obs.AQI}`);
|
|
280
|
+
parts.push(`Category: ${obs.Category.Name}`);
|
|
281
|
+
parts.push('');
|
|
282
|
+
parts.push(AQI_CATEGORY_DESCRIPTIONS[obs.Category.Number] ?? '');
|
|
283
|
+
parts.push('');
|
|
284
|
+
parts.push(`Reporting Area: ${obs.ReportingArea}, ${obs.StateCode}`);
|
|
285
|
+
parts.push(`Observed: ${obs.DateObserved} ${obs.HourObserved}:00 ${obs.LocalTimeZone}`);
|
|
286
|
+
return parts.join('\n');
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Build forecast description.
|
|
290
|
+
*/
|
|
291
|
+
buildForecastDescription(forecast) {
|
|
292
|
+
const parts = [];
|
|
293
|
+
parts.push(`${this.formatPollutant(forecast.ParameterName)}: AQI ${forecast.AQI}`);
|
|
294
|
+
parts.push(`Category: ${forecast.Category.Name}`);
|
|
295
|
+
if (forecast.ActionDay) {
|
|
296
|
+
parts.push('');
|
|
297
|
+
parts.push('⚠️ ACTION DAY - Consider reducing outdoor activities');
|
|
298
|
+
}
|
|
299
|
+
parts.push('');
|
|
300
|
+
parts.push(AQI_CATEGORY_DESCRIPTIONS[forecast.Category.Number] ?? '');
|
|
301
|
+
if (forecast.Discussion) {
|
|
302
|
+
parts.push('');
|
|
303
|
+
parts.push(`Forecast Discussion: ${forecast.Discussion}`);
|
|
304
|
+
}
|
|
305
|
+
parts.push('');
|
|
306
|
+
parts.push(`Reporting Area: ${forecast.ReportingArea}, ${forecast.StateCode}`);
|
|
307
|
+
parts.push(`Forecast Date: ${forecast.DateForecast}`);
|
|
308
|
+
return parts.join('\n');
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Format date as YYYY-MM-DD.
|
|
312
|
+
*/
|
|
313
|
+
formatDate(date) {
|
|
314
|
+
return date.toISOString().split('T')[0];
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Deduplicate alerts, keeping highest AQI per location/date.
|
|
318
|
+
*/
|
|
319
|
+
deduplicateAlerts(alerts) {
|
|
320
|
+
const seen = new Map();
|
|
321
|
+
for (const alert of alerts) {
|
|
322
|
+
const key = `${alert.location.address}-${alert.temporalType}-${alert.timestamps.eventStart?.split('T')[0]}`;
|
|
323
|
+
const existing = seen.get(key);
|
|
324
|
+
if (!existing) {
|
|
325
|
+
seen.set(key, alert);
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
// Keep higher AQI
|
|
329
|
+
const existingAqi = existing.metadata?.aqi ?? 0;
|
|
330
|
+
const currentAqi = alert.metadata?.aqi ?? 0;
|
|
331
|
+
if (currentAqi > existingAqi) {
|
|
332
|
+
seen.set(key, alert);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
return Array.from(seen.values());
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
//# sourceMappingURL=airnow.plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"airnow.plugin.js","sourceRoot":"","sources":["../../../../src/plugins/air-quality/airnow.plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/plugins/air-quality/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|