@aguacerowx/javascript-sdk 0.0.9 → 0.0.10
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/AguaceroCore.js +128 -68
- package/dist/default-colormaps.js +39 -12
- package/dist/dictionaries.js +38 -20
- package/dist/index.js +0 -6
- package/package.json +1 -1
- package/src/AguaceroCore.js +26 -1
- package/src/default-colormaps.js +67 -7
- package/src/dictionaries.js +39 -20
package/dist/AguaceroCore.js
CHANGED
|
@@ -10,7 +10,6 @@ var _unitConversions = require("./unitConversions.js");
|
|
|
10
10
|
var _dictionaries = require("./dictionaries.js");
|
|
11
11
|
var _defaultColormaps = require("./default-colormaps.js");
|
|
12
12
|
var _proj = _interopRequireDefault(require("proj4"));
|
|
13
|
-
var _fzstd = require("fzstd");
|
|
14
13
|
var _getBundleId = require("./getBundleId");
|
|
15
14
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
15
|
// AguaceroCore.js - The Headless "Engine"
|
|
@@ -92,7 +91,7 @@ class AguaceroCore extends _events.EventEmitter {
|
|
|
92
91
|
run: null,
|
|
93
92
|
forecastHour: 0,
|
|
94
93
|
visible: true,
|
|
95
|
-
opacity: userLayerOptions.opacity ??
|
|
94
|
+
opacity: userLayerOptions.opacity ?? 1,
|
|
96
95
|
units: options.initialUnit || 'imperial',
|
|
97
96
|
shaderSmoothingEnabled: options.shaderSmoothingEnabled ?? true
|
|
98
97
|
};
|
|
@@ -190,24 +189,60 @@ class AguaceroCore extends _events.EventEmitter {
|
|
|
190
189
|
this.isPlaying ? this.pause() : this.play();
|
|
191
190
|
}
|
|
192
191
|
step(direction = 1) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
192
|
+
// --- THIS IS THE CORRECTED MRMS LOGIC ---
|
|
193
|
+
if (this.state.isMRMS) {
|
|
194
|
+
const {
|
|
195
|
+
variable,
|
|
196
|
+
mrmsTimestamp
|
|
197
|
+
} = this.state;
|
|
198
|
+
if (!this.mrmsStatus || !this.mrmsStatus[variable]) {
|
|
199
|
+
console.warn('[Core.step] MRMS status or variable not available.');
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// CRITICAL FIX: The UI and state emissions use a REVERSED array (newest first).
|
|
204
|
+
// The step logic MUST use the same reversed array for indexes to match.
|
|
205
|
+
const availableTimestamps = [...(this.mrmsStatus[variable] || [])].reverse();
|
|
206
|
+
if (availableTimestamps.length === 0) return;
|
|
207
|
+
const currentIndex = availableTimestamps.indexOf(mrmsTimestamp);
|
|
208
|
+
if (currentIndex === -1) {
|
|
209
|
+
// If not found, reset to the first (newest) frame
|
|
210
|
+
this.setState({
|
|
211
|
+
mrmsTimestamp: availableTimestamps[0]
|
|
212
|
+
});
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
const maxIndex = availableTimestamps.length - 1;
|
|
216
|
+
let nextIndex = currentIndex + direction;
|
|
217
|
+
|
|
218
|
+
// Loop animation
|
|
219
|
+
if (nextIndex > maxIndex) nextIndex = 0;
|
|
220
|
+
if (nextIndex < 0) nextIndex = maxIndex;
|
|
221
|
+
const newTimestamp = availableTimestamps[nextIndex];
|
|
222
|
+
this.setState({
|
|
223
|
+
mrmsTimestamp: newTimestamp
|
|
224
|
+
});
|
|
225
|
+
} else {
|
|
226
|
+
var _this$modelStatus3;
|
|
227
|
+
const {
|
|
228
|
+
model,
|
|
229
|
+
date,
|
|
230
|
+
run,
|
|
231
|
+
forecastHour
|
|
232
|
+
} = this.state;
|
|
233
|
+
const forecastHours = (_this$modelStatus3 = this.modelStatus) === null || _this$modelStatus3 === void 0 || (_this$modelStatus3 = _this$modelStatus3[model]) === null || _this$modelStatus3 === void 0 || (_this$modelStatus3 = _this$modelStatus3[date]) === null || _this$modelStatus3 === void 0 ? void 0 : _this$modelStatus3[run];
|
|
234
|
+
if (!forecastHours || forecastHours.length === 0) return;
|
|
235
|
+
const currentIndex = forecastHours.indexOf(forecastHour);
|
|
236
|
+
if (currentIndex === -1) return;
|
|
237
|
+
const maxIndex = forecastHours.length - 1;
|
|
238
|
+
let nextIndex = currentIndex + direction;
|
|
239
|
+
if (nextIndex > maxIndex) nextIndex = 0;
|
|
240
|
+
if (nextIndex < 0) nextIndex = maxIndex;
|
|
241
|
+
const newHour = forecastHours[nextIndex];
|
|
242
|
+
this.setState({
|
|
243
|
+
forecastHour: newHour
|
|
244
|
+
});
|
|
245
|
+
}
|
|
211
246
|
}
|
|
212
247
|
setPlaybackSpeed(speed) {
|
|
213
248
|
if (speed > 0) {
|
|
@@ -350,6 +385,10 @@ class AguaceroCore extends _events.EventEmitter {
|
|
|
350
385
|
return new Uint8Array(reconstructedData.buffer);
|
|
351
386
|
}
|
|
352
387
|
async _loadGridData(state) {
|
|
388
|
+
if (this.isReactNative) {
|
|
389
|
+
console.warn(`[AguaceroCore] _loadGridData was called in React Native. This is a bypass. Data loading is handled natively.`);
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
353
392
|
const {
|
|
354
393
|
model,
|
|
355
394
|
date,
|
|
@@ -404,7 +443,7 @@ class AguaceroCore extends _events.EventEmitter {
|
|
|
404
443
|
const headers = {
|
|
405
444
|
'x-api-key': this.apiKey
|
|
406
445
|
};
|
|
407
|
-
if (this.bundleId) {
|
|
446
|
+
if (this.bundleId && this.isReactNative) {
|
|
408
447
|
headers['x-app-identifier'] = this.bundleId;
|
|
409
448
|
}
|
|
410
449
|
const response = await fetch(urlWithApiKeyParam, {
|
|
@@ -504,20 +543,68 @@ class AguaceroCore extends _events.EventEmitter {
|
|
|
504
543
|
const index1D = j * nx + i;
|
|
505
544
|
const byteValue = gridData.data[index1D];
|
|
506
545
|
const signedQuantizedValue = byteValue - 128;
|
|
546
|
+
|
|
547
|
+
// --- START OF FIX ---
|
|
548
|
+
// You were missing 'scale_type' in this destructuring assignment.
|
|
507
549
|
const {
|
|
508
550
|
scale,
|
|
509
551
|
offset,
|
|
510
|
-
missing_quantized
|
|
552
|
+
missing_quantized,
|
|
553
|
+
scale_type
|
|
511
554
|
} = gridData.encoding;
|
|
555
|
+
// --- END OF FIX ---
|
|
556
|
+
|
|
512
557
|
if (signedQuantizedValue === missing_quantized) return null;
|
|
513
|
-
const
|
|
558
|
+
const intermediateValue = signedQuantizedValue * scale + offset;
|
|
559
|
+
|
|
560
|
+
// Step 2: Apply non-linear scaling if specified
|
|
561
|
+
let nativeValue = intermediateValue;
|
|
562
|
+
if (scale_type === 'sqrt') {
|
|
563
|
+
// Square the value while preserving its sign
|
|
564
|
+
nativeValue = intermediateValue < 0 ? -(intermediateValue * intermediateValue) : intermediateValue * intermediateValue;
|
|
565
|
+
}
|
|
514
566
|
const {
|
|
567
|
+
colormap,
|
|
515
568
|
baseUnit
|
|
516
569
|
} = this._getColormapForVariable(variable);
|
|
570
|
+
|
|
571
|
+
// If the value is outside the colormap's bounds, return null.
|
|
572
|
+
if (colormap && colormap.length >= 2) {
|
|
573
|
+
const minBound = colormap[0];
|
|
574
|
+
const maxBound = colormap[colormap.length - 2];
|
|
575
|
+
if (nativeValue < minBound || nativeValue > maxBound) {
|
|
576
|
+
return null;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
517
579
|
let dataNativeUnit = baseUnit || (_dictionaries.DICTIONARIES.fld[variable] || {}).defaultUnit || 'none';
|
|
518
580
|
const displayUnit = this._getTargetUnit(dataNativeUnit, units);
|
|
519
581
|
const conversionFunc = (0, _unitConversions.getUnitConversionFunction)(dataNativeUnit, displayUnit);
|
|
520
|
-
|
|
582
|
+
let displayValue = conversionFunc ? conversionFunc(nativeValue) : nativeValue;
|
|
583
|
+
|
|
584
|
+
// --- START: ADDED CODE ---
|
|
585
|
+
|
|
586
|
+
// Create a variable to hold the precipitation type, if any.
|
|
587
|
+
let precipType = null;
|
|
588
|
+
|
|
589
|
+
// Check if the current variable is one of the special ptype variables.
|
|
590
|
+
if (variable === 'ptypeRefl' || variable === 'ptypeRate') {
|
|
591
|
+
const value = nativeValue; // Use the raw, unconverted value for ptype logic
|
|
592
|
+
|
|
593
|
+
if (value >= 100 && value < 200) {
|
|
594
|
+
displayValue -= 100;
|
|
595
|
+
precipType = 'Snow';
|
|
596
|
+
} else if (value >= 200 && value < 300) {
|
|
597
|
+
displayValue -= 200;
|
|
598
|
+
precipType = 'Frzg Rain'; // Abbreviated for tooltips
|
|
599
|
+
} else if (value >= 300 && value < 400) {
|
|
600
|
+
displayValue -= 300;
|
|
601
|
+
precipType = 'Ice Pellets';
|
|
602
|
+
} else {
|
|
603
|
+
precipType = 'Rain';
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// Return the final payload, now including the precipType.
|
|
521
608
|
return {
|
|
522
609
|
lngLat: {
|
|
523
610
|
lng,
|
|
@@ -528,7 +615,8 @@ class AguaceroCore extends _events.EventEmitter {
|
|
|
528
615
|
name: this.getVariableDisplayName(variable)
|
|
529
616
|
},
|
|
530
617
|
value: displayValue,
|
|
531
|
-
unit: displayUnit
|
|
618
|
+
unit: displayUnit,
|
|
619
|
+
precipType: precipType // NEW: Add this to the return object
|
|
532
620
|
};
|
|
533
621
|
} catch (error) {
|
|
534
622
|
return null;
|
|
@@ -548,9 +636,6 @@ class AguaceroCore extends _events.EventEmitter {
|
|
|
548
636
|
colormap: [],
|
|
549
637
|
baseUnit: ''
|
|
550
638
|
};
|
|
551
|
-
|
|
552
|
-
// This logic for user-provided custom colormaps is correct.
|
|
553
|
-
// If a user provides a custom map, it should always take top priority.
|
|
554
639
|
if (this.customColormaps[variable] && this.customColormaps[variable].colormap) {
|
|
555
640
|
return {
|
|
556
641
|
colormap: this.customColormaps[variable].colormap,
|
|
@@ -566,45 +651,18 @@ class AguaceroCore extends _events.EventEmitter {
|
|
|
566
651
|
};
|
|
567
652
|
}
|
|
568
653
|
const defaultColormapData = _defaultColormaps.DEFAULT_COLORMAPS[colormapKey];
|
|
569
|
-
|
|
570
|
-
// --- START OF THE BUG FIX ---
|
|
571
|
-
// This block handles the "default" case when no custom colormap is provided.
|
|
572
654
|
if (defaultColormapData && defaultColormapData.units) {
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
const
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
// 3. EDITED: If it exists, return ITS data. This is the correct path.
|
|
583
|
-
console.log(`[AguaceroCore] Using dictionary default unit '${preferredUnit}' for variable '${variable}'.`);
|
|
584
|
-
return {
|
|
585
|
-
colormap: unitData.colormap,
|
|
586
|
-
baseUnit: preferredUnit
|
|
587
|
-
};
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
// 4. EDITED: The old, buggy logic now serves as a FALLBACK ONLY.
|
|
592
|
-
// This will only run if the specified defaultUnit is missing from the colormap data.
|
|
593
|
-
console.warn(`[AguaceroCore] Default unit for '${variable}' not found in colormap. Using fallback.`);
|
|
594
|
-
const availableUnits = Object.keys(defaultColormapData.units);
|
|
595
|
-
if (availableUnits.length > 0) {
|
|
596
|
-
const fallbackUnit = availableUnits[0]; // e.g., '°F'
|
|
597
|
-
const unitData = defaultColormapData.units[fallbackUnit];
|
|
598
|
-
if (unitData && unitData.colormap) {
|
|
599
|
-
return {
|
|
600
|
-
colormap: unitData.colormap,
|
|
601
|
-
baseUnit: fallbackUnit
|
|
602
|
-
};
|
|
603
|
-
}
|
|
655
|
+
// ✅ Get defaultUnit from the field dictionary
|
|
656
|
+
const fieldInfo = _dictionaries.DICTIONARIES.fld[variable] || {};
|
|
657
|
+
const baseUnit = fieldInfo.defaultUnit || Object.keys(defaultColormapData.units)[0];
|
|
658
|
+
const unitData = defaultColormapData.units[baseUnit];
|
|
659
|
+
if (unitData && unitData.colormap) {
|
|
660
|
+
return {
|
|
661
|
+
colormap: unitData.colormap,
|
|
662
|
+
baseUnit: baseUnit
|
|
663
|
+
};
|
|
604
664
|
}
|
|
605
665
|
}
|
|
606
|
-
// --- END OF THE BUG FIX ---
|
|
607
|
-
|
|
608
666
|
return {
|
|
609
667
|
colormap: [],
|
|
610
668
|
baseUnit: ''
|
|
@@ -713,13 +771,15 @@ class AguaceroCore extends _events.EventEmitter {
|
|
|
713
771
|
}
|
|
714
772
|
_getTargetUnit(defaultUnit, system) {
|
|
715
773
|
if (system === 'metric') {
|
|
716
|
-
if (['°F', '°C'].includes(defaultUnit)) return '
|
|
774
|
+
if (['°F', '°C', 'fahrenheit', 'celsius'].includes(defaultUnit)) return '°C';
|
|
717
775
|
if (['kts', 'mph', 'm/s'].includes(defaultUnit)) return 'km/h';
|
|
718
776
|
if (['in', 'mm', 'cm'].includes(defaultUnit)) return 'mm';
|
|
719
777
|
}
|
|
720
|
-
if (
|
|
721
|
-
|
|
722
|
-
|
|
778
|
+
if (system === 'imperial') {
|
|
779
|
+
if (['°F', '°C', 'fahrenheit', 'celsius'].includes(defaultUnit)) return '°F';
|
|
780
|
+
if (['kts', 'mph', 'm/s'].includes(defaultUnit)) return 'mph';
|
|
781
|
+
if (['in', 'mm', 'cm'].includes(defaultUnit)) return 'in';
|
|
782
|
+
}
|
|
723
783
|
return defaultUnit;
|
|
724
784
|
}
|
|
725
785
|
_getGridIndexFromLngLat(lng, lat) {
|
|
@@ -17,14 +17,10 @@ const DEFAULT_COLORMAPS = exports.DEFAULT_COLORMAPS = {
|
|
|
17
17
|
// --- Snow Palette (Reflectivity Values Offset by +100) ---
|
|
18
18
|
105, "#33ccff", 135, "#8800cc", 170, "#ffccff", 180, "#dddddd",
|
|
19
19
|
// --- Freezing Rain Palette (Reflectivity Values Offset by +200) ---
|
|
20
|
-
205, "#ff3300", 230, "#ffaa33", 280, "#cc0066"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// Snow Breakpoints
|
|
25
|
-
105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180,
|
|
26
|
-
// Freezing Rain Breakpoints
|
|
27
|
-
205, 210, 215, 220, 225, 230, 235, 240, 245, 250, 255, 260, 265, 270, 275, 280]
|
|
20
|
+
205, "#ff3300", 230, "#ffaa33", 280, "#cc0066",
|
|
21
|
+
// icep
|
|
22
|
+
305, "#8800cc", 370, "#ffbb00", 380, "#dddddd"],
|
|
23
|
+
"breakpoints": []
|
|
28
24
|
}
|
|
29
25
|
}
|
|
30
26
|
},
|
|
@@ -811,6 +807,37 @@ const DEFAULT_COLORMAPS = exports.DEFAULT_COLORMAPS = {
|
|
|
811
807
|
}
|
|
812
808
|
}
|
|
813
809
|
},
|
|
810
|
+
"ptypeRate": {
|
|
811
|
+
"type": "fill",
|
|
812
|
+
"gridded": false,
|
|
813
|
+
"interpolationType": "interpolate",
|
|
814
|
+
"units": {
|
|
815
|
+
"in/hr": {
|
|
816
|
+
"colormap": [
|
|
817
|
+
// --- Rain Palette (Standard Reflectivity Values: 5 to 80) ---
|
|
818
|
+
0.005, "#00cc66", 0.1, "#ffff00", 0.3, "#ff8800", 1, "#ff0000", 1.5, '#ff00cc',
|
|
819
|
+
// --- Snow Palette (Reflectivity Values Offset by +100) ---
|
|
820
|
+
100.05, "#33ccff", 101, "#000099", 104, "#ff00cc",
|
|
821
|
+
// --- Freezing Rain Palette (Reflectivity Values Offset by +200) ---
|
|
822
|
+
200.005, "#ff3300", 200.1, "#ff33ff", 200.6, "#cc99cc",
|
|
823
|
+
// icep
|
|
824
|
+
300.005, "#8800cc", 300.2, "#aa44dd", 300.6, "#cc88dd"],
|
|
825
|
+
"breakpoints": []
|
|
826
|
+
},
|
|
827
|
+
"mm/hr": {
|
|
828
|
+
"colormap": [
|
|
829
|
+
// --- Rain Palette (Standard Reflectivity Values: 5 to 80) ---
|
|
830
|
+
0.1, "#00cc66", 3, "#ffff00", 7, "#ff8800", 24, "#ff0000", 36, '#ff00cc',
|
|
831
|
+
// --- Snow Palette (Reflectivity Values Offset by +100) ---
|
|
832
|
+
100.1, "#33ccff", 103, "#000099", 110, "#ff00cc",
|
|
833
|
+
// --- Freezing Rain Palette (Reflectivity Values Offset by +200) ---
|
|
834
|
+
200.1, "#ff3300", 203, "#ff33ff", 214, "#cc99cc",
|
|
835
|
+
// icep
|
|
836
|
+
300.1, "#ff3300", 303, "#ff33ff", 314, "#cc99cc"],
|
|
837
|
+
"breakpoints": []
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
},
|
|
814
841
|
"frzrRefl": {
|
|
815
842
|
"type": "fill",
|
|
816
843
|
"gridded": false,
|
|
@@ -902,11 +929,11 @@ const DEFAULT_COLORMAPS = exports.DEFAULT_COLORMAPS = {
|
|
|
902
929
|
"colormap": [0.01, "#eeccff", .1, "#ff9999", .25, "#cc3366", .5, "#ff9933", .75, "#ffee00", 1, "#00cccc", 3, "#99ffff"],
|
|
903
930
|
"breakpoints": [0.01, 0.1, 0.25, 0.5, 0.75, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 7, 8, 9, 10]
|
|
904
931
|
},
|
|
905
|
-
"cm": {
|
|
932
|
+
"cm [QPF]": {
|
|
906
933
|
"colormap": [0.03, "#eeccff", .25, "#ff9999", .75, "#cc3366", 1, "#cc0066", 2, "#ffee00", 3, "#00cccc", 7, "#99ffff"],
|
|
907
934
|
"breakpoints": [.03, .25, .5, .75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.5, 5, 5.5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 22, 24, 26]
|
|
908
935
|
},
|
|
909
|
-
"mm": {
|
|
936
|
+
"mm [QPF]": {
|
|
910
937
|
"colormap": [0.3, "#eeccff", 2.5, "#ff9999", 7.5, "#cc3366", 10, "#cc0066", 20, "#ffee00", 30, "#00cccc", 70, "#99ffff"],
|
|
911
938
|
"breakpoints": [0.3, 2.5, 5, 7.5, 10, 12.5, 15, 17.5, 20, 22.5, 25, 27.5, 30, 32.5, 35, 37.5, 40, 45, 50, 55, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 220, 240, 260]
|
|
912
939
|
}
|
|
@@ -921,11 +948,11 @@ const DEFAULT_COLORMAPS = exports.DEFAULT_COLORMAPS = {
|
|
|
921
948
|
"colormap": [0.01, "#eeccff", .1, "#ff9999", .3, "#cc3366", .4, "#cc0033", .5, "#ff9933", .9, "#ffee00", 1, "#00cccc", 3, "#99ffff"],
|
|
922
949
|
"breakpoints": [0.01, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.25, 1.5, 1.75, 2, 2.5, 3]
|
|
923
950
|
},
|
|
924
|
-
"cm": {
|
|
951
|
+
"cm [QPF]": {
|
|
925
952
|
"colormap": [0.03, "#eeccff", .25, "#ff9999", .75, "#cc3366", 1, "#cc0033", 2, "#ffee00", 3, "#00cccc", 7, "#99ffff"],
|
|
926
953
|
"breakpoints": [.03, .25, .5, .75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.5, 5, 5.5, 6, 7, 8, 9, 10, 12, 14, 16]
|
|
927
954
|
},
|
|
928
|
-
"mm": {
|
|
955
|
+
"mm [QPF]": {
|
|
929
956
|
"colormap": [0.3, "#eeccff", 2.5, "#ff9999", 7.5, "#cc3366", 10, "#cc0033", 20, "#ffee00", 30, "#00cccc", 70, "#99ffff"],
|
|
930
957
|
"breakpoints": [0.3, 2.5, 5, 7.5, 10, 12.5, 15, 17.5, 20, 22.5, 25, 27.5, 30, 32.5, 35, 37.5, 40, 45, 50, 55, 60, 70, 80, 90, 100, 120, 140, 160]
|
|
931
958
|
}
|