@aguacerowx/mapsgl 0.0.54 → 0.0.55
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/package.json +3 -2
- package/src/NexradWeatherController.js +11 -1
- package/src/NwsWatchesWarningsOverlay.js +12 -8
- package/src/nexrad/loadNexradSites.ts +85 -7
- package/src/nexrad/nexradArchiveDiag.ts +26 -0
- package/src/nexrad/nexradMapboxFrameOpts.bundled.js +3 -2
- package/src/nexrad/nexradMapboxFrameOpts.ts +3 -2
- package/src/nexrad/nexradSitesDefault.json +1700 -0
- package/src/nexrad/radarArchiveCore.bundled.js +2724 -37
- package/src/nexrad/radarArchiveCore.ts +149 -30
- package/src/nexrad/radarDecode.worker.bundled.js +130 -126
- package/src/nexrad/radarDecode.worker.ts +13 -215
- package/src/nexrad/radarDecodeSlot.ts +195 -0
- package/src/nwsSdkConstants.js +8 -0
|
@@ -321,18 +321,18 @@ var require_buffer = __commonJS({
|
|
|
321
321
|
throw new RangeError('The value "' + size + '" is invalid for option "size"');
|
|
322
322
|
}
|
|
323
323
|
}
|
|
324
|
-
function alloc(size,
|
|
324
|
+
function alloc(size, fill2, encoding) {
|
|
325
325
|
assertSize(size);
|
|
326
326
|
if (size <= 0) {
|
|
327
327
|
return createBuffer(size);
|
|
328
328
|
}
|
|
329
|
-
if (
|
|
330
|
-
return typeof encoding === "string" ? createBuffer(size).fill(
|
|
329
|
+
if (fill2 !== void 0) {
|
|
330
|
+
return typeof encoding === "string" ? createBuffer(size).fill(fill2, encoding) : createBuffer(size).fill(fill2);
|
|
331
331
|
}
|
|
332
332
|
return createBuffer(size);
|
|
333
333
|
}
|
|
334
|
-
Buffer3.alloc = function(size,
|
|
335
|
-
return alloc(size,
|
|
334
|
+
Buffer3.alloc = function(size, fill2, encoding) {
|
|
335
|
+
return alloc(size, fill2, encoding);
|
|
336
336
|
};
|
|
337
337
|
function allocUnsafe(size) {
|
|
338
338
|
assertSize(size);
|
|
@@ -1503,7 +1503,7 @@ var require_buffer = __commonJS({
|
|
|
1503
1503
|
}
|
|
1504
1504
|
return len;
|
|
1505
1505
|
};
|
|
1506
|
-
Buffer3.prototype.fill = function
|
|
1506
|
+
Buffer3.prototype.fill = function fill2(val, start, end, encoding) {
|
|
1507
1507
|
if (typeof val === "string") {
|
|
1508
1508
|
if (typeof start === "string") {
|
|
1509
1509
|
encoding = start;
|
|
@@ -1784,9 +1784,9 @@ var require_buffer = __commonJS({
|
|
|
1784
1784
|
const alphabet = "0123456789abcdef";
|
|
1785
1785
|
const table = new Array(256);
|
|
1786
1786
|
for (let i = 0; i < 16; ++i) {
|
|
1787
|
-
const
|
|
1787
|
+
const i162 = i * 16;
|
|
1788
1788
|
for (let j = 0; j < 16; ++j) {
|
|
1789
|
-
table[
|
|
1789
|
+
table[i162 + j] = alphabet[i] + alphabet[j];
|
|
1790
1790
|
}
|
|
1791
1791
|
}
|
|
1792
1792
|
return table;
|
|
@@ -2985,21 +2985,1813 @@ function objectKeyFromArchiveUrlString(url) {
|
|
|
2985
2985
|
return null;
|
|
2986
2986
|
}
|
|
2987
2987
|
|
|
2988
|
+
// src/nexrad/nexradSitesDefault.json
|
|
2989
|
+
var nexradSitesDefault_default = {
|
|
2990
|
+
description: "NEXRAD WSR-88D Level II sites and TDWR Terminal Doppler Weather Radar sites",
|
|
2991
|
+
source: "NOAA Radar Operations Center / NWS",
|
|
2992
|
+
generated: "2026-04-03",
|
|
2993
|
+
counts: {
|
|
2994
|
+
"WSR-88D": 204,
|
|
2995
|
+
TDWR: 0,
|
|
2996
|
+
total: 204
|
|
2997
|
+
},
|
|
2998
|
+
sites: [
|
|
2999
|
+
{
|
|
3000
|
+
id: "KABR",
|
|
3001
|
+
name: "Aberdeen",
|
|
3002
|
+
state: "SD",
|
|
3003
|
+
lat: 45.4558,
|
|
3004
|
+
lon: -98.4134,
|
|
3005
|
+
type: "WSR-88D"
|
|
3006
|
+
},
|
|
3007
|
+
{
|
|
3008
|
+
id: "KABX",
|
|
3009
|
+
name: "Albuquerque",
|
|
3010
|
+
state: "NM",
|
|
3011
|
+
lat: 35.1498,
|
|
3012
|
+
lon: -106.824,
|
|
3013
|
+
type: "WSR-88D"
|
|
3014
|
+
},
|
|
3015
|
+
{
|
|
3016
|
+
id: "KAKQ",
|
|
3017
|
+
name: "Norfolk Rich",
|
|
3018
|
+
state: "VA",
|
|
3019
|
+
lat: 36.9841,
|
|
3020
|
+
lon: -77.0074,
|
|
3021
|
+
type: "WSR-88D"
|
|
3022
|
+
},
|
|
3023
|
+
{
|
|
3024
|
+
id: "KAMA",
|
|
3025
|
+
name: "Amarillo",
|
|
3026
|
+
state: "TX",
|
|
3027
|
+
lat: 35.2335,
|
|
3028
|
+
lon: -101.7093,
|
|
3029
|
+
type: "WSR-88D"
|
|
3030
|
+
},
|
|
3031
|
+
{
|
|
3032
|
+
id: "KAMX",
|
|
3033
|
+
name: "Miami",
|
|
3034
|
+
state: "FL",
|
|
3035
|
+
lat: 25.6111,
|
|
3036
|
+
lon: -80.4127,
|
|
3037
|
+
type: "WSR-88D"
|
|
3038
|
+
},
|
|
3039
|
+
{
|
|
3040
|
+
id: "KAPX",
|
|
3041
|
+
name: "Gaylord",
|
|
3042
|
+
state: "MI",
|
|
3043
|
+
lat: 44.9071,
|
|
3044
|
+
lon: -84.7198,
|
|
3045
|
+
type: "WSR-88D"
|
|
3046
|
+
},
|
|
3047
|
+
{
|
|
3048
|
+
id: "KARX",
|
|
3049
|
+
name: "La Crosse",
|
|
3050
|
+
state: "WI",
|
|
3051
|
+
lat: 43.8228,
|
|
3052
|
+
lon: -91.1913,
|
|
3053
|
+
type: "WSR-88D"
|
|
3054
|
+
},
|
|
3055
|
+
{
|
|
3056
|
+
id: "KATX",
|
|
3057
|
+
name: "Seattle",
|
|
3058
|
+
state: "WA",
|
|
3059
|
+
lat: 48.1945,
|
|
3060
|
+
lon: -122.4958,
|
|
3061
|
+
type: "WSR-88D"
|
|
3062
|
+
},
|
|
3063
|
+
{
|
|
3064
|
+
id: "KBBX",
|
|
3065
|
+
name: "Beale Afb",
|
|
3066
|
+
state: "CA",
|
|
3067
|
+
lat: 39.4957,
|
|
3068
|
+
lon: -121.6316,
|
|
3069
|
+
type: "WSR-88D"
|
|
3070
|
+
},
|
|
3071
|
+
{
|
|
3072
|
+
id: "KBGM",
|
|
3073
|
+
name: "Binghamton",
|
|
3074
|
+
state: "NY",
|
|
3075
|
+
lat: 42.1996,
|
|
3076
|
+
lon: -75.9847,
|
|
3077
|
+
type: "WSR-88D"
|
|
3078
|
+
},
|
|
3079
|
+
{
|
|
3080
|
+
id: "KBHX",
|
|
3081
|
+
name: "Eureka",
|
|
3082
|
+
state: "CA",
|
|
3083
|
+
lat: 40.4986,
|
|
3084
|
+
lon: -124.2921,
|
|
3085
|
+
type: "WSR-88D"
|
|
3086
|
+
},
|
|
3087
|
+
{
|
|
3088
|
+
id: "KBIS",
|
|
3089
|
+
name: "Bismarck",
|
|
3090
|
+
state: "ND",
|
|
3091
|
+
lat: 46.7709,
|
|
3092
|
+
lon: -100.7606,
|
|
3093
|
+
type: "WSR-88D"
|
|
3094
|
+
},
|
|
3095
|
+
{
|
|
3096
|
+
id: "KBLX",
|
|
3097
|
+
name: "Billings",
|
|
3098
|
+
state: "MT",
|
|
3099
|
+
lat: 45.8538,
|
|
3100
|
+
lon: -108.6068,
|
|
3101
|
+
type: "WSR-88D"
|
|
3102
|
+
},
|
|
3103
|
+
{
|
|
3104
|
+
id: "KBMX",
|
|
3105
|
+
name: "Birmingham",
|
|
3106
|
+
state: "AL",
|
|
3107
|
+
lat: 33.1722,
|
|
3108
|
+
lon: -86.7698,
|
|
3109
|
+
type: "WSR-88D"
|
|
3110
|
+
},
|
|
3111
|
+
{
|
|
3112
|
+
id: "KBOX",
|
|
3113
|
+
name: "Boston",
|
|
3114
|
+
state: "MA",
|
|
3115
|
+
lat: 41.9559,
|
|
3116
|
+
lon: -71.137,
|
|
3117
|
+
type: "WSR-88D"
|
|
3118
|
+
},
|
|
3119
|
+
{
|
|
3120
|
+
id: "KBRO",
|
|
3121
|
+
name: "Brownsville",
|
|
3122
|
+
state: "TX",
|
|
3123
|
+
lat: 25.916,
|
|
3124
|
+
lon: -97.4189,
|
|
3125
|
+
type: "WSR-88D"
|
|
3126
|
+
},
|
|
3127
|
+
{
|
|
3128
|
+
id: "KBUF",
|
|
3129
|
+
name: "Buffalo",
|
|
3130
|
+
state: "NY",
|
|
3131
|
+
lat: 42.9488,
|
|
3132
|
+
lon: -78.7368,
|
|
3133
|
+
type: "WSR-88D"
|
|
3134
|
+
},
|
|
3135
|
+
{
|
|
3136
|
+
id: "KBYX",
|
|
3137
|
+
name: "Key W",
|
|
3138
|
+
state: "FL",
|
|
3139
|
+
lat: 24.5975,
|
|
3140
|
+
lon: -81.7032,
|
|
3141
|
+
type: "WSR-88D"
|
|
3142
|
+
},
|
|
3143
|
+
{
|
|
3144
|
+
id: "KCAE",
|
|
3145
|
+
name: "Columbia",
|
|
3146
|
+
state: "SC",
|
|
3147
|
+
lat: 33.9488,
|
|
3148
|
+
lon: -81.1183,
|
|
3149
|
+
type: "WSR-88D"
|
|
3150
|
+
},
|
|
3151
|
+
{
|
|
3152
|
+
id: "KCBW",
|
|
3153
|
+
name: "Houlton",
|
|
3154
|
+
state: "ME",
|
|
3155
|
+
lat: 46.0393,
|
|
3156
|
+
lon: -67.8065,
|
|
3157
|
+
type: "WSR-88D"
|
|
3158
|
+
},
|
|
3159
|
+
{
|
|
3160
|
+
id: "KCBX",
|
|
3161
|
+
name: "Boise",
|
|
3162
|
+
state: "ID",
|
|
3163
|
+
lat: 43.4903,
|
|
3164
|
+
lon: -116.236,
|
|
3165
|
+
type: "WSR-88D"
|
|
3166
|
+
},
|
|
3167
|
+
{
|
|
3168
|
+
id: "KCCX",
|
|
3169
|
+
name: "State College",
|
|
3170
|
+
state: "PA",
|
|
3171
|
+
lat: 40.9232,
|
|
3172
|
+
lon: -78.0037,
|
|
3173
|
+
type: "WSR-88D"
|
|
3174
|
+
},
|
|
3175
|
+
{
|
|
3176
|
+
id: "KCLE",
|
|
3177
|
+
name: "Cleveland",
|
|
3178
|
+
state: "OH",
|
|
3179
|
+
lat: 41.4132,
|
|
3180
|
+
lon: -81.8597,
|
|
3181
|
+
type: "WSR-88D"
|
|
3182
|
+
},
|
|
3183
|
+
{
|
|
3184
|
+
id: "KCLX",
|
|
3185
|
+
name: "Charleston",
|
|
3186
|
+
state: "SC",
|
|
3187
|
+
lat: 32.6555,
|
|
3188
|
+
lon: -81.0423,
|
|
3189
|
+
type: "WSR-88D"
|
|
3190
|
+
},
|
|
3191
|
+
{
|
|
3192
|
+
id: "KCRP",
|
|
3193
|
+
name: "Corpus Christi",
|
|
3194
|
+
state: "TX",
|
|
3195
|
+
lat: 27.784,
|
|
3196
|
+
lon: -97.5113,
|
|
3197
|
+
type: "WSR-88D"
|
|
3198
|
+
},
|
|
3199
|
+
{
|
|
3200
|
+
id: "KCXX",
|
|
3201
|
+
name: "Burlington",
|
|
3202
|
+
state: "VT",
|
|
3203
|
+
lat: 44.511,
|
|
3204
|
+
lon: -73.1664,
|
|
3205
|
+
type: "WSR-88D"
|
|
3206
|
+
},
|
|
3207
|
+
{
|
|
3208
|
+
id: "KCYS",
|
|
3209
|
+
name: "Cheyenne",
|
|
3210
|
+
state: "WY",
|
|
3211
|
+
lat: 41.1519,
|
|
3212
|
+
lon: -104.8061,
|
|
3213
|
+
type: "WSR-88D"
|
|
3214
|
+
},
|
|
3215
|
+
{
|
|
3216
|
+
id: "KDAX",
|
|
3217
|
+
name: "Sacramento",
|
|
3218
|
+
state: "CA",
|
|
3219
|
+
lat: 38.5012,
|
|
3220
|
+
lon: -121.6779,
|
|
3221
|
+
type: "WSR-88D"
|
|
3222
|
+
},
|
|
3223
|
+
{
|
|
3224
|
+
id: "KDDC",
|
|
3225
|
+
name: "Dodge City",
|
|
3226
|
+
state: "KS",
|
|
3227
|
+
lat: 37.7608,
|
|
3228
|
+
lon: -99.9689,
|
|
3229
|
+
type: "WSR-88D"
|
|
3230
|
+
},
|
|
3231
|
+
{
|
|
3232
|
+
id: "KDFX",
|
|
3233
|
+
name: "Laughlin Afb",
|
|
3234
|
+
state: "TX",
|
|
3235
|
+
lat: 29.2731,
|
|
3236
|
+
lon: -100.2803,
|
|
3237
|
+
type: "WSR-88D"
|
|
3238
|
+
},
|
|
3239
|
+
{
|
|
3240
|
+
id: "KDGX",
|
|
3241
|
+
name: "Jackson Brandon",
|
|
3242
|
+
state: "MS",
|
|
3243
|
+
lat: 32.2798,
|
|
3244
|
+
lon: -89.9845,
|
|
3245
|
+
type: "WSR-88D"
|
|
3246
|
+
},
|
|
3247
|
+
{
|
|
3248
|
+
id: "KDIX",
|
|
3249
|
+
name: "Phila",
|
|
3250
|
+
state: "NJ",
|
|
3251
|
+
lat: 39.9471,
|
|
3252
|
+
lon: -74.4108,
|
|
3253
|
+
type: "WSR-88D"
|
|
3254
|
+
},
|
|
3255
|
+
{
|
|
3256
|
+
id: "KDLH",
|
|
3257
|
+
name: "Duluth",
|
|
3258
|
+
state: "MN",
|
|
3259
|
+
lat: 46.8369,
|
|
3260
|
+
lon: -92.2098,
|
|
3261
|
+
type: "WSR-88D"
|
|
3262
|
+
},
|
|
3263
|
+
{
|
|
3264
|
+
id: "KDMX",
|
|
3265
|
+
name: "Des Moines",
|
|
3266
|
+
state: "IA",
|
|
3267
|
+
lat: 41.7312,
|
|
3268
|
+
lon: -93.7229,
|
|
3269
|
+
type: "WSR-88D"
|
|
3270
|
+
},
|
|
3271
|
+
{
|
|
3272
|
+
id: "KDOX",
|
|
3273
|
+
name: "Dover Afb",
|
|
3274
|
+
state: "DE",
|
|
3275
|
+
lat: 38.8258,
|
|
3276
|
+
lon: -75.4401,
|
|
3277
|
+
type: "WSR-88D"
|
|
3278
|
+
},
|
|
3279
|
+
{
|
|
3280
|
+
id: "KDTX",
|
|
3281
|
+
name: "Detroit",
|
|
3282
|
+
state: "MI",
|
|
3283
|
+
lat: 42.7,
|
|
3284
|
+
lon: -83.4718,
|
|
3285
|
+
type: "WSR-88D"
|
|
3286
|
+
},
|
|
3287
|
+
{
|
|
3288
|
+
id: "KDVN",
|
|
3289
|
+
name: "Davenport",
|
|
3290
|
+
state: "IA",
|
|
3291
|
+
lat: 41.6116,
|
|
3292
|
+
lon: -90.5808,
|
|
3293
|
+
type: "WSR-88D"
|
|
3294
|
+
},
|
|
3295
|
+
{
|
|
3296
|
+
id: "KDYX",
|
|
3297
|
+
name: "Dyess Afb",
|
|
3298
|
+
state: "TX",
|
|
3299
|
+
lat: 32.5385,
|
|
3300
|
+
lon: -99.2543,
|
|
3301
|
+
type: "WSR-88D"
|
|
3302
|
+
},
|
|
3303
|
+
{
|
|
3304
|
+
id: "KEAX",
|
|
3305
|
+
name: "Kansas City",
|
|
3306
|
+
state: "MO",
|
|
3307
|
+
lat: 38.8102,
|
|
3308
|
+
lon: -94.2644,
|
|
3309
|
+
type: "WSR-88D"
|
|
3310
|
+
},
|
|
3311
|
+
{
|
|
3312
|
+
id: "KEMX",
|
|
3313
|
+
name: "Tucson",
|
|
3314
|
+
state: "AZ",
|
|
3315
|
+
lat: 31.8936,
|
|
3316
|
+
lon: -110.6303,
|
|
3317
|
+
type: "WSR-88D"
|
|
3318
|
+
},
|
|
3319
|
+
{
|
|
3320
|
+
id: "KENX",
|
|
3321
|
+
name: "Albany",
|
|
3322
|
+
state: "NY",
|
|
3323
|
+
lat: 42.5865,
|
|
3324
|
+
lon: -74.0639,
|
|
3325
|
+
type: "WSR-88D"
|
|
3326
|
+
},
|
|
3327
|
+
{
|
|
3328
|
+
id: "KEOX",
|
|
3329
|
+
name: "Ft Rucker",
|
|
3330
|
+
state: "AL",
|
|
3331
|
+
lat: 31.4606,
|
|
3332
|
+
lon: -85.4594,
|
|
3333
|
+
type: "WSR-88D"
|
|
3334
|
+
},
|
|
3335
|
+
{
|
|
3336
|
+
id: "KEPZ",
|
|
3337
|
+
name: "El Paso",
|
|
3338
|
+
state: "NM",
|
|
3339
|
+
lat: 31.8731,
|
|
3340
|
+
lon: -106.698,
|
|
3341
|
+
type: "WSR-88D"
|
|
3342
|
+
},
|
|
3343
|
+
{
|
|
3344
|
+
id: "KESX",
|
|
3345
|
+
name: "Las Vegas",
|
|
3346
|
+
state: "NV",
|
|
3347
|
+
lat: 35.7013,
|
|
3348
|
+
lon: -114.8915,
|
|
3349
|
+
type: "WSR-88D"
|
|
3350
|
+
},
|
|
3351
|
+
{
|
|
3352
|
+
id: "KEVX",
|
|
3353
|
+
name: "Eglin Afb",
|
|
3354
|
+
state: "FL",
|
|
3355
|
+
lat: 30.565,
|
|
3356
|
+
lon: -85.9216,
|
|
3357
|
+
type: "WSR-88D"
|
|
3358
|
+
},
|
|
3359
|
+
{
|
|
3360
|
+
id: "KEWX",
|
|
3361
|
+
name: "Austin San Antonio",
|
|
3362
|
+
state: "TX",
|
|
3363
|
+
lat: 29.7041,
|
|
3364
|
+
lon: -98.0285,
|
|
3365
|
+
type: "WSR-88D"
|
|
3366
|
+
},
|
|
3367
|
+
{
|
|
3368
|
+
id: "KEYX",
|
|
3369
|
+
name: "Edwards",
|
|
3370
|
+
state: "CA",
|
|
3371
|
+
lat: 35.0977,
|
|
3372
|
+
lon: -117.561,
|
|
3373
|
+
type: "WSR-88D"
|
|
3374
|
+
},
|
|
3375
|
+
{
|
|
3376
|
+
id: "KFCX",
|
|
3377
|
+
name: "Roanoke",
|
|
3378
|
+
state: "VA",
|
|
3379
|
+
lat: 37.0244,
|
|
3380
|
+
lon: -80.274,
|
|
3381
|
+
type: "WSR-88D"
|
|
3382
|
+
},
|
|
3383
|
+
{
|
|
3384
|
+
id: "KFDR",
|
|
3385
|
+
name: "Altus Afb",
|
|
3386
|
+
state: "OK",
|
|
3387
|
+
lat: 34.3622,
|
|
3388
|
+
lon: -98.9767,
|
|
3389
|
+
type: "WSR-88D"
|
|
3390
|
+
},
|
|
3391
|
+
{
|
|
3392
|
+
id: "KFDX",
|
|
3393
|
+
name: "Cannon Afb",
|
|
3394
|
+
state: "NM",
|
|
3395
|
+
lat: 34.6341,
|
|
3396
|
+
lon: -103.6189,
|
|
3397
|
+
type: "WSR-88D"
|
|
3398
|
+
},
|
|
3399
|
+
{
|
|
3400
|
+
id: "KFFC",
|
|
3401
|
+
name: "Atlanta",
|
|
3402
|
+
state: "GA",
|
|
3403
|
+
lat: 33.3635,
|
|
3404
|
+
lon: -84.5659,
|
|
3405
|
+
type: "WSR-88D"
|
|
3406
|
+
},
|
|
3407
|
+
{
|
|
3408
|
+
id: "KFSD",
|
|
3409
|
+
name: "Sioux Falls",
|
|
3410
|
+
state: "SD",
|
|
3411
|
+
lat: 43.5877,
|
|
3412
|
+
lon: -96.7294,
|
|
3413
|
+
type: "WSR-88D"
|
|
3414
|
+
},
|
|
3415
|
+
{
|
|
3416
|
+
id: "KFSX",
|
|
3417
|
+
name: "Flagstaff",
|
|
3418
|
+
state: "AZ",
|
|
3419
|
+
lat: 34.5743,
|
|
3420
|
+
lon: -111.1984,
|
|
3421
|
+
type: "WSR-88D"
|
|
3422
|
+
},
|
|
3423
|
+
{
|
|
3424
|
+
id: "KFTG",
|
|
3425
|
+
name: "Denver Front Range Ap",
|
|
3426
|
+
state: "CO",
|
|
3427
|
+
lat: 39.7866,
|
|
3428
|
+
lon: -104.5459,
|
|
3429
|
+
type: "WSR-88D"
|
|
3430
|
+
},
|
|
3431
|
+
{
|
|
3432
|
+
id: "KFWS",
|
|
3433
|
+
name: "Dallas",
|
|
3434
|
+
state: "TX",
|
|
3435
|
+
lat: 32.573,
|
|
3436
|
+
lon: -97.3032,
|
|
3437
|
+
type: "WSR-88D"
|
|
3438
|
+
},
|
|
3439
|
+
{
|
|
3440
|
+
id: "KGGW",
|
|
3441
|
+
name: "Glasgow",
|
|
3442
|
+
state: "MT",
|
|
3443
|
+
lat: 48.2065,
|
|
3444
|
+
lon: -106.6249,
|
|
3445
|
+
type: "WSR-88D"
|
|
3446
|
+
},
|
|
3447
|
+
{
|
|
3448
|
+
id: "KGJX",
|
|
3449
|
+
name: "Grand Junction",
|
|
3450
|
+
state: "CO",
|
|
3451
|
+
lat: 39.0622,
|
|
3452
|
+
lon: -108.2138,
|
|
3453
|
+
type: "WSR-88D"
|
|
3454
|
+
},
|
|
3455
|
+
{
|
|
3456
|
+
id: "KGLD",
|
|
3457
|
+
name: "Goodland",
|
|
3458
|
+
state: "KS",
|
|
3459
|
+
lat: 39.3669,
|
|
3460
|
+
lon: -101.7004,
|
|
3461
|
+
type: "WSR-88D"
|
|
3462
|
+
},
|
|
3463
|
+
{
|
|
3464
|
+
id: "KGRB",
|
|
3465
|
+
name: "Green Bay",
|
|
3466
|
+
state: "WI",
|
|
3467
|
+
lat: 44.4986,
|
|
3468
|
+
lon: -88.1113,
|
|
3469
|
+
type: "WSR-88D"
|
|
3470
|
+
},
|
|
3471
|
+
{
|
|
3472
|
+
id: "KGRK",
|
|
3473
|
+
name: "Ft Hood",
|
|
3474
|
+
state: "TX",
|
|
3475
|
+
lat: 30.7218,
|
|
3476
|
+
lon: -97.383,
|
|
3477
|
+
type: "WSR-88D"
|
|
3478
|
+
},
|
|
3479
|
+
{
|
|
3480
|
+
id: "KGRR",
|
|
3481
|
+
name: "Grand Rapids",
|
|
3482
|
+
state: "MI",
|
|
3483
|
+
lat: 42.8939,
|
|
3484
|
+
lon: -85.5449,
|
|
3485
|
+
type: "WSR-88D"
|
|
3486
|
+
},
|
|
3487
|
+
{
|
|
3488
|
+
id: "KGSP",
|
|
3489
|
+
name: "Greer",
|
|
3490
|
+
state: "SC",
|
|
3491
|
+
lat: 34.8833,
|
|
3492
|
+
lon: -82.22,
|
|
3493
|
+
type: "WSR-88D"
|
|
3494
|
+
},
|
|
3495
|
+
{
|
|
3496
|
+
id: "KGWX",
|
|
3497
|
+
name: "Columbus Afb",
|
|
3498
|
+
state: "MS",
|
|
3499
|
+
lat: 33.8969,
|
|
3500
|
+
lon: -88.3293,
|
|
3501
|
+
type: "WSR-88D"
|
|
3502
|
+
},
|
|
3503
|
+
{
|
|
3504
|
+
id: "KGYX",
|
|
3505
|
+
name: "Portland",
|
|
3506
|
+
state: "ME",
|
|
3507
|
+
lat: 43.8913,
|
|
3508
|
+
lon: -70.2566,
|
|
3509
|
+
type: "WSR-88D"
|
|
3510
|
+
},
|
|
3511
|
+
{
|
|
3512
|
+
id: "KHDC",
|
|
3513
|
+
name: "Hammond Muni Ap",
|
|
3514
|
+
state: "LA",
|
|
3515
|
+
lat: 30.5193,
|
|
3516
|
+
lon: -90.4074,
|
|
3517
|
+
type: "WSR-88D"
|
|
3518
|
+
},
|
|
3519
|
+
{
|
|
3520
|
+
id: "KHDX",
|
|
3521
|
+
name: "Holloman Afb",
|
|
3522
|
+
state: "NM",
|
|
3523
|
+
lat: 33.0769,
|
|
3524
|
+
lon: -106.1201,
|
|
3525
|
+
type: "WSR-88D"
|
|
3526
|
+
},
|
|
3527
|
+
{
|
|
3528
|
+
id: "KHGX",
|
|
3529
|
+
name: "Houston",
|
|
3530
|
+
state: "TX",
|
|
3531
|
+
lat: 29.472,
|
|
3532
|
+
lon: -95.0788,
|
|
3533
|
+
type: "WSR-88D"
|
|
3534
|
+
},
|
|
3535
|
+
{
|
|
3536
|
+
id: "KHNX",
|
|
3537
|
+
name: "San Joaquin Valley",
|
|
3538
|
+
state: "CA",
|
|
3539
|
+
lat: 36.3142,
|
|
3540
|
+
lon: -119.6322,
|
|
3541
|
+
type: "WSR-88D"
|
|
3542
|
+
},
|
|
3543
|
+
{
|
|
3544
|
+
id: "KHPX",
|
|
3545
|
+
name: "Ft Campbell",
|
|
3546
|
+
state: "KY",
|
|
3547
|
+
lat: 36.737,
|
|
3548
|
+
lon: -87.2856,
|
|
3549
|
+
type: "WSR-88D"
|
|
3550
|
+
},
|
|
3551
|
+
{
|
|
3552
|
+
id: "KHTX",
|
|
3553
|
+
name: "Huntsville",
|
|
3554
|
+
state: "AL",
|
|
3555
|
+
lat: 34.9306,
|
|
3556
|
+
lon: -86.0835,
|
|
3557
|
+
type: "WSR-88D"
|
|
3558
|
+
},
|
|
3559
|
+
{
|
|
3560
|
+
id: "KICT",
|
|
3561
|
+
name: "Wichita",
|
|
3562
|
+
state: "KS",
|
|
3563
|
+
lat: 37.6546,
|
|
3564
|
+
lon: -97.4431,
|
|
3565
|
+
type: "WSR-88D"
|
|
3566
|
+
},
|
|
3567
|
+
{
|
|
3568
|
+
id: "KICX",
|
|
3569
|
+
name: "Cedar City",
|
|
3570
|
+
state: "UT",
|
|
3571
|
+
lat: 37.591,
|
|
3572
|
+
lon: -112.8623,
|
|
3573
|
+
type: "WSR-88D"
|
|
3574
|
+
},
|
|
3575
|
+
{
|
|
3576
|
+
id: "KILN",
|
|
3577
|
+
name: "Cincinnati",
|
|
3578
|
+
state: "OH",
|
|
3579
|
+
lat: 39.4202,
|
|
3580
|
+
lon: -83.8216,
|
|
3581
|
+
type: "WSR-88D"
|
|
3582
|
+
},
|
|
3583
|
+
{
|
|
3584
|
+
id: "KILX",
|
|
3585
|
+
name: "Lincoln",
|
|
3586
|
+
state: "IL",
|
|
3587
|
+
lat: 40.1505,
|
|
3588
|
+
lon: -89.3368,
|
|
3589
|
+
type: "WSR-88D"
|
|
3590
|
+
},
|
|
3591
|
+
{
|
|
3592
|
+
id: "KIND",
|
|
3593
|
+
name: "Indianapolis",
|
|
3594
|
+
state: "IN",
|
|
3595
|
+
lat: 39.7075,
|
|
3596
|
+
lon: -86.2804,
|
|
3597
|
+
type: "WSR-88D"
|
|
3598
|
+
},
|
|
3599
|
+
{
|
|
3600
|
+
id: "KINX",
|
|
3601
|
+
name: "Tulsa",
|
|
3602
|
+
state: "OK",
|
|
3603
|
+
lat: 36.1751,
|
|
3604
|
+
lon: -95.5642,
|
|
3605
|
+
type: "WSR-88D"
|
|
3606
|
+
},
|
|
3607
|
+
{
|
|
3608
|
+
id: "KIWA",
|
|
3609
|
+
name: "Phoenix",
|
|
3610
|
+
state: "AZ",
|
|
3611
|
+
lat: 33.2893,
|
|
3612
|
+
lon: -111.6699,
|
|
3613
|
+
type: "WSR-88D"
|
|
3614
|
+
},
|
|
3615
|
+
{
|
|
3616
|
+
id: "KIWX",
|
|
3617
|
+
name: "Ft Wayne",
|
|
3618
|
+
state: "IN",
|
|
3619
|
+
lat: 41.3586,
|
|
3620
|
+
lon: -85.7,
|
|
3621
|
+
type: "WSR-88D"
|
|
3622
|
+
},
|
|
3623
|
+
{
|
|
3624
|
+
id: "KJAX",
|
|
3625
|
+
name: "Jacksonville",
|
|
3626
|
+
state: "FL",
|
|
3627
|
+
lat: 30.4846,
|
|
3628
|
+
lon: -81.7019,
|
|
3629
|
+
type: "WSR-88D"
|
|
3630
|
+
},
|
|
3631
|
+
{
|
|
3632
|
+
id: "KJGX",
|
|
3633
|
+
name: "Robins Afb",
|
|
3634
|
+
state: "GA",
|
|
3635
|
+
lat: 32.6756,
|
|
3636
|
+
lon: -83.3509,
|
|
3637
|
+
type: "WSR-88D"
|
|
3638
|
+
},
|
|
3639
|
+
{
|
|
3640
|
+
id: "KJKL",
|
|
3641
|
+
name: "Jackson",
|
|
3642
|
+
state: "KY",
|
|
3643
|
+
lat: 37.5908,
|
|
3644
|
+
lon: -83.3131,
|
|
3645
|
+
type: "WSR-88D"
|
|
3646
|
+
},
|
|
3647
|
+
{
|
|
3648
|
+
id: "KLBB",
|
|
3649
|
+
name: "Lubbock",
|
|
3650
|
+
state: "TX",
|
|
3651
|
+
lat: 33.6541,
|
|
3652
|
+
lon: -101.8141,
|
|
3653
|
+
type: "WSR-88D"
|
|
3654
|
+
},
|
|
3655
|
+
{
|
|
3656
|
+
id: "KLCH",
|
|
3657
|
+
name: "Lake Charles",
|
|
3658
|
+
state: "LA",
|
|
3659
|
+
lat: 30.1253,
|
|
3660
|
+
lon: -93.2158,
|
|
3661
|
+
type: "WSR-88D"
|
|
3662
|
+
},
|
|
3663
|
+
{
|
|
3664
|
+
id: "KLGX",
|
|
3665
|
+
name: "Langley Hill Nw Washin",
|
|
3666
|
+
state: "WA",
|
|
3667
|
+
lat: 47.1169,
|
|
3668
|
+
lon: -124.1066,
|
|
3669
|
+
type: "WSR-88D"
|
|
3670
|
+
},
|
|
3671
|
+
{
|
|
3672
|
+
id: "KLNX",
|
|
3673
|
+
name: "N Platte",
|
|
3674
|
+
state: "NE",
|
|
3675
|
+
lat: 41.9579,
|
|
3676
|
+
lon: -100.5763,
|
|
3677
|
+
type: "WSR-88D"
|
|
3678
|
+
},
|
|
3679
|
+
{
|
|
3680
|
+
id: "KLOT",
|
|
3681
|
+
name: "Chicago",
|
|
3682
|
+
state: "IL",
|
|
3683
|
+
lat: 41.6044,
|
|
3684
|
+
lon: -88.0845,
|
|
3685
|
+
type: "WSR-88D"
|
|
3686
|
+
},
|
|
3687
|
+
{
|
|
3688
|
+
id: "KLRX",
|
|
3689
|
+
name: "Elko",
|
|
3690
|
+
state: "NV",
|
|
3691
|
+
lat: 40.7397,
|
|
3692
|
+
lon: -116.8027,
|
|
3693
|
+
type: "WSR-88D"
|
|
3694
|
+
},
|
|
3695
|
+
{
|
|
3696
|
+
id: "KLSX",
|
|
3697
|
+
name: "St Louis",
|
|
3698
|
+
state: "MO",
|
|
3699
|
+
lat: 38.6987,
|
|
3700
|
+
lon: -90.6829,
|
|
3701
|
+
type: "WSR-88D"
|
|
3702
|
+
},
|
|
3703
|
+
{
|
|
3704
|
+
id: "KLTX",
|
|
3705
|
+
name: "Wilmington",
|
|
3706
|
+
state: "NC",
|
|
3707
|
+
lat: 33.9892,
|
|
3708
|
+
lon: -78.4291,
|
|
3709
|
+
type: "WSR-88D"
|
|
3710
|
+
},
|
|
3711
|
+
{
|
|
3712
|
+
id: "KLVX",
|
|
3713
|
+
name: "Louisville",
|
|
3714
|
+
state: "KY",
|
|
3715
|
+
lat: 37.9753,
|
|
3716
|
+
lon: -85.9438,
|
|
3717
|
+
type: "WSR-88D"
|
|
3718
|
+
},
|
|
3719
|
+
{
|
|
3720
|
+
id: "KLWX",
|
|
3721
|
+
name: "Sterling",
|
|
3722
|
+
state: "VA",
|
|
3723
|
+
lat: 38.9763,
|
|
3724
|
+
lon: -77.4876,
|
|
3725
|
+
type: "WSR-88D"
|
|
3726
|
+
},
|
|
3727
|
+
{
|
|
3728
|
+
id: "KLZK",
|
|
3729
|
+
name: "Little Rock",
|
|
3730
|
+
state: "AR",
|
|
3731
|
+
lat: 34.8365,
|
|
3732
|
+
lon: -92.2622,
|
|
3733
|
+
type: "WSR-88D"
|
|
3734
|
+
},
|
|
3735
|
+
{
|
|
3736
|
+
id: "KMAF",
|
|
3737
|
+
name: "Midland Odessa",
|
|
3738
|
+
state: "TX",
|
|
3739
|
+
lat: 31.9434,
|
|
3740
|
+
lon: -102.1892,
|
|
3741
|
+
type: "WSR-88D"
|
|
3742
|
+
},
|
|
3743
|
+
{
|
|
3744
|
+
id: "KMAX",
|
|
3745
|
+
name: "Medford",
|
|
3746
|
+
state: "OR",
|
|
3747
|
+
lat: 42.0811,
|
|
3748
|
+
lon: -122.7174,
|
|
3749
|
+
type: "WSR-88D"
|
|
3750
|
+
},
|
|
3751
|
+
{
|
|
3752
|
+
id: "KMBX",
|
|
3753
|
+
name: "Minot Afb",
|
|
3754
|
+
state: "ND",
|
|
3755
|
+
lat: 48.393,
|
|
3756
|
+
lon: -100.8645,
|
|
3757
|
+
type: "WSR-88D"
|
|
3758
|
+
},
|
|
3759
|
+
{
|
|
3760
|
+
id: "KMHX",
|
|
3761
|
+
name: "Morehead City",
|
|
3762
|
+
state: "NC",
|
|
3763
|
+
lat: 34.7759,
|
|
3764
|
+
lon: -76.8762,
|
|
3765
|
+
type: "WSR-88D"
|
|
3766
|
+
},
|
|
3767
|
+
{
|
|
3768
|
+
id: "KMKX",
|
|
3769
|
+
name: "Milwaukee",
|
|
3770
|
+
state: "WI",
|
|
3771
|
+
lat: 42.9678,
|
|
3772
|
+
lon: -88.5506,
|
|
3773
|
+
type: "WSR-88D"
|
|
3774
|
+
},
|
|
3775
|
+
{
|
|
3776
|
+
id: "KMLB",
|
|
3777
|
+
name: "Melbourne",
|
|
3778
|
+
state: "FL",
|
|
3779
|
+
lat: 28.1132,
|
|
3780
|
+
lon: -80.6542,
|
|
3781
|
+
type: "WSR-88D"
|
|
3782
|
+
},
|
|
3783
|
+
{
|
|
3784
|
+
id: "KMOB",
|
|
3785
|
+
name: "Mobile",
|
|
3786
|
+
state: "AL",
|
|
3787
|
+
lat: 30.6795,
|
|
3788
|
+
lon: -88.2399,
|
|
3789
|
+
type: "WSR-88D"
|
|
3790
|
+
},
|
|
3791
|
+
{
|
|
3792
|
+
id: "KMPX",
|
|
3793
|
+
name: "Minneapolis",
|
|
3794
|
+
state: "MN",
|
|
3795
|
+
lat: 44.8488,
|
|
3796
|
+
lon: -93.5655,
|
|
3797
|
+
type: "WSR-88D"
|
|
3798
|
+
},
|
|
3799
|
+
{
|
|
3800
|
+
id: "KMQT",
|
|
3801
|
+
name: "Marquette",
|
|
3802
|
+
state: "MI",
|
|
3803
|
+
lat: 46.5311,
|
|
3804
|
+
lon: -87.5485,
|
|
3805
|
+
type: "WSR-88D"
|
|
3806
|
+
},
|
|
3807
|
+
{
|
|
3808
|
+
id: "KMRX",
|
|
3809
|
+
name: "Knoxville",
|
|
3810
|
+
state: "TN",
|
|
3811
|
+
lat: 36.1685,
|
|
3812
|
+
lon: -83.4018,
|
|
3813
|
+
type: "WSR-88D"
|
|
3814
|
+
},
|
|
3815
|
+
{
|
|
3816
|
+
id: "KMSX",
|
|
3817
|
+
name: "Missoula",
|
|
3818
|
+
state: "MT",
|
|
3819
|
+
lat: 47.041,
|
|
3820
|
+
lon: -113.9862,
|
|
3821
|
+
type: "WSR-88D"
|
|
3822
|
+
},
|
|
3823
|
+
{
|
|
3824
|
+
id: "KMTX",
|
|
3825
|
+
name: "Salt Lake City",
|
|
3826
|
+
state: "UT",
|
|
3827
|
+
lat: 41.2627,
|
|
3828
|
+
lon: -112.4477,
|
|
3829
|
+
type: "WSR-88D"
|
|
3830
|
+
},
|
|
3831
|
+
{
|
|
3832
|
+
id: "KMUX",
|
|
3833
|
+
name: "San Francisco",
|
|
3834
|
+
state: "CA",
|
|
3835
|
+
lat: 37.1551,
|
|
3836
|
+
lon: -121.8985,
|
|
3837
|
+
type: "WSR-88D"
|
|
3838
|
+
},
|
|
3839
|
+
{
|
|
3840
|
+
id: "KMVX",
|
|
3841
|
+
name: "Grand Forks",
|
|
3842
|
+
state: "ND",
|
|
3843
|
+
lat: 47.5279,
|
|
3844
|
+
lon: -97.3255,
|
|
3845
|
+
type: "WSR-88D"
|
|
3846
|
+
},
|
|
3847
|
+
{
|
|
3848
|
+
id: "KMXX",
|
|
3849
|
+
name: "Maxwell Afb",
|
|
3850
|
+
state: "AL",
|
|
3851
|
+
lat: 32.5366,
|
|
3852
|
+
lon: -85.7897,
|
|
3853
|
+
type: "WSR-88D"
|
|
3854
|
+
},
|
|
3855
|
+
{
|
|
3856
|
+
id: "KNKX",
|
|
3857
|
+
name: "San Diego",
|
|
3858
|
+
state: "CA",
|
|
3859
|
+
lat: 32.919,
|
|
3860
|
+
lon: -117.0419,
|
|
3861
|
+
type: "WSR-88D"
|
|
3862
|
+
},
|
|
3863
|
+
{
|
|
3864
|
+
id: "KNQA",
|
|
3865
|
+
name: "Memphis",
|
|
3866
|
+
state: "TN",
|
|
3867
|
+
lat: 35.3448,
|
|
3868
|
+
lon: -89.8734,
|
|
3869
|
+
type: "WSR-88D"
|
|
3870
|
+
},
|
|
3871
|
+
{
|
|
3872
|
+
id: "KOAX",
|
|
3873
|
+
name: "Omaha",
|
|
3874
|
+
state: "NE",
|
|
3875
|
+
lat: 41.3202,
|
|
3876
|
+
lon: -96.3668,
|
|
3877
|
+
type: "WSR-88D"
|
|
3878
|
+
},
|
|
3879
|
+
{
|
|
3880
|
+
id: "KOHX",
|
|
3881
|
+
name: "Nashville",
|
|
3882
|
+
state: "TN",
|
|
3883
|
+
lat: 36.2472,
|
|
3884
|
+
lon: -86.5625,
|
|
3885
|
+
type: "WSR-88D"
|
|
3886
|
+
},
|
|
3887
|
+
{
|
|
3888
|
+
id: "KOKX",
|
|
3889
|
+
name: "Nyc",
|
|
3890
|
+
state: "NY",
|
|
3891
|
+
lat: 40.8656,
|
|
3892
|
+
lon: -72.8639,
|
|
3893
|
+
type: "WSR-88D"
|
|
3894
|
+
},
|
|
3895
|
+
{
|
|
3896
|
+
id: "KOTX",
|
|
3897
|
+
name: "Spokane",
|
|
3898
|
+
state: "WA",
|
|
3899
|
+
lat: 47.6804,
|
|
3900
|
+
lon: -117.6268,
|
|
3901
|
+
type: "WSR-88D"
|
|
3902
|
+
},
|
|
3903
|
+
{
|
|
3904
|
+
id: "KPAH",
|
|
3905
|
+
name: "Paducah",
|
|
3906
|
+
state: "KY",
|
|
3907
|
+
lat: 37.0684,
|
|
3908
|
+
lon: -88.7721,
|
|
3909
|
+
type: "WSR-88D"
|
|
3910
|
+
},
|
|
3911
|
+
{
|
|
3912
|
+
id: "KPBZ",
|
|
3913
|
+
name: "Pittsburgh",
|
|
3914
|
+
state: "PA",
|
|
3915
|
+
lat: 40.5316,
|
|
3916
|
+
lon: -80.218,
|
|
3917
|
+
type: "WSR-88D"
|
|
3918
|
+
},
|
|
3919
|
+
{
|
|
3920
|
+
id: "KPDT",
|
|
3921
|
+
name: "Pendleton",
|
|
3922
|
+
state: "OR",
|
|
3923
|
+
lat: 45.6906,
|
|
3924
|
+
lon: -118.8529,
|
|
3925
|
+
type: "WSR-88D"
|
|
3926
|
+
},
|
|
3927
|
+
{
|
|
3928
|
+
id: "KPOE",
|
|
3929
|
+
name: "Ft Polk",
|
|
3930
|
+
state: "LA",
|
|
3931
|
+
lat: 31.1557,
|
|
3932
|
+
lon: -92.9761,
|
|
3933
|
+
type: "WSR-88D"
|
|
3934
|
+
},
|
|
3935
|
+
{
|
|
3936
|
+
id: "KPUX",
|
|
3937
|
+
name: "Pueblo",
|
|
3938
|
+
state: "CO",
|
|
3939
|
+
lat: 38.4596,
|
|
3940
|
+
lon: -104.1813,
|
|
3941
|
+
type: "WSR-88D"
|
|
3942
|
+
},
|
|
3943
|
+
{
|
|
3944
|
+
id: "KRAX",
|
|
3945
|
+
name: "Raleigh Durham",
|
|
3946
|
+
state: "NC",
|
|
3947
|
+
lat: 35.6655,
|
|
3948
|
+
lon: -78.4898,
|
|
3949
|
+
type: "WSR-88D"
|
|
3950
|
+
},
|
|
3951
|
+
{
|
|
3952
|
+
id: "KRGX",
|
|
3953
|
+
name: "Reno",
|
|
3954
|
+
state: "NV",
|
|
3955
|
+
lat: 39.7541,
|
|
3956
|
+
lon: -119.462,
|
|
3957
|
+
type: "WSR-88D"
|
|
3958
|
+
},
|
|
3959
|
+
{
|
|
3960
|
+
id: "KRIW",
|
|
3961
|
+
name: "Riverton",
|
|
3962
|
+
state: "WY",
|
|
3963
|
+
lat: 43.0661,
|
|
3964
|
+
lon: -108.4773,
|
|
3965
|
+
type: "WSR-88D"
|
|
3966
|
+
},
|
|
3967
|
+
{
|
|
3968
|
+
id: "KRLX",
|
|
3969
|
+
name: "Charleston",
|
|
3970
|
+
state: "WV",
|
|
3971
|
+
lat: 38.3111,
|
|
3972
|
+
lon: -81.7229,
|
|
3973
|
+
type: "WSR-88D"
|
|
3974
|
+
},
|
|
3975
|
+
{
|
|
3976
|
+
id: "KRTX",
|
|
3977
|
+
name: "Portland",
|
|
3978
|
+
state: "OR",
|
|
3979
|
+
lat: 45.715,
|
|
3980
|
+
lon: -122.9649,
|
|
3981
|
+
type: "WSR-88D"
|
|
3982
|
+
},
|
|
3983
|
+
{
|
|
3984
|
+
id: "KSFX",
|
|
3985
|
+
name: "Pocatello",
|
|
3986
|
+
state: "ID",
|
|
3987
|
+
lat: 43.1056,
|
|
3988
|
+
lon: -112.6861,
|
|
3989
|
+
type: "WSR-88D"
|
|
3990
|
+
},
|
|
3991
|
+
{
|
|
3992
|
+
id: "KSGF",
|
|
3993
|
+
name: "Springfield",
|
|
3994
|
+
state: "MO",
|
|
3995
|
+
lat: 37.2352,
|
|
3996
|
+
lon: -93.4004,
|
|
3997
|
+
type: "WSR-88D"
|
|
3998
|
+
},
|
|
3999
|
+
{
|
|
4000
|
+
id: "KSHV",
|
|
4001
|
+
name: "Shreveport",
|
|
4002
|
+
state: "LA",
|
|
4003
|
+
lat: 32.4508,
|
|
4004
|
+
lon: -93.8413,
|
|
4005
|
+
type: "WSR-88D"
|
|
4006
|
+
},
|
|
4007
|
+
{
|
|
4008
|
+
id: "KSJT",
|
|
4009
|
+
name: "San Angelo",
|
|
4010
|
+
state: "TX",
|
|
4011
|
+
lat: 31.3713,
|
|
4012
|
+
lon: -100.4925,
|
|
4013
|
+
type: "WSR-88D"
|
|
4014
|
+
},
|
|
4015
|
+
{
|
|
4016
|
+
id: "KSOX",
|
|
4017
|
+
name: "Santa Ana Mountains",
|
|
4018
|
+
state: "CA",
|
|
4019
|
+
lat: 33.8177,
|
|
4020
|
+
lon: -117.636,
|
|
4021
|
+
type: "WSR-88D"
|
|
4022
|
+
},
|
|
4023
|
+
{
|
|
4024
|
+
id: "KSRX",
|
|
4025
|
+
name: "Ft Smith",
|
|
4026
|
+
state: "AR",
|
|
4027
|
+
lat: 35.2904,
|
|
4028
|
+
lon: -94.362,
|
|
4029
|
+
type: "WSR-88D"
|
|
4030
|
+
},
|
|
4031
|
+
{
|
|
4032
|
+
id: "KTBW",
|
|
4033
|
+
name: "Tampa",
|
|
4034
|
+
state: "FL",
|
|
4035
|
+
lat: 27.7055,
|
|
4036
|
+
lon: -82.4018,
|
|
4037
|
+
type: "WSR-88D"
|
|
4038
|
+
},
|
|
4039
|
+
{
|
|
4040
|
+
id: "KTFX",
|
|
4041
|
+
name: "Great Falls",
|
|
4042
|
+
state: "MT",
|
|
4043
|
+
lat: 47.4597,
|
|
4044
|
+
lon: -111.3854,
|
|
4045
|
+
type: "WSR-88D"
|
|
4046
|
+
},
|
|
4047
|
+
{
|
|
4048
|
+
id: "KTLH",
|
|
4049
|
+
name: "Tallahassee",
|
|
4050
|
+
state: "FL",
|
|
4051
|
+
lat: 30.3976,
|
|
4052
|
+
lon: -84.3289,
|
|
4053
|
+
type: "WSR-88D"
|
|
4054
|
+
},
|
|
4055
|
+
{
|
|
4056
|
+
id: "KTLX",
|
|
4057
|
+
name: "Oklahoma City",
|
|
4058
|
+
state: "OK",
|
|
4059
|
+
lat: 35.3334,
|
|
4060
|
+
lon: -97.2778,
|
|
4061
|
+
type: "WSR-88D"
|
|
4062
|
+
},
|
|
4063
|
+
{
|
|
4064
|
+
id: "KTWX",
|
|
4065
|
+
name: "Topeka",
|
|
4066
|
+
state: "KS",
|
|
4067
|
+
lat: 38.997,
|
|
4068
|
+
lon: -96.2326,
|
|
4069
|
+
type: "WSR-88D"
|
|
4070
|
+
},
|
|
4071
|
+
{
|
|
4072
|
+
id: "KTYX",
|
|
4073
|
+
name: "Ft Drum",
|
|
4074
|
+
state: "NY",
|
|
4075
|
+
lat: 43.7557,
|
|
4076
|
+
lon: -75.6798,
|
|
4077
|
+
type: "WSR-88D"
|
|
4078
|
+
},
|
|
4079
|
+
{
|
|
4080
|
+
id: "KUDX",
|
|
4081
|
+
name: "Rapid City",
|
|
4082
|
+
state: "SD",
|
|
4083
|
+
lat: 44.1249,
|
|
4084
|
+
lon: -102.8299,
|
|
4085
|
+
type: "WSR-88D"
|
|
4086
|
+
},
|
|
4087
|
+
{
|
|
4088
|
+
id: "KUEX",
|
|
4089
|
+
name: "Hastings",
|
|
4090
|
+
state: "NE",
|
|
4091
|
+
lat: 40.3209,
|
|
4092
|
+
lon: -98.442,
|
|
4093
|
+
type: "WSR-88D"
|
|
4094
|
+
},
|
|
4095
|
+
{
|
|
4096
|
+
id: "KVAX",
|
|
4097
|
+
name: "Moody Afb",
|
|
4098
|
+
state: "GA",
|
|
4099
|
+
lat: 30.8903,
|
|
4100
|
+
lon: -83.0017,
|
|
4101
|
+
type: "WSR-88D"
|
|
4102
|
+
},
|
|
4103
|
+
{
|
|
4104
|
+
id: "KVBX",
|
|
4105
|
+
name: "Vandenberg Afb",
|
|
4106
|
+
state: "CA",
|
|
4107
|
+
lat: 34.8383,
|
|
4108
|
+
lon: -120.3979,
|
|
4109
|
+
type: "WSR-88D"
|
|
4110
|
+
},
|
|
4111
|
+
{
|
|
4112
|
+
id: "KVNX",
|
|
4113
|
+
name: "Vance Afb",
|
|
4114
|
+
state: "OK",
|
|
4115
|
+
lat: 36.7406,
|
|
4116
|
+
lon: -98.1277,
|
|
4117
|
+
type: "WSR-88D"
|
|
4118
|
+
},
|
|
4119
|
+
{
|
|
4120
|
+
id: "KVTX",
|
|
4121
|
+
name: "Los Angeles",
|
|
4122
|
+
state: "CA",
|
|
4123
|
+
lat: 34.4117,
|
|
4124
|
+
lon: -119.1796,
|
|
4125
|
+
type: "WSR-88D"
|
|
4126
|
+
},
|
|
4127
|
+
{
|
|
4128
|
+
id: "KVWX",
|
|
4129
|
+
name: "Evansville",
|
|
4130
|
+
state: "IN",
|
|
4131
|
+
lat: 38.2604,
|
|
4132
|
+
lon: -87.7247,
|
|
4133
|
+
type: "WSR-88D"
|
|
4134
|
+
},
|
|
4135
|
+
{
|
|
4136
|
+
id: "KYUX",
|
|
4137
|
+
name: "Yuma",
|
|
4138
|
+
state: "AZ",
|
|
4139
|
+
lat: 32.4953,
|
|
4140
|
+
lon: -114.6567,
|
|
4141
|
+
type: "WSR-88D"
|
|
4142
|
+
},
|
|
4143
|
+
{
|
|
4144
|
+
id: "PABC",
|
|
4145
|
+
name: "Bethel Faa",
|
|
4146
|
+
state: "AK",
|
|
4147
|
+
lat: 60.7919,
|
|
4148
|
+
lon: -161.8764,
|
|
4149
|
+
type: "TDWR"
|
|
4150
|
+
},
|
|
4151
|
+
{
|
|
4152
|
+
id: "PACG",
|
|
4153
|
+
name: "Sitka",
|
|
4154
|
+
state: "AK",
|
|
4155
|
+
lat: 56.8526,
|
|
4156
|
+
lon: -135.5292,
|
|
4157
|
+
type: "TDWR"
|
|
4158
|
+
},
|
|
4159
|
+
{
|
|
4160
|
+
id: "PAEC",
|
|
4161
|
+
name: "Nome",
|
|
4162
|
+
state: "AK",
|
|
4163
|
+
lat: 64.5115,
|
|
4164
|
+
lon: -165.2954,
|
|
4165
|
+
type: "TDWR"
|
|
4166
|
+
},
|
|
4167
|
+
{
|
|
4168
|
+
id: "PAHG",
|
|
4169
|
+
name: "Anchorage",
|
|
4170
|
+
state: "AK",
|
|
4171
|
+
lat: 60.7258,
|
|
4172
|
+
lon: -151.3515,
|
|
4173
|
+
type: "TDWR"
|
|
4174
|
+
},
|
|
4175
|
+
{
|
|
4176
|
+
id: "PAKC",
|
|
4177
|
+
name: "King Salmon",
|
|
4178
|
+
state: "AK",
|
|
4179
|
+
lat: 58.6794,
|
|
4180
|
+
lon: -156.6298,
|
|
4181
|
+
type: "TDWR"
|
|
4182
|
+
},
|
|
4183
|
+
{
|
|
4184
|
+
id: "PAPD",
|
|
4185
|
+
name: "Fairbanks",
|
|
4186
|
+
state: "AK",
|
|
4187
|
+
lat: 65.0351,
|
|
4188
|
+
lon: -147.5017,
|
|
4189
|
+
type: "TDWR"
|
|
4190
|
+
},
|
|
4191
|
+
{
|
|
4192
|
+
id: "PGUA",
|
|
4193
|
+
name: "Andersen Afb Agana",
|
|
4194
|
+
state: "GU",
|
|
4195
|
+
lat: 13.4559,
|
|
4196
|
+
lon: 144.8111,
|
|
4197
|
+
type: "TDWR"
|
|
4198
|
+
},
|
|
4199
|
+
{
|
|
4200
|
+
id: "PHKI",
|
|
4201
|
+
name: "S Kauai",
|
|
4202
|
+
state: "HI",
|
|
4203
|
+
lat: 21.894,
|
|
4204
|
+
lon: -159.5525,
|
|
4205
|
+
type: "TDWR"
|
|
4206
|
+
},
|
|
4207
|
+
{
|
|
4208
|
+
id: "PHKM",
|
|
4209
|
+
name: "Kamuela",
|
|
4210
|
+
state: "HI",
|
|
4211
|
+
lat: 20.1253,
|
|
4212
|
+
lon: -155.7777,
|
|
4213
|
+
type: "TDWR"
|
|
4214
|
+
},
|
|
4215
|
+
{
|
|
4216
|
+
id: "PHMO",
|
|
4217
|
+
name: "Molokai",
|
|
4218
|
+
state: "HI",
|
|
4219
|
+
lat: 21.1328,
|
|
4220
|
+
lon: -157.1802,
|
|
4221
|
+
type: "TDWR"
|
|
4222
|
+
},
|
|
4223
|
+
{
|
|
4224
|
+
id: "PHWA",
|
|
4225
|
+
name: "S Shore",
|
|
4226
|
+
state: "HI",
|
|
4227
|
+
lat: 19.095,
|
|
4228
|
+
lon: -155.569,
|
|
4229
|
+
type: "TDWR"
|
|
4230
|
+
},
|
|
4231
|
+
{
|
|
4232
|
+
id: "RKJK",
|
|
4233
|
+
name: "Kunsan",
|
|
4234
|
+
state: "",
|
|
4235
|
+
lat: 35.9242,
|
|
4236
|
+
lon: 126.6221,
|
|
4237
|
+
type: "TDWR"
|
|
4238
|
+
},
|
|
4239
|
+
{
|
|
4240
|
+
id: "RKSG",
|
|
4241
|
+
name: "Camp Humphreys",
|
|
4242
|
+
state: "",
|
|
4243
|
+
lat: 37.2076,
|
|
4244
|
+
lon: 127.2859,
|
|
4245
|
+
type: "TDWR"
|
|
4246
|
+
},
|
|
4247
|
+
{
|
|
4248
|
+
id: "RODN",
|
|
4249
|
+
name: "Kadena",
|
|
4250
|
+
state: "",
|
|
4251
|
+
lat: 26.3077,
|
|
4252
|
+
lon: 127.9035,
|
|
4253
|
+
type: "TDWR"
|
|
4254
|
+
},
|
|
4255
|
+
{
|
|
4256
|
+
id: "TADW",
|
|
4257
|
+
name: "Andrews Afb",
|
|
4258
|
+
state: "MD",
|
|
4259
|
+
lat: 38.6954,
|
|
4260
|
+
lon: -76.845,
|
|
4261
|
+
type: "TDWR"
|
|
4262
|
+
},
|
|
4263
|
+
{
|
|
4264
|
+
id: "TATL",
|
|
4265
|
+
name: "Atlanta",
|
|
4266
|
+
state: "GA",
|
|
4267
|
+
lat: 33.6466,
|
|
4268
|
+
lon: -84.2621,
|
|
4269
|
+
type: "TDWR"
|
|
4270
|
+
},
|
|
4271
|
+
{
|
|
4272
|
+
id: "TBNA",
|
|
4273
|
+
name: "Nashville",
|
|
4274
|
+
state: "TN",
|
|
4275
|
+
lat: 35.9796,
|
|
4276
|
+
lon: -86.6617,
|
|
4277
|
+
type: "TDWR"
|
|
4278
|
+
},
|
|
4279
|
+
{
|
|
4280
|
+
id: "TBOS",
|
|
4281
|
+
name: "Boston",
|
|
4282
|
+
state: "MA",
|
|
4283
|
+
lat: 42.1583,
|
|
4284
|
+
lon: -70.9334,
|
|
4285
|
+
type: "TDWR"
|
|
4286
|
+
},
|
|
4287
|
+
{
|
|
4288
|
+
id: "TBWI",
|
|
4289
|
+
name: "Baltimore Washington",
|
|
4290
|
+
state: "MD",
|
|
4291
|
+
lat: 39.0896,
|
|
4292
|
+
lon: -76.6302,
|
|
4293
|
+
type: "TDWR"
|
|
4294
|
+
},
|
|
4295
|
+
{
|
|
4296
|
+
id: "TCLT",
|
|
4297
|
+
name: "Charlotte",
|
|
4298
|
+
state: "NC",
|
|
4299
|
+
lat: 35.3373,
|
|
4300
|
+
lon: -80.885,
|
|
4301
|
+
type: "TDWR"
|
|
4302
|
+
},
|
|
4303
|
+
{
|
|
4304
|
+
id: "TCMH",
|
|
4305
|
+
name: "Columbus",
|
|
4306
|
+
state: "OH",
|
|
4307
|
+
lat: 40.0056,
|
|
4308
|
+
lon: -82.7151,
|
|
4309
|
+
type: "TDWR"
|
|
4310
|
+
},
|
|
4311
|
+
{
|
|
4312
|
+
id: "TCVG",
|
|
4313
|
+
name: "Covington",
|
|
4314
|
+
state: "KY",
|
|
4315
|
+
lat: 38.8981,
|
|
4316
|
+
lon: -84.5799,
|
|
4317
|
+
type: "TDWR"
|
|
4318
|
+
},
|
|
4319
|
+
{
|
|
4320
|
+
id: "TDAL",
|
|
4321
|
+
name: "Dallas Love Fld",
|
|
4322
|
+
state: "TX",
|
|
4323
|
+
lat: 32.9258,
|
|
4324
|
+
lon: -96.9683,
|
|
4325
|
+
type: "TDWR"
|
|
4326
|
+
},
|
|
4327
|
+
{
|
|
4328
|
+
id: "TDAY",
|
|
4329
|
+
name: "Dayton",
|
|
4330
|
+
state: "OH",
|
|
4331
|
+
lat: 40.0221,
|
|
4332
|
+
lon: -84.1231,
|
|
4333
|
+
type: "TDWR"
|
|
4334
|
+
},
|
|
4335
|
+
{
|
|
4336
|
+
id: "TDCA",
|
|
4337
|
+
name: "Washington Natl",
|
|
4338
|
+
state: "MD",
|
|
4339
|
+
lat: 38.759,
|
|
4340
|
+
lon: -76.9617,
|
|
4341
|
+
type: "TDWR"
|
|
4342
|
+
},
|
|
4343
|
+
{
|
|
4344
|
+
id: "TDEN",
|
|
4345
|
+
name: "Denver",
|
|
4346
|
+
state: "CO",
|
|
4347
|
+
lat: 39.7275,
|
|
4348
|
+
lon: -104.5265,
|
|
4349
|
+
type: "TDWR"
|
|
4350
|
+
},
|
|
4351
|
+
{
|
|
4352
|
+
id: "TDFW",
|
|
4353
|
+
name: "Dallas Ft Worth",
|
|
4354
|
+
state: "TX",
|
|
4355
|
+
lat: 33.0648,
|
|
4356
|
+
lon: -96.9181,
|
|
4357
|
+
type: "TDWR"
|
|
4358
|
+
},
|
|
4359
|
+
{
|
|
4360
|
+
id: "TDTW",
|
|
4361
|
+
name: "Detroit",
|
|
4362
|
+
state: "MI",
|
|
4363
|
+
lat: 42.1113,
|
|
4364
|
+
lon: -83.515,
|
|
4365
|
+
type: "TDWR"
|
|
4366
|
+
},
|
|
4367
|
+
{
|
|
4368
|
+
id: "TEWR",
|
|
4369
|
+
name: "Newark",
|
|
4370
|
+
state: "NJ",
|
|
4371
|
+
lat: 40.5936,
|
|
4372
|
+
lon: -74.2703,
|
|
4373
|
+
type: "TDWR"
|
|
4374
|
+
},
|
|
4375
|
+
{
|
|
4376
|
+
id: "TFLL",
|
|
4377
|
+
name: "Ft Lauderdale",
|
|
4378
|
+
state: "FL",
|
|
4379
|
+
lat: 26.1432,
|
|
4380
|
+
lon: -80.344,
|
|
4381
|
+
type: "TDWR"
|
|
4382
|
+
},
|
|
4383
|
+
{
|
|
4384
|
+
id: "THOU",
|
|
4385
|
+
name: "Houston Hobby",
|
|
4386
|
+
state: "TX",
|
|
4387
|
+
lat: 29.5163,
|
|
4388
|
+
lon: -95.2416,
|
|
4389
|
+
type: "TDWR"
|
|
4390
|
+
},
|
|
4391
|
+
{
|
|
4392
|
+
id: "TIAD",
|
|
4393
|
+
name: "Washington Dulles",
|
|
4394
|
+
state: "VA",
|
|
4395
|
+
lat: 39.0838,
|
|
4396
|
+
lon: -77.5294,
|
|
4397
|
+
type: "TDWR"
|
|
4398
|
+
},
|
|
4399
|
+
{
|
|
4400
|
+
id: "TIAH",
|
|
4401
|
+
name: "Houston Intl",
|
|
4402
|
+
state: "TX",
|
|
4403
|
+
lat: 30.0649,
|
|
4404
|
+
lon: -95.5671,
|
|
4405
|
+
type: "TDWR"
|
|
4406
|
+
},
|
|
4407
|
+
{
|
|
4408
|
+
id: "TICH",
|
|
4409
|
+
name: "Wichita",
|
|
4410
|
+
state: "KS",
|
|
4411
|
+
lat: 37.5071,
|
|
4412
|
+
lon: -97.437,
|
|
4413
|
+
type: "TDWR"
|
|
4414
|
+
},
|
|
4415
|
+
{
|
|
4416
|
+
id: "TIDS",
|
|
4417
|
+
name: "Indianapolis",
|
|
4418
|
+
state: "IN",
|
|
4419
|
+
lat: 39.6372,
|
|
4420
|
+
lon: -86.4355,
|
|
4421
|
+
type: "TDWR"
|
|
4422
|
+
},
|
|
4423
|
+
{
|
|
4424
|
+
id: "TJFK",
|
|
4425
|
+
name: "Nyc Jfk",
|
|
4426
|
+
state: "NY",
|
|
4427
|
+
lat: 40.5889,
|
|
4428
|
+
lon: -73.8803,
|
|
4429
|
+
type: "TDWR"
|
|
4430
|
+
},
|
|
4431
|
+
{
|
|
4432
|
+
id: "TJUA",
|
|
4433
|
+
name: "San Juan",
|
|
4434
|
+
state: "PR",
|
|
4435
|
+
lat: 18.1156,
|
|
4436
|
+
lon: -66.0782,
|
|
4437
|
+
type: "TDWR"
|
|
4438
|
+
},
|
|
4439
|
+
{
|
|
4440
|
+
id: "TLAS",
|
|
4441
|
+
name: "Las Vegas",
|
|
4442
|
+
state: "NV",
|
|
4443
|
+
lat: 36.1436,
|
|
4444
|
+
lon: -115.0072,
|
|
4445
|
+
type: "TDWR"
|
|
4446
|
+
},
|
|
4447
|
+
{
|
|
4448
|
+
id: "TLVE",
|
|
4449
|
+
name: "Cleveland",
|
|
4450
|
+
state: "OH",
|
|
4451
|
+
lat: 41.2898,
|
|
4452
|
+
lon: -82.0076,
|
|
4453
|
+
type: "TDWR"
|
|
4454
|
+
},
|
|
4455
|
+
{
|
|
4456
|
+
id: "TMCI",
|
|
4457
|
+
name: "Kansas City",
|
|
4458
|
+
state: "MO",
|
|
4459
|
+
lat: 39.4985,
|
|
4460
|
+
lon: -94.742,
|
|
4461
|
+
type: "TDWR"
|
|
4462
|
+
},
|
|
4463
|
+
{
|
|
4464
|
+
id: "TMCO",
|
|
4465
|
+
name: "Orlando Intl",
|
|
4466
|
+
state: "FL",
|
|
4467
|
+
lat: 28.3437,
|
|
4468
|
+
lon: -81.3258,
|
|
4469
|
+
type: "TDWR"
|
|
4470
|
+
},
|
|
4471
|
+
{
|
|
4472
|
+
id: "TMDW",
|
|
4473
|
+
name: "Chicago Midway",
|
|
4474
|
+
state: "IL",
|
|
4475
|
+
lat: 41.6514,
|
|
4476
|
+
lon: -87.7296,
|
|
4477
|
+
type: "TDWR"
|
|
4478
|
+
},
|
|
4479
|
+
{
|
|
4480
|
+
id: "TMEM",
|
|
4481
|
+
name: "Memphis",
|
|
4482
|
+
state: "MS",
|
|
4483
|
+
lat: 34.8958,
|
|
4484
|
+
lon: -89.9927,
|
|
4485
|
+
type: "TDWR"
|
|
4486
|
+
},
|
|
4487
|
+
{
|
|
4488
|
+
id: "TMIA",
|
|
4489
|
+
name: "Miami",
|
|
4490
|
+
state: "FL",
|
|
4491
|
+
lat: 25.7575,
|
|
4492
|
+
lon: -80.4912,
|
|
4493
|
+
type: "TDWR"
|
|
4494
|
+
},
|
|
4495
|
+
{
|
|
4496
|
+
id: "TMKE",
|
|
4497
|
+
name: "Milwaukee",
|
|
4498
|
+
state: "WI",
|
|
4499
|
+
lat: 42.8196,
|
|
4500
|
+
lon: -88.0464,
|
|
4501
|
+
type: "TDWR"
|
|
4502
|
+
},
|
|
4503
|
+
{
|
|
4504
|
+
id: "TMSP",
|
|
4505
|
+
name: "Minneapolis",
|
|
4506
|
+
state: "MN",
|
|
4507
|
+
lat: 44.8714,
|
|
4508
|
+
lon: -92.9328,
|
|
4509
|
+
type: "TDWR"
|
|
4510
|
+
},
|
|
4511
|
+
{
|
|
4512
|
+
id: "TMSY",
|
|
4513
|
+
name: "New Orleans",
|
|
4514
|
+
state: "LA",
|
|
4515
|
+
lat: 30.0216,
|
|
4516
|
+
lon: -90.4032,
|
|
4517
|
+
type: "TDWR"
|
|
4518
|
+
},
|
|
4519
|
+
{
|
|
4520
|
+
id: "TOKC",
|
|
4521
|
+
name: "Norman Wfo",
|
|
4522
|
+
state: "OK",
|
|
4523
|
+
lat: 35.2761,
|
|
4524
|
+
lon: -97.5099,
|
|
4525
|
+
type: "TDWR"
|
|
4526
|
+
},
|
|
4527
|
+
{
|
|
4528
|
+
id: "TORD",
|
|
4529
|
+
name: "Chicago Ohare",
|
|
4530
|
+
state: "IL",
|
|
4531
|
+
lat: 41.7971,
|
|
4532
|
+
lon: -87.8583,
|
|
4533
|
+
type: "TDWR"
|
|
4534
|
+
},
|
|
4535
|
+
{
|
|
4536
|
+
id: "TPBI",
|
|
4537
|
+
name: "W Palm Beach",
|
|
4538
|
+
state: "FL",
|
|
4539
|
+
lat: 26.6879,
|
|
4540
|
+
lon: -80.2732,
|
|
4541
|
+
type: "TDWR"
|
|
4542
|
+
},
|
|
4543
|
+
{
|
|
4544
|
+
id: "TPHL",
|
|
4545
|
+
name: "Phila",
|
|
4546
|
+
state: "NJ",
|
|
4547
|
+
lat: 39.9492,
|
|
4548
|
+
lon: -75.07,
|
|
4549
|
+
type: "TDWR"
|
|
4550
|
+
},
|
|
4551
|
+
{
|
|
4552
|
+
id: "TPHX",
|
|
4553
|
+
name: "Phoenix",
|
|
4554
|
+
state: "AZ",
|
|
4555
|
+
lat: 33.4205,
|
|
4556
|
+
lon: -112.1629,
|
|
4557
|
+
type: "TDWR"
|
|
4558
|
+
},
|
|
4559
|
+
{
|
|
4560
|
+
id: "TPIT",
|
|
4561
|
+
name: "Pittsburgh",
|
|
4562
|
+
state: "PA",
|
|
4563
|
+
lat: 40.5013,
|
|
4564
|
+
lon: -80.4861,
|
|
4565
|
+
type: "TDWR"
|
|
4566
|
+
},
|
|
4567
|
+
{
|
|
4568
|
+
id: "TRDU",
|
|
4569
|
+
name: "Raleigh",
|
|
4570
|
+
state: "NC",
|
|
4571
|
+
lat: 36.0021,
|
|
4572
|
+
lon: -78.6973,
|
|
4573
|
+
type: "TDWR"
|
|
4574
|
+
},
|
|
4575
|
+
{
|
|
4576
|
+
id: "TSDF",
|
|
4577
|
+
name: "Louisville",
|
|
4578
|
+
state: "KY",
|
|
4579
|
+
lat: 38.0459,
|
|
4580
|
+
lon: -85.6105,
|
|
4581
|
+
type: "TDWR"
|
|
4582
|
+
},
|
|
4583
|
+
{
|
|
4584
|
+
id: "TSJU",
|
|
4585
|
+
name: "San Juan",
|
|
4586
|
+
state: "PR",
|
|
4587
|
+
lat: 18.474,
|
|
4588
|
+
lon: -66.1795,
|
|
4589
|
+
type: "TDWR"
|
|
4590
|
+
},
|
|
4591
|
+
{
|
|
4592
|
+
id: "TSLC",
|
|
4593
|
+
name: "Salt Lake City",
|
|
4594
|
+
state: "UT",
|
|
4595
|
+
lat: 40.9673,
|
|
4596
|
+
lon: -111.9298,
|
|
4597
|
+
type: "TDWR"
|
|
4598
|
+
},
|
|
4599
|
+
{
|
|
4600
|
+
id: "TSTL",
|
|
4601
|
+
name: "St Louis",
|
|
4602
|
+
state: "MO",
|
|
4603
|
+
lat: 38.8054,
|
|
4604
|
+
lon: -90.489,
|
|
4605
|
+
type: "TDWR"
|
|
4606
|
+
},
|
|
4607
|
+
{
|
|
4608
|
+
id: "TTPA",
|
|
4609
|
+
name: "Tampa",
|
|
4610
|
+
state: "FL",
|
|
4611
|
+
lat: 27.8595,
|
|
4612
|
+
lon: -82.5178,
|
|
4613
|
+
type: "TDWR"
|
|
4614
|
+
},
|
|
4615
|
+
{
|
|
4616
|
+
id: "TTUL",
|
|
4617
|
+
name: "Tulsa",
|
|
4618
|
+
state: "OK",
|
|
4619
|
+
lat: 36.0706,
|
|
4620
|
+
lon: -95.8263,
|
|
4621
|
+
type: "TDWR"
|
|
4622
|
+
},
|
|
4623
|
+
{
|
|
4624
|
+
id: "KCRI",
|
|
4625
|
+
name: "Norman Testbed",
|
|
4626
|
+
state: "OK",
|
|
4627
|
+
lat: 35.238,
|
|
4628
|
+
lon: -97.46,
|
|
4629
|
+
type: "TDWR"
|
|
4630
|
+
},
|
|
4631
|
+
{
|
|
4632
|
+
id: "FWLX",
|
|
4633
|
+
name: "WLX X-Band",
|
|
4634
|
+
state: "TN",
|
|
4635
|
+
lat: 35.254,
|
|
4636
|
+
lon: -87.325,
|
|
4637
|
+
type: "TDWR"
|
|
4638
|
+
},
|
|
4639
|
+
{
|
|
4640
|
+
id: "FUSA",
|
|
4641
|
+
name: "FUSA/Denton",
|
|
4642
|
+
state: "MD",
|
|
4643
|
+
lat: 38.86949,
|
|
4644
|
+
lon: -75.81616,
|
|
4645
|
+
type: "TDWR"
|
|
4646
|
+
},
|
|
4647
|
+
{
|
|
4648
|
+
id: "GAWX",
|
|
4649
|
+
name: "GAWX/Lawrenceville",
|
|
4650
|
+
state: "GA",
|
|
4651
|
+
lat: 33.98047,
|
|
4652
|
+
lon: -84.00345,
|
|
4653
|
+
type: "TDWR"
|
|
4654
|
+
},
|
|
4655
|
+
{
|
|
4656
|
+
id: "WILU",
|
|
4657
|
+
name: "Western Illinois University (WIU)",
|
|
4658
|
+
state: "IL",
|
|
4659
|
+
lat: 40.465,
|
|
4660
|
+
lon: -90.685,
|
|
4661
|
+
type: "TDWR"
|
|
4662
|
+
},
|
|
4663
|
+
{
|
|
4664
|
+
id: "KULM",
|
|
4665
|
+
name: "Monroe/ULM",
|
|
4666
|
+
state: "LA",
|
|
4667
|
+
lat: 32.529,
|
|
4668
|
+
lon: -92.012,
|
|
4669
|
+
type: "TDWR"
|
|
4670
|
+
},
|
|
4671
|
+
{
|
|
4672
|
+
id: "MZZU",
|
|
4673
|
+
name: "Columbia/Mizzou",
|
|
4674
|
+
state: "MO",
|
|
4675
|
+
lat: 38.906,
|
|
4676
|
+
lon: -92.269,
|
|
4677
|
+
type: "TDWR"
|
|
4678
|
+
},
|
|
4679
|
+
{
|
|
4680
|
+
id: "OP5R",
|
|
4681
|
+
name: "Fort Greely",
|
|
4682
|
+
state: "AK",
|
|
4683
|
+
lat: 63.922,
|
|
4684
|
+
lon: -145.833,
|
|
4685
|
+
type: "TDWR"
|
|
4686
|
+
}
|
|
4687
|
+
]
|
|
4688
|
+
};
|
|
4689
|
+
|
|
4690
|
+
// src/nexrad/nexradArchiveDiag.ts
|
|
4691
|
+
function redactApiKeyFromUrl(u) {
|
|
4692
|
+
return u.replace(/([?&])apiKey=[^&]*/gi, "$1apiKey=(redacted)");
|
|
4693
|
+
}
|
|
4694
|
+
function isReactNative() {
|
|
4695
|
+
const nav = globalThis.navigator;
|
|
4696
|
+
return nav?.product === "ReactNative";
|
|
4697
|
+
}
|
|
4698
|
+
function nexradArchiveDiag(phase, detail) {
|
|
4699
|
+
if (!isReactNative()) return;
|
|
4700
|
+
if (detail !== void 0) {
|
|
4701
|
+
console.warn(`[Aguacero][NEXRAD][archive] ${phase}`, detail);
|
|
4702
|
+
} else {
|
|
4703
|
+
console.warn(`[Aguacero][NEXRAD][archive] ${phase}`);
|
|
4704
|
+
}
|
|
4705
|
+
}
|
|
4706
|
+
|
|
2988
4707
|
// src/nexrad/loadNexradSites.ts
|
|
2989
4708
|
var sitesUrl = "/data/nexrad.json";
|
|
4709
|
+
function setNexradSitesJsonUrl(url) {
|
|
4710
|
+
sitesUrl = url || sitesUrl;
|
|
4711
|
+
}
|
|
4712
|
+
var SITES_FETCH_API_KEY = "";
|
|
4713
|
+
var SITES_FETCH_BUNDLE_ID = "";
|
|
4714
|
+
function setNexradSitesFetchAuth(apiKey, bundleId) {
|
|
4715
|
+
SITES_FETCH_API_KEY = apiKey || "";
|
|
4716
|
+
if (bundleId !== void 0) {
|
|
4717
|
+
SITES_FETCH_BUNDLE_ID = bundleId || "";
|
|
4718
|
+
}
|
|
4719
|
+
}
|
|
2990
4720
|
var nexradSitesPayloadPromise = null;
|
|
4721
|
+
function sitesFetchUrl() {
|
|
4722
|
+
if (!sitesUrl.startsWith("http") || !SITES_FETCH_API_KEY) {
|
|
4723
|
+
return sitesUrl;
|
|
4724
|
+
}
|
|
4725
|
+
const sep = sitesUrl.includes("?") ? "&" : "?";
|
|
4726
|
+
return `${sitesUrl}${sep}apiKey=${SITES_FETCH_API_KEY}`;
|
|
4727
|
+
}
|
|
4728
|
+
function sitesFetchHeaders() {
|
|
4729
|
+
if (!SITES_FETCH_API_KEY) {
|
|
4730
|
+
return void 0;
|
|
4731
|
+
}
|
|
4732
|
+
const headers = {
|
|
4733
|
+
"x-api-key": SITES_FETCH_API_KEY
|
|
4734
|
+
};
|
|
4735
|
+
const nav = globalThis.navigator;
|
|
4736
|
+
if (nav?.product === "ReactNative" && SITES_FETCH_BUNDLE_ID) {
|
|
4737
|
+
headers["x-app-identifier"] = SITES_FETCH_BUNDLE_ID;
|
|
4738
|
+
}
|
|
4739
|
+
return headers;
|
|
4740
|
+
}
|
|
4741
|
+
function embeddedSitesPayload() {
|
|
4742
|
+
return nexradSitesDefault_default;
|
|
4743
|
+
}
|
|
2991
4744
|
function loadNexradSitesPayload() {
|
|
2992
4745
|
if (nexradSitesPayloadPromise) {
|
|
2993
4746
|
return nexradSitesPayloadPromise;
|
|
2994
4747
|
}
|
|
2995
|
-
nexradSitesPayloadPromise =
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
4748
|
+
nexradSitesPayloadPromise = (async () => {
|
|
4749
|
+
const url = sitesFetchUrl();
|
|
4750
|
+
const headers = sitesFetchHeaders();
|
|
4751
|
+
const headerKeys = headers ? Object.keys(headers).join(",") : "";
|
|
4752
|
+
nexradArchiveDiag("sites.fetch.start", {
|
|
4753
|
+
canonicalUrl: sitesUrl,
|
|
4754
|
+
fetchUrl: redactApiKeyFromUrl(url),
|
|
4755
|
+
hasApiKeyQuery: url.includes("apiKey="),
|
|
4756
|
+
headerKeys: headerKeys || "(none)",
|
|
4757
|
+
apiKeyLen: SITES_FETCH_API_KEY.length,
|
|
4758
|
+
bundleIdLen: SITES_FETCH_BUNDLE_ID.length
|
|
4759
|
+
});
|
|
4760
|
+
try {
|
|
4761
|
+
const response = await fetch(url, headers ? { headers } : void 0);
|
|
4762
|
+
if (response.ok) {
|
|
4763
|
+
nexradArchiveDiag("sites.fetch.ok", {
|
|
4764
|
+
status: response.status,
|
|
4765
|
+
canonicalUrl: sitesUrl
|
|
4766
|
+
});
|
|
4767
|
+
return await response.json();
|
|
4768
|
+
}
|
|
4769
|
+
if (sitesUrl.startsWith("https://")) {
|
|
4770
|
+
console.warn(
|
|
4771
|
+
`[mapsgl] nexrad.json HTTP ${response.status} for ${sitesUrl} \u2014 using embedded site list`
|
|
4772
|
+
);
|
|
4773
|
+
nexradArchiveDiag("sites.fetch.fallbackEmbedded", {
|
|
4774
|
+
httpStatus: response.status,
|
|
4775
|
+
reason: "HTTPS non-OK \u2014 CloudFront may not host /data/nexrad.json; embedded list used",
|
|
4776
|
+
canonicalUrl: sitesUrl
|
|
4777
|
+
});
|
|
4778
|
+
return embeddedSitesPayload();
|
|
4779
|
+
}
|
|
4780
|
+
throw new Error(`nexrad.json fetch failed: HTTP ${response.status}`);
|
|
4781
|
+
} catch (error) {
|
|
4782
|
+
if (sitesUrl.startsWith("https://")) {
|
|
4783
|
+
console.warn("[mapsgl] nexrad.json load failed \u2014 using embedded site list:", error);
|
|
4784
|
+
nexradArchiveDiag("sites.fetch.catchFallbackEmbedded", {
|
|
4785
|
+
message: error instanceof Error ? error.message : String(error),
|
|
4786
|
+
canonicalUrl: sitesUrl
|
|
4787
|
+
});
|
|
4788
|
+
return embeddedSitesPayload();
|
|
4789
|
+
}
|
|
4790
|
+
console.error("[mapsgl] Could not load nexrad.json:", error);
|
|
4791
|
+
nexradSitesPayloadPromise = null;
|
|
4792
|
+
throw error;
|
|
4793
|
+
}
|
|
4794
|
+
})();
|
|
3003
4795
|
return nexradSitesPayloadPromise;
|
|
3004
4796
|
}
|
|
3005
4797
|
async function loadNexradSites() {
|
|
@@ -3010,15 +4802,872 @@ async function loadNexradSites() {
|
|
|
3010
4802
|
return [];
|
|
3011
4803
|
}
|
|
3012
4804
|
|
|
4805
|
+
// ../../node_modules/fzstd/esm/index.mjs
|
|
4806
|
+
var ab = ArrayBuffer;
|
|
4807
|
+
var u8 = Uint8Array;
|
|
4808
|
+
var u16 = Uint16Array;
|
|
4809
|
+
var i16 = Int16Array;
|
|
4810
|
+
var i32 = Int32Array;
|
|
4811
|
+
var slc = function(v, s, e) {
|
|
4812
|
+
if (u8.prototype.slice)
|
|
4813
|
+
return u8.prototype.slice.call(v, s, e);
|
|
4814
|
+
if (s == null || s < 0)
|
|
4815
|
+
s = 0;
|
|
4816
|
+
if (e == null || e > v.length)
|
|
4817
|
+
e = v.length;
|
|
4818
|
+
var n = new u8(e - s);
|
|
4819
|
+
n.set(v.subarray(s, e));
|
|
4820
|
+
return n;
|
|
4821
|
+
};
|
|
4822
|
+
var fill = function(v, n, s, e) {
|
|
4823
|
+
if (u8.prototype.fill)
|
|
4824
|
+
return u8.prototype.fill.call(v, n, s, e);
|
|
4825
|
+
if (s == null || s < 0)
|
|
4826
|
+
s = 0;
|
|
4827
|
+
if (e == null || e > v.length)
|
|
4828
|
+
e = v.length;
|
|
4829
|
+
for (; s < e; ++s)
|
|
4830
|
+
v[s] = n;
|
|
4831
|
+
return v;
|
|
4832
|
+
};
|
|
4833
|
+
var cpw = function(v, t, s, e) {
|
|
4834
|
+
if (u8.prototype.copyWithin)
|
|
4835
|
+
return u8.prototype.copyWithin.call(v, t, s, e);
|
|
4836
|
+
if (s == null || s < 0)
|
|
4837
|
+
s = 0;
|
|
4838
|
+
if (e == null || e > v.length)
|
|
4839
|
+
e = v.length;
|
|
4840
|
+
while (s < e) {
|
|
4841
|
+
v[t++] = v[s++];
|
|
4842
|
+
}
|
|
4843
|
+
};
|
|
4844
|
+
var ec = [
|
|
4845
|
+
"invalid zstd data",
|
|
4846
|
+
"window size too large (>2046MB)",
|
|
4847
|
+
"invalid block type",
|
|
4848
|
+
"FSE accuracy too high",
|
|
4849
|
+
"match distance too far back",
|
|
4850
|
+
"unexpected EOF"
|
|
4851
|
+
];
|
|
4852
|
+
var err = function(ind, msg, nt) {
|
|
4853
|
+
var e = new Error(msg || ec[ind]);
|
|
4854
|
+
e.code = ind;
|
|
4855
|
+
if (Error.captureStackTrace)
|
|
4856
|
+
Error.captureStackTrace(e, err);
|
|
4857
|
+
if (!nt)
|
|
4858
|
+
throw e;
|
|
4859
|
+
return e;
|
|
4860
|
+
};
|
|
4861
|
+
var rb = function(d, b, n) {
|
|
4862
|
+
var i = 0, o = 0;
|
|
4863
|
+
for (; i < n; ++i)
|
|
4864
|
+
o |= d[b++] << (i << 3);
|
|
4865
|
+
return o;
|
|
4866
|
+
};
|
|
4867
|
+
var b4 = function(d, b) {
|
|
4868
|
+
return (d[b] | d[b + 1] << 8 | d[b + 2] << 16 | d[b + 3] << 24) >>> 0;
|
|
4869
|
+
};
|
|
4870
|
+
var rzfh = function(dat, w) {
|
|
4871
|
+
var n3 = dat[0] | dat[1] << 8 | dat[2] << 16;
|
|
4872
|
+
if (n3 == 3126568 && dat[3] == 253) {
|
|
4873
|
+
var flg = dat[4];
|
|
4874
|
+
var ss = flg >> 5 & 1, cc = flg >> 2 & 1, df = flg & 3, fcf = flg >> 6;
|
|
4875
|
+
if (flg & 8)
|
|
4876
|
+
err(0);
|
|
4877
|
+
var bt = 6 - ss;
|
|
4878
|
+
var db = df == 3 ? 4 : df;
|
|
4879
|
+
var di = rb(dat, bt, db);
|
|
4880
|
+
bt += db;
|
|
4881
|
+
var fsb = fcf ? 1 << fcf : ss;
|
|
4882
|
+
var fss = rb(dat, bt, fsb) + (fcf == 1 && 256);
|
|
4883
|
+
var ws = fss;
|
|
4884
|
+
if (!ss) {
|
|
4885
|
+
var wb = 1 << 10 + (dat[5] >> 3);
|
|
4886
|
+
ws = wb + (wb >> 3) * (dat[5] & 7);
|
|
4887
|
+
}
|
|
4888
|
+
if (ws > 2145386496)
|
|
4889
|
+
err(1);
|
|
4890
|
+
var buf = new u8((w == 1 ? fss || ws : w ? 0 : ws) + 12);
|
|
4891
|
+
buf[0] = 1, buf[4] = 4, buf[8] = 8;
|
|
4892
|
+
return {
|
|
4893
|
+
b: bt + fsb,
|
|
4894
|
+
y: 0,
|
|
4895
|
+
l: 0,
|
|
4896
|
+
d: di,
|
|
4897
|
+
w: w && w != 1 ? w : buf.subarray(12),
|
|
4898
|
+
e: ws,
|
|
4899
|
+
o: new i32(buf.buffer, 0, 3),
|
|
4900
|
+
u: fss,
|
|
4901
|
+
c: cc,
|
|
4902
|
+
m: Math.min(131072, ws)
|
|
4903
|
+
};
|
|
4904
|
+
} else if ((n3 >> 4 | dat[3] << 20) == 25481893) {
|
|
4905
|
+
return b4(dat, 4) + 8;
|
|
4906
|
+
}
|
|
4907
|
+
err(0);
|
|
4908
|
+
};
|
|
4909
|
+
var msb = function(val) {
|
|
4910
|
+
var bits = 0;
|
|
4911
|
+
for (; 1 << bits <= val; ++bits)
|
|
4912
|
+
;
|
|
4913
|
+
return bits - 1;
|
|
4914
|
+
};
|
|
4915
|
+
var rfse = function(dat, bt, mal) {
|
|
4916
|
+
var tpos = (bt << 3) + 4;
|
|
4917
|
+
var al = (dat[bt] & 15) + 5;
|
|
4918
|
+
if (al > mal)
|
|
4919
|
+
err(3);
|
|
4920
|
+
var sz = 1 << al;
|
|
4921
|
+
var probs = sz, sym = -1, re = -1, i = -1, ht = sz;
|
|
4922
|
+
var buf = new ab(512 + (sz << 2));
|
|
4923
|
+
var freq = new i16(buf, 0, 256);
|
|
4924
|
+
var dstate = new u16(buf, 0, 256);
|
|
4925
|
+
var nstate = new u16(buf, 512, sz);
|
|
4926
|
+
var bb1 = 512 + (sz << 1);
|
|
4927
|
+
var syms = new u8(buf, bb1, sz);
|
|
4928
|
+
var nbits = new u8(buf, bb1 + sz);
|
|
4929
|
+
while (sym < 255 && probs > 0) {
|
|
4930
|
+
var bits = msb(probs + 1);
|
|
4931
|
+
var cbt = tpos >> 3;
|
|
4932
|
+
var msk = (1 << bits + 1) - 1;
|
|
4933
|
+
var val = (dat[cbt] | dat[cbt + 1] << 8 | dat[cbt + 2] << 16) >> (tpos & 7) & msk;
|
|
4934
|
+
var msk1fb = (1 << bits) - 1;
|
|
4935
|
+
var msv = msk - probs - 1;
|
|
4936
|
+
var sval = val & msk1fb;
|
|
4937
|
+
if (sval < msv)
|
|
4938
|
+
tpos += bits, val = sval;
|
|
4939
|
+
else {
|
|
4940
|
+
tpos += bits + 1;
|
|
4941
|
+
if (val > msk1fb)
|
|
4942
|
+
val -= msv;
|
|
4943
|
+
}
|
|
4944
|
+
freq[++sym] = --val;
|
|
4945
|
+
if (val == -1) {
|
|
4946
|
+
probs += val;
|
|
4947
|
+
syms[--ht] = sym;
|
|
4948
|
+
} else
|
|
4949
|
+
probs -= val;
|
|
4950
|
+
if (!val) {
|
|
4951
|
+
do {
|
|
4952
|
+
var rbt = tpos >> 3;
|
|
4953
|
+
re = (dat[rbt] | dat[rbt + 1] << 8) >> (tpos & 7) & 3;
|
|
4954
|
+
tpos += 2;
|
|
4955
|
+
sym += re;
|
|
4956
|
+
} while (re == 3);
|
|
4957
|
+
}
|
|
4958
|
+
}
|
|
4959
|
+
if (sym > 255 || probs)
|
|
4960
|
+
err(0);
|
|
4961
|
+
var sympos = 0;
|
|
4962
|
+
var sstep = (sz >> 1) + (sz >> 3) + 3;
|
|
4963
|
+
var smask = sz - 1;
|
|
4964
|
+
for (var s = 0; s <= sym; ++s) {
|
|
4965
|
+
var sf = freq[s];
|
|
4966
|
+
if (sf < 1) {
|
|
4967
|
+
dstate[s] = -sf;
|
|
4968
|
+
continue;
|
|
4969
|
+
}
|
|
4970
|
+
for (i = 0; i < sf; ++i) {
|
|
4971
|
+
syms[sympos] = s;
|
|
4972
|
+
do {
|
|
4973
|
+
sympos = sympos + sstep & smask;
|
|
4974
|
+
} while (sympos >= ht);
|
|
4975
|
+
}
|
|
4976
|
+
}
|
|
4977
|
+
if (sympos)
|
|
4978
|
+
err(0);
|
|
4979
|
+
for (i = 0; i < sz; ++i) {
|
|
4980
|
+
var ns = dstate[syms[i]]++;
|
|
4981
|
+
var nb = nbits[i] = al - msb(ns);
|
|
4982
|
+
nstate[i] = (ns << nb) - sz;
|
|
4983
|
+
}
|
|
4984
|
+
return [tpos + 7 >> 3, {
|
|
4985
|
+
b: al,
|
|
4986
|
+
s: syms,
|
|
4987
|
+
n: nbits,
|
|
4988
|
+
t: nstate
|
|
4989
|
+
}];
|
|
4990
|
+
};
|
|
4991
|
+
var rhu = function(dat, bt) {
|
|
4992
|
+
var i = 0, wc = -1;
|
|
4993
|
+
var buf = new u8(292), hb = dat[bt];
|
|
4994
|
+
var hw = buf.subarray(0, 256);
|
|
4995
|
+
var rc = buf.subarray(256, 268);
|
|
4996
|
+
var ri = new u16(buf.buffer, 268);
|
|
4997
|
+
if (hb < 128) {
|
|
4998
|
+
var _a = rfse(dat, bt + 1, 6), ebt = _a[0], fdt = _a[1];
|
|
4999
|
+
bt += hb;
|
|
5000
|
+
var epos = ebt << 3;
|
|
5001
|
+
var lb = dat[bt];
|
|
5002
|
+
if (!lb)
|
|
5003
|
+
err(0);
|
|
5004
|
+
var st1 = 0, st2 = 0, btr1 = fdt.b, btr2 = btr1;
|
|
5005
|
+
var fpos = (++bt << 3) - 8 + msb(lb);
|
|
5006
|
+
for (; ; ) {
|
|
5007
|
+
fpos -= btr1;
|
|
5008
|
+
if (fpos < epos)
|
|
5009
|
+
break;
|
|
5010
|
+
var cbt = fpos >> 3;
|
|
5011
|
+
st1 += (dat[cbt] | dat[cbt + 1] << 8) >> (fpos & 7) & (1 << btr1) - 1;
|
|
5012
|
+
hw[++wc] = fdt.s[st1];
|
|
5013
|
+
fpos -= btr2;
|
|
5014
|
+
if (fpos < epos)
|
|
5015
|
+
break;
|
|
5016
|
+
cbt = fpos >> 3;
|
|
5017
|
+
st2 += (dat[cbt] | dat[cbt + 1] << 8) >> (fpos & 7) & (1 << btr2) - 1;
|
|
5018
|
+
hw[++wc] = fdt.s[st2];
|
|
5019
|
+
btr1 = fdt.n[st1];
|
|
5020
|
+
st1 = fdt.t[st1];
|
|
5021
|
+
btr2 = fdt.n[st2];
|
|
5022
|
+
st2 = fdt.t[st2];
|
|
5023
|
+
}
|
|
5024
|
+
if (++wc > 255)
|
|
5025
|
+
err(0);
|
|
5026
|
+
} else {
|
|
5027
|
+
wc = hb - 127;
|
|
5028
|
+
for (; i < wc; i += 2) {
|
|
5029
|
+
var byte = dat[++bt];
|
|
5030
|
+
hw[i] = byte >> 4;
|
|
5031
|
+
hw[i + 1] = byte & 15;
|
|
5032
|
+
}
|
|
5033
|
+
++bt;
|
|
5034
|
+
}
|
|
5035
|
+
var wes = 0;
|
|
5036
|
+
for (i = 0; i < wc; ++i) {
|
|
5037
|
+
var wt = hw[i];
|
|
5038
|
+
if (wt > 11)
|
|
5039
|
+
err(0);
|
|
5040
|
+
wes += wt && 1 << wt - 1;
|
|
5041
|
+
}
|
|
5042
|
+
var mb = msb(wes) + 1;
|
|
5043
|
+
var ts = 1 << mb;
|
|
5044
|
+
var rem = ts - wes;
|
|
5045
|
+
if (rem & rem - 1)
|
|
5046
|
+
err(0);
|
|
5047
|
+
hw[wc++] = msb(rem) + 1;
|
|
5048
|
+
for (i = 0; i < wc; ++i) {
|
|
5049
|
+
var wt = hw[i];
|
|
5050
|
+
++rc[hw[i] = wt && mb + 1 - wt];
|
|
5051
|
+
}
|
|
5052
|
+
var hbuf = new u8(ts << 1);
|
|
5053
|
+
var syms = hbuf.subarray(0, ts), nb = hbuf.subarray(ts);
|
|
5054
|
+
ri[mb] = 0;
|
|
5055
|
+
for (i = mb; i > 0; --i) {
|
|
5056
|
+
var pv = ri[i];
|
|
5057
|
+
fill(nb, i, pv, ri[i - 1] = pv + rc[i] * (1 << mb - i));
|
|
5058
|
+
}
|
|
5059
|
+
if (ri[0] != ts)
|
|
5060
|
+
err(0);
|
|
5061
|
+
for (i = 0; i < wc; ++i) {
|
|
5062
|
+
var bits = hw[i];
|
|
5063
|
+
if (bits) {
|
|
5064
|
+
var code = ri[bits];
|
|
5065
|
+
fill(syms, i, code, ri[bits] = code + (1 << mb - bits));
|
|
5066
|
+
}
|
|
5067
|
+
}
|
|
5068
|
+
return [bt, {
|
|
5069
|
+
n: nb,
|
|
5070
|
+
b: mb,
|
|
5071
|
+
s: syms
|
|
5072
|
+
}];
|
|
5073
|
+
};
|
|
5074
|
+
var dllt = rfse(/* @__PURE__ */ new u8([
|
|
5075
|
+
81,
|
|
5076
|
+
16,
|
|
5077
|
+
99,
|
|
5078
|
+
140,
|
|
5079
|
+
49,
|
|
5080
|
+
198,
|
|
5081
|
+
24,
|
|
5082
|
+
99,
|
|
5083
|
+
12,
|
|
5084
|
+
33,
|
|
5085
|
+
196,
|
|
5086
|
+
24,
|
|
5087
|
+
99,
|
|
5088
|
+
102,
|
|
5089
|
+
102,
|
|
5090
|
+
134,
|
|
5091
|
+
70,
|
|
5092
|
+
146,
|
|
5093
|
+
4
|
|
5094
|
+
]), 0, 6)[1];
|
|
5095
|
+
var dmlt = rfse(/* @__PURE__ */ new u8([
|
|
5096
|
+
33,
|
|
5097
|
+
20,
|
|
5098
|
+
196,
|
|
5099
|
+
24,
|
|
5100
|
+
99,
|
|
5101
|
+
140,
|
|
5102
|
+
33,
|
|
5103
|
+
132,
|
|
5104
|
+
16,
|
|
5105
|
+
66,
|
|
5106
|
+
8,
|
|
5107
|
+
33,
|
|
5108
|
+
132,
|
|
5109
|
+
16,
|
|
5110
|
+
66,
|
|
5111
|
+
8,
|
|
5112
|
+
33,
|
|
5113
|
+
68,
|
|
5114
|
+
68,
|
|
5115
|
+
68,
|
|
5116
|
+
68,
|
|
5117
|
+
68,
|
|
5118
|
+
68,
|
|
5119
|
+
68,
|
|
5120
|
+
68,
|
|
5121
|
+
36,
|
|
5122
|
+
9
|
|
5123
|
+
]), 0, 6)[1];
|
|
5124
|
+
var doct = rfse(/* @__PURE__ */ new u8([
|
|
5125
|
+
32,
|
|
5126
|
+
132,
|
|
5127
|
+
16,
|
|
5128
|
+
66,
|
|
5129
|
+
102,
|
|
5130
|
+
70,
|
|
5131
|
+
68,
|
|
5132
|
+
68,
|
|
5133
|
+
68,
|
|
5134
|
+
68,
|
|
5135
|
+
36,
|
|
5136
|
+
73,
|
|
5137
|
+
2
|
|
5138
|
+
]), 0, 5)[1];
|
|
5139
|
+
var b2bl = function(b, s) {
|
|
5140
|
+
var len = b.length, bl = new i32(len);
|
|
5141
|
+
for (var i = 0; i < len; ++i) {
|
|
5142
|
+
bl[i] = s;
|
|
5143
|
+
s += 1 << b[i];
|
|
5144
|
+
}
|
|
5145
|
+
return bl;
|
|
5146
|
+
};
|
|
5147
|
+
var llb = /* @__PURE__ */ new u8((/* @__PURE__ */ new i32([
|
|
5148
|
+
0,
|
|
5149
|
+
0,
|
|
5150
|
+
0,
|
|
5151
|
+
0,
|
|
5152
|
+
16843009,
|
|
5153
|
+
50528770,
|
|
5154
|
+
134678020,
|
|
5155
|
+
202050057,
|
|
5156
|
+
269422093
|
|
5157
|
+
])).buffer, 0, 36);
|
|
5158
|
+
var llbl = /* @__PURE__ */ b2bl(llb, 0);
|
|
5159
|
+
var mlb = /* @__PURE__ */ new u8((/* @__PURE__ */ new i32([
|
|
5160
|
+
0,
|
|
5161
|
+
0,
|
|
5162
|
+
0,
|
|
5163
|
+
0,
|
|
5164
|
+
0,
|
|
5165
|
+
0,
|
|
5166
|
+
0,
|
|
5167
|
+
0,
|
|
5168
|
+
16843009,
|
|
5169
|
+
50528770,
|
|
5170
|
+
117769220,
|
|
5171
|
+
185207048,
|
|
5172
|
+
252579084,
|
|
5173
|
+
16
|
|
5174
|
+
])).buffer, 0, 53);
|
|
5175
|
+
var mlbl = /* @__PURE__ */ b2bl(mlb, 3);
|
|
5176
|
+
var dhu = function(dat, out, hu) {
|
|
5177
|
+
var len = dat.length, ss = out.length, lb = dat[len - 1], msk = (1 << hu.b) - 1, eb = -hu.b;
|
|
5178
|
+
if (!lb)
|
|
5179
|
+
err(0);
|
|
5180
|
+
var st = 0, btr = hu.b, pos = (len << 3) - 8 + msb(lb) - btr, i = -1;
|
|
5181
|
+
for (; pos > eb && i < ss; ) {
|
|
5182
|
+
var cbt = pos >> 3;
|
|
5183
|
+
var val = (dat[cbt] | dat[cbt + 1] << 8 | dat[cbt + 2] << 16) >> (pos & 7);
|
|
5184
|
+
st = (st << btr | val) & msk;
|
|
5185
|
+
out[++i] = hu.s[st];
|
|
5186
|
+
pos -= btr = hu.n[st];
|
|
5187
|
+
}
|
|
5188
|
+
if (pos != eb || i + 1 != ss)
|
|
5189
|
+
err(0);
|
|
5190
|
+
};
|
|
5191
|
+
var dhu4 = function(dat, out, hu) {
|
|
5192
|
+
var bt = 6;
|
|
5193
|
+
var ss = out.length, sz1 = ss + 3 >> 2, sz2 = sz1 << 1, sz3 = sz1 + sz2;
|
|
5194
|
+
dhu(dat.subarray(bt, bt += dat[0] | dat[1] << 8), out.subarray(0, sz1), hu);
|
|
5195
|
+
dhu(dat.subarray(bt, bt += dat[2] | dat[3] << 8), out.subarray(sz1, sz2), hu);
|
|
5196
|
+
dhu(dat.subarray(bt, bt += dat[4] | dat[5] << 8), out.subarray(sz2, sz3), hu);
|
|
5197
|
+
dhu(dat.subarray(bt), out.subarray(sz3), hu);
|
|
5198
|
+
};
|
|
5199
|
+
var rzb = function(dat, st, out) {
|
|
5200
|
+
var _a;
|
|
5201
|
+
var bt = st.b;
|
|
5202
|
+
var b0 = dat[bt], btype = b0 >> 1 & 3;
|
|
5203
|
+
st.l = b0 & 1;
|
|
5204
|
+
var sz = b0 >> 3 | dat[bt + 1] << 5 | dat[bt + 2] << 13;
|
|
5205
|
+
var ebt = (bt += 3) + sz;
|
|
5206
|
+
if (btype == 1) {
|
|
5207
|
+
if (bt >= dat.length)
|
|
5208
|
+
return;
|
|
5209
|
+
st.b = bt + 1;
|
|
5210
|
+
if (out) {
|
|
5211
|
+
fill(out, dat[bt], st.y, st.y += sz);
|
|
5212
|
+
return out;
|
|
5213
|
+
}
|
|
5214
|
+
return fill(new u8(sz), dat[bt]);
|
|
5215
|
+
}
|
|
5216
|
+
if (ebt > dat.length)
|
|
5217
|
+
return;
|
|
5218
|
+
if (btype == 0) {
|
|
5219
|
+
st.b = ebt;
|
|
5220
|
+
if (out) {
|
|
5221
|
+
out.set(dat.subarray(bt, ebt), st.y);
|
|
5222
|
+
st.y += sz;
|
|
5223
|
+
return out;
|
|
5224
|
+
}
|
|
5225
|
+
return slc(dat, bt, ebt);
|
|
5226
|
+
}
|
|
5227
|
+
if (btype == 2) {
|
|
5228
|
+
var b3 = dat[bt], lbt = b3 & 3, sf = b3 >> 2 & 3;
|
|
5229
|
+
var lss = b3 >> 4, lcs = 0, s4 = 0;
|
|
5230
|
+
if (lbt < 2) {
|
|
5231
|
+
if (sf & 1)
|
|
5232
|
+
lss |= dat[++bt] << 4 | (sf & 2 && dat[++bt] << 12);
|
|
5233
|
+
else
|
|
5234
|
+
lss = b3 >> 3;
|
|
5235
|
+
} else {
|
|
5236
|
+
s4 = sf;
|
|
5237
|
+
if (sf < 2)
|
|
5238
|
+
lss |= (dat[++bt] & 63) << 4, lcs = dat[bt] >> 6 | dat[++bt] << 2;
|
|
5239
|
+
else if (sf == 2)
|
|
5240
|
+
lss |= dat[++bt] << 4 | (dat[++bt] & 3) << 12, lcs = dat[bt] >> 2 | dat[++bt] << 6;
|
|
5241
|
+
else
|
|
5242
|
+
lss |= dat[++bt] << 4 | (dat[++bt] & 63) << 12, lcs = dat[bt] >> 6 | dat[++bt] << 2 | dat[++bt] << 10;
|
|
5243
|
+
}
|
|
5244
|
+
++bt;
|
|
5245
|
+
var buf = out ? out.subarray(st.y, st.y + st.m) : new u8(st.m);
|
|
5246
|
+
var spl = buf.length - lss;
|
|
5247
|
+
if (lbt == 0)
|
|
5248
|
+
buf.set(dat.subarray(bt, bt += lss), spl);
|
|
5249
|
+
else if (lbt == 1)
|
|
5250
|
+
fill(buf, dat[bt++], spl);
|
|
5251
|
+
else {
|
|
5252
|
+
var hu = st.h;
|
|
5253
|
+
if (lbt == 2) {
|
|
5254
|
+
var hud = rhu(dat, bt);
|
|
5255
|
+
lcs += bt - (bt = hud[0]);
|
|
5256
|
+
st.h = hu = hud[1];
|
|
5257
|
+
} else if (!hu)
|
|
5258
|
+
err(0);
|
|
5259
|
+
(s4 ? dhu4 : dhu)(dat.subarray(bt, bt += lcs), buf.subarray(spl), hu);
|
|
5260
|
+
}
|
|
5261
|
+
var ns = dat[bt++];
|
|
5262
|
+
if (ns) {
|
|
5263
|
+
if (ns == 255)
|
|
5264
|
+
ns = (dat[bt++] | dat[bt++] << 8) + 32512;
|
|
5265
|
+
else if (ns > 127)
|
|
5266
|
+
ns = ns - 128 << 8 | dat[bt++];
|
|
5267
|
+
var scm = dat[bt++];
|
|
5268
|
+
if (scm & 3)
|
|
5269
|
+
err(0);
|
|
5270
|
+
var dts = [dmlt, doct, dllt];
|
|
5271
|
+
for (var i = 2; i > -1; --i) {
|
|
5272
|
+
var md = scm >> (i << 1) + 2 & 3;
|
|
5273
|
+
if (md == 1) {
|
|
5274
|
+
var rbuf = new u8([0, 0, dat[bt++]]);
|
|
5275
|
+
dts[i] = {
|
|
5276
|
+
s: rbuf.subarray(2, 3),
|
|
5277
|
+
n: rbuf.subarray(0, 1),
|
|
5278
|
+
t: new u16(rbuf.buffer, 0, 1),
|
|
5279
|
+
b: 0
|
|
5280
|
+
};
|
|
5281
|
+
} else if (md == 2) {
|
|
5282
|
+
_a = rfse(dat, bt, 9 - (i & 1)), bt = _a[0], dts[i] = _a[1];
|
|
5283
|
+
} else if (md == 3) {
|
|
5284
|
+
if (!st.t)
|
|
5285
|
+
err(0);
|
|
5286
|
+
dts[i] = st.t[i];
|
|
5287
|
+
}
|
|
5288
|
+
}
|
|
5289
|
+
var _b = st.t = dts, mlt = _b[0], oct = _b[1], llt = _b[2];
|
|
5290
|
+
var lb = dat[ebt - 1];
|
|
5291
|
+
if (!lb)
|
|
5292
|
+
err(0);
|
|
5293
|
+
var spos = (ebt << 3) - 8 + msb(lb) - llt.b, cbt = spos >> 3, oubt = 0;
|
|
5294
|
+
var lst = (dat[cbt] | dat[cbt + 1] << 8) >> (spos & 7) & (1 << llt.b) - 1;
|
|
5295
|
+
cbt = (spos -= oct.b) >> 3;
|
|
5296
|
+
var ost = (dat[cbt] | dat[cbt + 1] << 8) >> (spos & 7) & (1 << oct.b) - 1;
|
|
5297
|
+
cbt = (spos -= mlt.b) >> 3;
|
|
5298
|
+
var mst = (dat[cbt] | dat[cbt + 1] << 8) >> (spos & 7) & (1 << mlt.b) - 1;
|
|
5299
|
+
for (++ns; --ns; ) {
|
|
5300
|
+
var llc = llt.s[lst];
|
|
5301
|
+
var lbtr = llt.n[lst];
|
|
5302
|
+
var mlc = mlt.s[mst];
|
|
5303
|
+
var mbtr = mlt.n[mst];
|
|
5304
|
+
var ofc = oct.s[ost];
|
|
5305
|
+
var obtr = oct.n[ost];
|
|
5306
|
+
cbt = (spos -= ofc) >> 3;
|
|
5307
|
+
var ofp = 1 << ofc;
|
|
5308
|
+
var off = ofp + ((dat[cbt] | dat[cbt + 1] << 8 | dat[cbt + 2] << 16 | dat[cbt + 3] << 24) >>> (spos & 7) & ofp - 1);
|
|
5309
|
+
cbt = (spos -= mlb[mlc]) >> 3;
|
|
5310
|
+
var ml = mlbl[mlc] + ((dat[cbt] | dat[cbt + 1] << 8 | dat[cbt + 2] << 16) >> (spos & 7) & (1 << mlb[mlc]) - 1);
|
|
5311
|
+
cbt = (spos -= llb[llc]) >> 3;
|
|
5312
|
+
var ll = llbl[llc] + ((dat[cbt] | dat[cbt + 1] << 8 | dat[cbt + 2] << 16) >> (spos & 7) & (1 << llb[llc]) - 1);
|
|
5313
|
+
cbt = (spos -= lbtr) >> 3;
|
|
5314
|
+
lst = llt.t[lst] + ((dat[cbt] | dat[cbt + 1] << 8) >> (spos & 7) & (1 << lbtr) - 1);
|
|
5315
|
+
cbt = (spos -= mbtr) >> 3;
|
|
5316
|
+
mst = mlt.t[mst] + ((dat[cbt] | dat[cbt + 1] << 8) >> (spos & 7) & (1 << mbtr) - 1);
|
|
5317
|
+
cbt = (spos -= obtr) >> 3;
|
|
5318
|
+
ost = oct.t[ost] + ((dat[cbt] | dat[cbt + 1] << 8) >> (spos & 7) & (1 << obtr) - 1);
|
|
5319
|
+
if (off > 3) {
|
|
5320
|
+
st.o[2] = st.o[1];
|
|
5321
|
+
st.o[1] = st.o[0];
|
|
5322
|
+
st.o[0] = off -= 3;
|
|
5323
|
+
} else {
|
|
5324
|
+
var idx = off - (ll != 0);
|
|
5325
|
+
if (idx) {
|
|
5326
|
+
off = idx == 3 ? st.o[0] - 1 : st.o[idx];
|
|
5327
|
+
if (idx > 1)
|
|
5328
|
+
st.o[2] = st.o[1];
|
|
5329
|
+
st.o[1] = st.o[0];
|
|
5330
|
+
st.o[0] = off;
|
|
5331
|
+
} else
|
|
5332
|
+
off = st.o[0];
|
|
5333
|
+
}
|
|
5334
|
+
for (var i = 0; i < ll; ++i) {
|
|
5335
|
+
buf[oubt + i] = buf[spl + i];
|
|
5336
|
+
}
|
|
5337
|
+
oubt += ll, spl += ll;
|
|
5338
|
+
var stin = oubt - off;
|
|
5339
|
+
if (stin < 0) {
|
|
5340
|
+
var len = -stin;
|
|
5341
|
+
var bs = st.e + stin;
|
|
5342
|
+
if (len > ml)
|
|
5343
|
+
len = ml;
|
|
5344
|
+
for (var i = 0; i < len; ++i) {
|
|
5345
|
+
buf[oubt + i] = st.w[bs + i];
|
|
5346
|
+
}
|
|
5347
|
+
oubt += len, ml -= len, stin = 0;
|
|
5348
|
+
}
|
|
5349
|
+
for (var i = 0; i < ml; ++i) {
|
|
5350
|
+
buf[oubt + i] = buf[stin + i];
|
|
5351
|
+
}
|
|
5352
|
+
oubt += ml;
|
|
5353
|
+
}
|
|
5354
|
+
if (oubt != spl) {
|
|
5355
|
+
while (spl < buf.length) {
|
|
5356
|
+
buf[oubt++] = buf[spl++];
|
|
5357
|
+
}
|
|
5358
|
+
} else
|
|
5359
|
+
oubt = buf.length;
|
|
5360
|
+
if (out)
|
|
5361
|
+
st.y += oubt;
|
|
5362
|
+
else
|
|
5363
|
+
buf = slc(buf, 0, oubt);
|
|
5364
|
+
} else if (out) {
|
|
5365
|
+
st.y += lss;
|
|
5366
|
+
if (spl) {
|
|
5367
|
+
for (var i = 0; i < lss; ++i) {
|
|
5368
|
+
buf[i] = buf[spl + i];
|
|
5369
|
+
}
|
|
5370
|
+
}
|
|
5371
|
+
} else if (spl)
|
|
5372
|
+
buf = slc(buf, spl);
|
|
5373
|
+
st.b = ebt;
|
|
5374
|
+
return buf;
|
|
5375
|
+
}
|
|
5376
|
+
err(2);
|
|
5377
|
+
};
|
|
5378
|
+
var cct = function(bufs, ol) {
|
|
5379
|
+
if (bufs.length == 1)
|
|
5380
|
+
return bufs[0];
|
|
5381
|
+
var buf = new u8(ol);
|
|
5382
|
+
for (var i = 0, b = 0; i < bufs.length; ++i) {
|
|
5383
|
+
var chk = bufs[i];
|
|
5384
|
+
buf.set(chk, b);
|
|
5385
|
+
b += chk.length;
|
|
5386
|
+
}
|
|
5387
|
+
return buf;
|
|
5388
|
+
};
|
|
5389
|
+
function decompress(dat, buf) {
|
|
5390
|
+
var bufs = [], nb = +!buf;
|
|
5391
|
+
var bt = 0, ol = 0;
|
|
5392
|
+
for (; dat.length; ) {
|
|
5393
|
+
var st = rzfh(dat, nb || buf);
|
|
5394
|
+
if (typeof st == "object") {
|
|
5395
|
+
if (nb) {
|
|
5396
|
+
buf = null;
|
|
5397
|
+
if (st.w.length == st.u) {
|
|
5398
|
+
bufs.push(buf = st.w);
|
|
5399
|
+
ol += st.u;
|
|
5400
|
+
}
|
|
5401
|
+
} else {
|
|
5402
|
+
bufs.push(buf);
|
|
5403
|
+
st.e = 0;
|
|
5404
|
+
}
|
|
5405
|
+
for (; !st.l; ) {
|
|
5406
|
+
var blk = rzb(dat, st, buf);
|
|
5407
|
+
if (!blk)
|
|
5408
|
+
err(5);
|
|
5409
|
+
if (buf)
|
|
5410
|
+
st.e = st.y;
|
|
5411
|
+
else {
|
|
5412
|
+
bufs.push(blk);
|
|
5413
|
+
ol += blk.length;
|
|
5414
|
+
cpw(st.w, 0, blk.length);
|
|
5415
|
+
st.w.set(blk, st.w.length - blk.length);
|
|
5416
|
+
}
|
|
5417
|
+
}
|
|
5418
|
+
bt = st.b + st.c * 4;
|
|
5419
|
+
} else
|
|
5420
|
+
bt = st;
|
|
5421
|
+
dat = dat.subarray(bt);
|
|
5422
|
+
}
|
|
5423
|
+
return cct(bufs, ol);
|
|
5424
|
+
}
|
|
5425
|
+
|
|
5426
|
+
// src/nexrad/radarDecodeSlot.ts
|
|
5427
|
+
var SLOT_HDR_BYTES = 28;
|
|
5428
|
+
function isZstd(bytes) {
|
|
5429
|
+
return bytes.length >= 4 && bytes[0] === 40 && bytes[1] === 181 && bytes[2] === 47 && bytes[3] === 253;
|
|
5430
|
+
}
|
|
5431
|
+
function parseObjectKey(objectKey) {
|
|
5432
|
+
const parts = objectKey.split("_");
|
|
5433
|
+
if (parts.length < 2) return null;
|
|
5434
|
+
return { stationId: parts[0] };
|
|
5435
|
+
}
|
|
5436
|
+
function buildRayBoundariesDeg(azimuths) {
|
|
5437
|
+
const nRays = azimuths.length;
|
|
5438
|
+
const boundaries = new Float32Array(nRays + 1);
|
|
5439
|
+
if (nRays === 0) return boundaries;
|
|
5440
|
+
let totalSpacing = 0;
|
|
5441
|
+
let validCount = 0;
|
|
5442
|
+
for (let i = 1; i < nRays; i++) {
|
|
5443
|
+
let diff = azimuths[i] - azimuths[i - 1];
|
|
5444
|
+
while (diff < -180) diff += 360;
|
|
5445
|
+
while (diff > 180) diff -= 360;
|
|
5446
|
+
const absDiff = Math.abs(diff);
|
|
5447
|
+
if (absDiff > 0 && absDiff < 10) {
|
|
5448
|
+
totalSpacing += absDiff;
|
|
5449
|
+
validCount++;
|
|
5450
|
+
}
|
|
5451
|
+
}
|
|
5452
|
+
let avgSpacing = validCount > 0 ? totalSpacing / validCount : 360 / nRays;
|
|
5453
|
+
if (avgSpacing <= 0 || isNaN(avgSpacing)) avgSpacing = 1;
|
|
5454
|
+
boundaries[0] = azimuths[0] - avgSpacing / 2;
|
|
5455
|
+
for (let i = 1; i < nRays; i++) {
|
|
5456
|
+
let diff = azimuths[i] - azimuths[i - 1];
|
|
5457
|
+
while (diff < -180) diff += 360;
|
|
5458
|
+
while (diff > 180) diff -= 360;
|
|
5459
|
+
boundaries[i] = azimuths[i - 1] + diff / 2;
|
|
5460
|
+
}
|
|
5461
|
+
boundaries[nRays] = azimuths[nRays - 1] + avgSpacing / 2;
|
|
5462
|
+
return boundaries;
|
|
5463
|
+
}
|
|
5464
|
+
function decodeRadarSlotMessage(data) {
|
|
5465
|
+
const {
|
|
5466
|
+
requestId,
|
|
5467
|
+
objectKey,
|
|
5468
|
+
slotBuffer,
|
|
5469
|
+
nRays,
|
|
5470
|
+
nGates,
|
|
5471
|
+
firstGateKm,
|
|
5472
|
+
gateWidthKm,
|
|
5473
|
+
azimuthsBuffer,
|
|
5474
|
+
sites
|
|
5475
|
+
} = data;
|
|
5476
|
+
const compressed = new Uint8Array(slotBuffer);
|
|
5477
|
+
if (!isZstd(compressed)) {
|
|
5478
|
+
return {
|
|
5479
|
+
type: "DECODE_RESULT",
|
|
5480
|
+
requestId,
|
|
5481
|
+
gateData: null,
|
|
5482
|
+
error: `Slot for ${objectKey} is not valid zstd`
|
|
5483
|
+
};
|
|
5484
|
+
}
|
|
5485
|
+
const decompressed = decompress(compressed);
|
|
5486
|
+
const buffer = decompressed.buffer.slice(
|
|
5487
|
+
decompressed.byteOffset,
|
|
5488
|
+
decompressed.byteOffset + decompressed.byteLength
|
|
5489
|
+
);
|
|
5490
|
+
const view = new DataView(buffer);
|
|
5491
|
+
const valueScale = view.getFloat32(0, false);
|
|
5492
|
+
const valueOffset = view.getFloat32(4, false);
|
|
5493
|
+
const present = view.getUint32(8, false);
|
|
5494
|
+
if (present === 0) {
|
|
5495
|
+
return {
|
|
5496
|
+
type: "DECODE_RESULT",
|
|
5497
|
+
requestId,
|
|
5498
|
+
gateData: null,
|
|
5499
|
+
error: `Slot for ${objectKey} marked not present`
|
|
5500
|
+
};
|
|
5501
|
+
}
|
|
5502
|
+
const slotNRays = view.getUint16(12, false);
|
|
5503
|
+
const slotNGates = view.getUint16(14, false);
|
|
5504
|
+
const gateBytes = buffer.byteLength - SLOT_HDR_BYTES;
|
|
5505
|
+
const expectedGates = slotNRays * slotNGates;
|
|
5506
|
+
const bytesPerGate = gateBytes / expectedGates;
|
|
5507
|
+
if (bytesPerGate !== 1 && bytesPerGate !== 2 && bytesPerGate !== 4) {
|
|
5508
|
+
return {
|
|
5509
|
+
type: "DECODE_RESULT",
|
|
5510
|
+
requestId,
|
|
5511
|
+
gateData: null,
|
|
5512
|
+
error: `Unexpected bytesPerGate=${bytesPerGate} for ${objectKey}`
|
|
5513
|
+
};
|
|
5514
|
+
}
|
|
5515
|
+
const keyParts = parseObjectKey(objectKey);
|
|
5516
|
+
if (!keyParts) {
|
|
5517
|
+
return {
|
|
5518
|
+
type: "DECODE_RESULT",
|
|
5519
|
+
requestId,
|
|
5520
|
+
gateData: null,
|
|
5521
|
+
error: `Unable to parse station from key: ${objectKey}`
|
|
5522
|
+
};
|
|
5523
|
+
}
|
|
5524
|
+
const site = sites.find((s) => s.id === keyParts.stationId);
|
|
5525
|
+
if (!site) {
|
|
5526
|
+
return {
|
|
5527
|
+
type: "DECODE_RESULT",
|
|
5528
|
+
requestId,
|
|
5529
|
+
gateData: null,
|
|
5530
|
+
error: `Station "${keyParts.stationId}" not found`
|
|
5531
|
+
};
|
|
5532
|
+
}
|
|
5533
|
+
const azimuths = new Float32Array(slotNRays);
|
|
5534
|
+
const azView = new DataView(azimuthsBuffer);
|
|
5535
|
+
const headerNRays = azimuthsBuffer.byteLength / 4;
|
|
5536
|
+
for (let i = 0; i < slotNRays; i++) {
|
|
5537
|
+
if (i < headerNRays) {
|
|
5538
|
+
azimuths[i] = azView.getFloat32(i * 4, false);
|
|
5539
|
+
} else {
|
|
5540
|
+
const prevAz = i > 0 ? azimuths[i - 1] : 0;
|
|
5541
|
+
azimuths[i] = (prevAz + 360 / slotNRays) % 360;
|
|
5542
|
+
}
|
|
5543
|
+
}
|
|
5544
|
+
const rayBoundariesDeg = buildRayBoundariesDeg(azimuths);
|
|
5545
|
+
const gateCount = slotNRays * slotNGates;
|
|
5546
|
+
const gateDataCopy = new Uint8Array(slotNRays * slotNGates * 2);
|
|
5547
|
+
const outView = new DataView(gateDataCopy.buffer);
|
|
5548
|
+
if (bytesPerGate === 1) {
|
|
5549
|
+
const raw = new Uint8Array(buffer, SLOT_HDR_BYTES, gateCount);
|
|
5550
|
+
for (let ray = 0; ray < slotNRays; ray++) {
|
|
5551
|
+
let prev = 0;
|
|
5552
|
+
for (let g = 0; g < slotNGates; g++) {
|
|
5553
|
+
const idx = ray * slotNGates + g;
|
|
5554
|
+
const delta = raw[idx];
|
|
5555
|
+
const val = prev + delta & 255;
|
|
5556
|
+
prev = val;
|
|
5557
|
+
if (val === 0) {
|
|
5558
|
+
outView.setInt16(idx * 2, -32768, false);
|
|
5559
|
+
} else {
|
|
5560
|
+
outView.setInt16(idx * 2, val, false);
|
|
5561
|
+
}
|
|
5562
|
+
}
|
|
5563
|
+
}
|
|
5564
|
+
} else {
|
|
5565
|
+
const rawBytes = new Uint8Array(buffer, SLOT_HDR_BYTES, gateCount * 2);
|
|
5566
|
+
for (let ray = 0; ray < slotNRays; ray++) {
|
|
5567
|
+
let prev = 0;
|
|
5568
|
+
for (let g = 0; g < slotNGates; g++) {
|
|
5569
|
+
const idx = ray * slotNGates + g;
|
|
5570
|
+
const hi = rawBytes[idx * 2];
|
|
5571
|
+
const lo = rawBytes[idx * 2 + 1];
|
|
5572
|
+
const delta = (hi << 8 | lo) << 16 >> 16;
|
|
5573
|
+
const val = prev + delta | 0;
|
|
5574
|
+
prev = val;
|
|
5575
|
+
outView.setInt16(idx * 2, val, false);
|
|
5576
|
+
}
|
|
5577
|
+
}
|
|
5578
|
+
}
|
|
5579
|
+
return {
|
|
5580
|
+
type: "DECODE_RESULT",
|
|
5581
|
+
requestId,
|
|
5582
|
+
gateData: gateDataCopy,
|
|
5583
|
+
stationLat: site.lat,
|
|
5584
|
+
stationLon: site.lon,
|
|
5585
|
+
firstGateKm,
|
|
5586
|
+
gateWidthKm,
|
|
5587
|
+
valueScale,
|
|
5588
|
+
valueOffset,
|
|
5589
|
+
rayBoundariesDeg,
|
|
5590
|
+
nRays: slotNRays,
|
|
5591
|
+
nGates: slotNGates
|
|
5592
|
+
};
|
|
5593
|
+
}
|
|
5594
|
+
|
|
3013
5595
|
// src/nexrad/radarArchiveCore.ts
|
|
3014
5596
|
if (typeof globalThis.Buffer === "undefined") {
|
|
3015
5597
|
globalThis.Buffer = import_buffer.Buffer;
|
|
3016
5598
|
}
|
|
5599
|
+
function createAbortError(message = "Aborted") {
|
|
5600
|
+
const g = globalThis;
|
|
5601
|
+
if (typeof g.DOMException !== "undefined") {
|
|
5602
|
+
return new g.DOMException(message, "AbortError");
|
|
5603
|
+
}
|
|
5604
|
+
const err2 = new Error(message);
|
|
5605
|
+
err2.name = "AbortError";
|
|
5606
|
+
return err2;
|
|
5607
|
+
}
|
|
5608
|
+
function isAbortError(err2) {
|
|
5609
|
+
if (err2 == null || typeof err2 !== "object") return false;
|
|
5610
|
+
return err2.name === "AbortError";
|
|
5611
|
+
}
|
|
3017
5612
|
var NEXRAD_ARCHIVE_API_KEY = "";
|
|
5613
|
+
var NEXRAD_ARCHIVE_BUNDLE_ID = "";
|
|
3018
5614
|
function setNexradArchiveApiKey(k) {
|
|
3019
5615
|
NEXRAD_ARCHIVE_API_KEY = k || "";
|
|
3020
5616
|
}
|
|
5617
|
+
function setNexradArchiveBundleId(bundleId) {
|
|
5618
|
+
NEXRAD_ARCHIVE_BUNDLE_ID = bundleId || "";
|
|
5619
|
+
}
|
|
5620
|
+
function cloudFrontUrlWithApiKeyQuery(baseUrl) {
|
|
5621
|
+
if (!NEXRAD_ARCHIVE_API_KEY) return baseUrl;
|
|
5622
|
+
const sep = baseUrl.includes("?") ? "&" : "?";
|
|
5623
|
+
return `${baseUrl}${sep}apiKey=${NEXRAD_ARCHIVE_API_KEY}`;
|
|
5624
|
+
}
|
|
5625
|
+
function level2CloudFrontFetchHeaders(range) {
|
|
5626
|
+
const headers = {
|
|
5627
|
+
"x-api-key": NEXRAD_ARCHIVE_API_KEY
|
|
5628
|
+
};
|
|
5629
|
+
if (range !== void 0) {
|
|
5630
|
+
headers["Range"] = range;
|
|
5631
|
+
}
|
|
5632
|
+
const g = globalThis;
|
|
5633
|
+
if (g.navigator?.product === "ReactNative" && NEXRAD_ARCHIVE_BUNDLE_ID) {
|
|
5634
|
+
headers["x-app-identifier"] = NEXRAD_ARCHIVE_BUNDLE_ID;
|
|
5635
|
+
}
|
|
5636
|
+
return headers;
|
|
5637
|
+
}
|
|
5638
|
+
function shouldDecodeRadarOnMainThread() {
|
|
5639
|
+
const g = globalThis;
|
|
5640
|
+
return typeof Worker === "undefined" || g.navigator?.product === "ReactNative";
|
|
5641
|
+
}
|
|
5642
|
+
var MainThreadRadarDecodeWorker = class {
|
|
5643
|
+
onmessage = null;
|
|
5644
|
+
onerror = null;
|
|
5645
|
+
postMessage(data) {
|
|
5646
|
+
const msg = data;
|
|
5647
|
+
if (!msg || msg.type !== "DECODE_SLOT") return;
|
|
5648
|
+
queueMicrotask(() => {
|
|
5649
|
+
try {
|
|
5650
|
+
const response = decodeRadarSlotMessage(msg);
|
|
5651
|
+
this.onmessage?.({ data: response });
|
|
5652
|
+
} catch (error) {
|
|
5653
|
+
this.onmessage?.({
|
|
5654
|
+
data: {
|
|
5655
|
+
type: "DECODE_RESULT",
|
|
5656
|
+
requestId: msg.requestId,
|
|
5657
|
+
gateData: null,
|
|
5658
|
+
error: error instanceof Error ? error.message : "Main-thread radar decode failed"
|
|
5659
|
+
}
|
|
5660
|
+
});
|
|
5661
|
+
}
|
|
5662
|
+
});
|
|
5663
|
+
}
|
|
5664
|
+
terminate() {
|
|
5665
|
+
}
|
|
5666
|
+
};
|
|
3021
5667
|
function createRadarDecodeWorker() {
|
|
5668
|
+
if (shouldDecodeRadarOnMainThread()) {
|
|
5669
|
+
return new MainThreadRadarDecodeWorker();
|
|
5670
|
+
}
|
|
3022
5671
|
return new Worker(new URL("./radarDecode.worker.bundled.js", import.meta.url), { type: "module" });
|
|
3023
5672
|
}
|
|
3024
5673
|
var LEVEL2_BASE_URL = "https://d3dc62msmxkrd7.cloudfront.net/level-2";
|
|
@@ -4017,8 +6666,8 @@ function decodeLevel3RasterProduct(buffer, objectKey, radarVariable) {
|
|
|
4017
6666
|
});
|
|
4018
6667
|
}
|
|
4019
6668
|
return null;
|
|
4020
|
-
} catch (
|
|
4021
|
-
console.warn("[aguacero][nexrad-l3][decode-throw]", { objectKey, radarVariable, err });
|
|
6669
|
+
} catch (err2) {
|
|
6670
|
+
console.warn("[aguacero][nexrad-l3][decode-throw]", { objectKey, radarVariable, err: err2 });
|
|
4022
6671
|
return null;
|
|
4023
6672
|
}
|
|
4024
6673
|
}
|
|
@@ -4104,7 +6753,7 @@ function parseFileHeader(buffer, azBlockBytes) {
|
|
|
4104
6753
|
};
|
|
4105
6754
|
}
|
|
4106
6755
|
function decodeSweepInWorker(objectKey, slotBuffer, header, sites, priority, signal) {
|
|
4107
|
-
if (signal?.aborted) return Promise.reject(
|
|
6756
|
+
if (signal?.aborted) return Promise.reject(createAbortError());
|
|
4108
6757
|
const { worker } = getDecodeWorkerForPriority(priority);
|
|
4109
6758
|
const requestId = ++radarDecodeRequestId;
|
|
4110
6759
|
const azCopy = header.azimuthsBuffer.slice(0);
|
|
@@ -4116,7 +6765,7 @@ function decodeSweepInWorker(objectKey, slotBuffer, header, sites, priority, sig
|
|
|
4116
6765
|
radarDecodePending.delete(requestId);
|
|
4117
6766
|
radarDecodeRequestMeta.delete(requestId);
|
|
4118
6767
|
signal?.removeEventListener("abort", onAbort);
|
|
4119
|
-
reject(
|
|
6768
|
+
reject(createAbortError());
|
|
4120
6769
|
};
|
|
4121
6770
|
radarDecodePending.set(requestId, {
|
|
4122
6771
|
resolve: (frame) => {
|
|
@@ -4126,11 +6775,11 @@ function decodeSweepInWorker(objectKey, slotBuffer, header, sites, priority, sig
|
|
|
4126
6775
|
resolve(frame);
|
|
4127
6776
|
}
|
|
4128
6777
|
},
|
|
4129
|
-
reject: (
|
|
6778
|
+
reject: (err2) => {
|
|
4130
6779
|
if (!isSettled) {
|
|
4131
6780
|
isSettled = true;
|
|
4132
6781
|
signal?.removeEventListener("abort", onAbort);
|
|
4133
|
-
reject(
|
|
6782
|
+
reject(err2);
|
|
4134
6783
|
}
|
|
4135
6784
|
}
|
|
4136
6785
|
});
|
|
@@ -4241,13 +6890,28 @@ async function fetchAndParseArchive(url, objectKey, radarVariable, groupId, rada
|
|
|
4241
6890
|
}
|
|
4242
6891
|
return decoded2;
|
|
4243
6892
|
}
|
|
6893
|
+
const level2Url = cloudFrontUrlWithApiKeyQuery(url);
|
|
6894
|
+
nexradArchiveDiag("level2.pipeline.start", {
|
|
6895
|
+
objectKey,
|
|
6896
|
+
radarVariable,
|
|
6897
|
+
groupId,
|
|
6898
|
+
apiKeyLen: NEXRAD_ARCHIVE_API_KEY.length,
|
|
6899
|
+
bundleIdLen: NEXRAD_ARCHIVE_BUNDLE_ID.length,
|
|
6900
|
+
urlNoSecret: redactApiKeyFromUrl(level2Url)
|
|
6901
|
+
});
|
|
4244
6902
|
const azBlockBytes = LEVEL2_AZ_BLOCK_BYTES;
|
|
4245
6903
|
const INDEX_FETCH_BYTES = FILE_HDR_BYTES + azBlockBytes + LEVEL2_FILE_NYQUIST_BYTES + MAX_SLOTS * SLOT_INDEX_ENTRY;
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
6904
|
+
nexradArchiveDiag("level2.index.fetch", {
|
|
6905
|
+
objectKey,
|
|
6906
|
+
byteRangeEnd: INDEX_FETCH_BYTES - 1
|
|
6907
|
+
});
|
|
6908
|
+
const indexResp = await fetch(level2Url, {
|
|
6909
|
+
headers: level2CloudFrontFetchHeaders(`bytes=0-${INDEX_FETCH_BYTES - 1}`)
|
|
6910
|
+
});
|
|
6911
|
+
nexradArchiveDiag("level2.index.response", {
|
|
6912
|
+
objectKey,
|
|
6913
|
+
status: indexResp.status,
|
|
6914
|
+
ok: indexResp.ok
|
|
4251
6915
|
});
|
|
4252
6916
|
if (!indexResp.ok && indexResp.status !== 206) {
|
|
4253
6917
|
throw new Error(`HTTP ${indexResp.status} fetching level2 index ${url}`);
|
|
@@ -4304,16 +6968,24 @@ async function fetchAndParseArchive(url, objectKey, radarVariable, groupId, rada
|
|
|
4304
6968
|
return null;
|
|
4305
6969
|
}
|
|
4306
6970
|
const slotRangeEnd = slotEndExclusive - 1;
|
|
4307
|
-
const slotHeaders = {
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
6971
|
+
const slotHeaders = level2CloudFrontFetchHeaders(`bytes=${slot.offset}-${slotRangeEnd}`);
|
|
6972
|
+
nexradArchiveDiag("level2.slot.fetch", {
|
|
6973
|
+
objectKey,
|
|
6974
|
+
slotIdx,
|
|
6975
|
+
compressedSize: slot.compressedSize,
|
|
6976
|
+
offset: slot.offset
|
|
6977
|
+
});
|
|
6978
|
+
let slotResp = await fetch(level2Url, { headers: slotHeaders });
|
|
6979
|
+
nexradArchiveDiag("level2.slot.response", {
|
|
6980
|
+
objectKey,
|
|
6981
|
+
status: slotResp.status,
|
|
6982
|
+
ok: slotResp.ok
|
|
6983
|
+
});
|
|
4312
6984
|
let slotBuffer;
|
|
4313
6985
|
if (slotResp.ok || slotResp.status === 206) {
|
|
4314
6986
|
slotBuffer = await slotResp.arrayBuffer();
|
|
4315
6987
|
} else if (slotResp.status === 416) {
|
|
4316
|
-
const fullResp = await fetch(
|
|
6988
|
+
const fullResp = await fetch(level2Url, { headers: level2CloudFrontFetchHeaders(void 0) });
|
|
4317
6989
|
if (!fullResp.ok) {
|
|
4318
6990
|
throw new Error(`HTTP ${fullResp.status} full fetch after 416 for level2 ${url}`);
|
|
4319
6991
|
}
|
|
@@ -4327,6 +6999,7 @@ async function fetchAndParseArchive(url, objectKey, radarVariable, groupId, rada
|
|
|
4327
6999
|
} else {
|
|
4328
7000
|
throw new Error(`HTTP ${slotResp.status} fetching level2 slot ${url}`);
|
|
4329
7001
|
}
|
|
7002
|
+
nexradArchiveDiag("level2.decode.start", { objectKey, radarVariable });
|
|
4330
7003
|
const sites = await loadNexradSites();
|
|
4331
7004
|
let decoded = await decodeSweepInWorker(
|
|
4332
7005
|
objectKey,
|
|
@@ -4350,12 +7023,23 @@ async function fetchAndParseArchive(url, objectKey, radarVariable, groupId, rada
|
|
|
4350
7023
|
);
|
|
4351
7024
|
}
|
|
4352
7025
|
setArchiveCache(cacheKey, decoded);
|
|
7026
|
+
nexradArchiveDiag("level2.decode.done", {
|
|
7027
|
+
objectKey,
|
|
7028
|
+
radarVariable,
|
|
7029
|
+
nRays: decoded.nRays ?? null,
|
|
7030
|
+
nGates: decoded.nGates ?? null
|
|
7031
|
+
});
|
|
4353
7032
|
return decoded;
|
|
4354
|
-
} catch (
|
|
4355
|
-
if (
|
|
7033
|
+
} catch (err2) {
|
|
7034
|
+
if (isAbortError(err2)) {
|
|
4356
7035
|
return null;
|
|
4357
7036
|
}
|
|
4358
|
-
|
|
7037
|
+
nexradArchiveDiag("fetchAndParseArchive.failed", {
|
|
7038
|
+
objectKey,
|
|
7039
|
+
radarSource,
|
|
7040
|
+
message: err2 instanceof Error ? err2.message : String(err2)
|
|
7041
|
+
});
|
|
7042
|
+
console.error(`[RadarLayer] fetchAndParseArchive failed for ${objectKey}:`, err2);
|
|
4359
7043
|
return null;
|
|
4360
7044
|
} finally {
|
|
4361
7045
|
inflightFetches.delete(cacheKey);
|
|
@@ -4368,7 +7052,10 @@ async function fetchAndParseArchive(url, objectKey, radarVariable, groupId, rada
|
|
|
4368
7052
|
export {
|
|
4369
7053
|
fetchAndParseArchive,
|
|
4370
7054
|
objectKeyToUrl,
|
|
4371
|
-
setNexradArchiveApiKey
|
|
7055
|
+
setNexradArchiveApiKey,
|
|
7056
|
+
setNexradArchiveBundleId,
|
|
7057
|
+
setNexradSitesFetchAuth,
|
|
7058
|
+
setNexradSitesJsonUrl
|
|
4372
7059
|
};
|
|
4373
7060
|
/*! Bundled license information:
|
|
4374
7061
|
|