@aguacerowx/javascript-sdk 0.0.4 → 0.0.6
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 +1 -1
- package/src/AguaceroCore.js +84 -16
- package/src/dictionaries.js +1 -1
package/package.json
CHANGED
package/src/AguaceroCore.js
CHANGED
|
@@ -7,7 +7,6 @@ import { getUnitConversionFunction } from './unitConversions.js';
|
|
|
7
7
|
import { DICTIONARIES, MODEL_CONFIGS } from './dictionaries.js';
|
|
8
8
|
import { DEFAULT_COLORMAPS } from './default-colormaps.js';
|
|
9
9
|
import proj4 from 'proj4';
|
|
10
|
-
import { decompress } from 'fzstd';
|
|
11
10
|
import { getBundleId } from './getBundleId';
|
|
12
11
|
|
|
13
12
|
// --- Non-UI Helper Functions ---
|
|
@@ -161,6 +160,7 @@ export class AguaceroCore extends EventEmitter {
|
|
|
161
160
|
|
|
162
161
|
play() {
|
|
163
162
|
if (this.isPlaying) return;
|
|
163
|
+
console.log('▶️ [Core] Play called');
|
|
164
164
|
this.isPlaying = true;
|
|
165
165
|
clearInterval(this.playIntervalId);
|
|
166
166
|
this.playIntervalId = setInterval(() => { this.step(1); }, this.playbackSpeed);
|
|
@@ -170,6 +170,7 @@ export class AguaceroCore extends EventEmitter {
|
|
|
170
170
|
|
|
171
171
|
pause() {
|
|
172
172
|
if (!this.isPlaying) return;
|
|
173
|
+
console.log('⏸️ [Core] Pause called');
|
|
173
174
|
this.isPlaying = false;
|
|
174
175
|
clearInterval(this.playIntervalId);
|
|
175
176
|
this.playIntervalId = null;
|
|
@@ -177,19 +178,65 @@ export class AguaceroCore extends EventEmitter {
|
|
|
177
178
|
this._emitStateChange(); // Notify UI that isPlaying is now false
|
|
178
179
|
}
|
|
179
180
|
|
|
180
|
-
togglePlay() {
|
|
181
|
+
togglePlay() {
|
|
182
|
+
console.log('⏯️ [Core] Toggle Play called');
|
|
183
|
+
this.isPlaying ? this.pause() : this.play();
|
|
184
|
+
}
|
|
181
185
|
|
|
182
186
|
step(direction = 1) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
187
|
+
console.log(`[Core.step] Stepping... Direction: ${direction}, Mode: ${this.state.isMRMS ? 'MRMS' : 'Model'}`);
|
|
188
|
+
|
|
189
|
+
// --- THIS IS THE CORRECTED MRMS LOGIC ---
|
|
190
|
+
if (this.state.isMRMS) {
|
|
191
|
+
const { variable, mrmsTimestamp } = this.state;
|
|
192
|
+
if (!this.mrmsStatus || !this.mrmsStatus[variable]) {
|
|
193
|
+
console.warn('[Core.step] MRMS status or variable not available.');
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// CRITICAL FIX: The UI and state emissions use a REVERSED array (newest first).
|
|
198
|
+
// The step logic MUST use the same reversed array for indexes to match.
|
|
199
|
+
const availableTimestamps = [...(this.mrmsStatus[variable] || [])].reverse();
|
|
200
|
+
if (availableTimestamps.length === 0) return;
|
|
201
|
+
|
|
202
|
+
const currentIndex = availableTimestamps.indexOf(mrmsTimestamp);
|
|
203
|
+
console.log(`[Core.step] MRMS Current Timestamp: ${mrmsTimestamp}, Index: ${currentIndex}`);
|
|
204
|
+
|
|
205
|
+
if (currentIndex === -1) {
|
|
206
|
+
// If not found, reset to the first (newest) frame
|
|
207
|
+
this.setState({ mrmsTimestamp: availableTimestamps[0] });
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const maxIndex = availableTimestamps.length - 1;
|
|
212
|
+
let nextIndex = currentIndex + direction;
|
|
213
|
+
|
|
214
|
+
// Loop animation
|
|
215
|
+
if (nextIndex > maxIndex) nextIndex = 0;
|
|
216
|
+
if (nextIndex < 0) nextIndex = maxIndex;
|
|
217
|
+
|
|
218
|
+
const newTimestamp = availableTimestamps[nextIndex];
|
|
219
|
+
console.log(`[Core.step] MRMS New Index: ${nextIndex}, New Timestamp: ${newTimestamp}`);
|
|
220
|
+
this.setState({ mrmsTimestamp: newTimestamp });
|
|
221
|
+
|
|
222
|
+
} else {
|
|
223
|
+
const { model, date, run, forecastHour } = this.state;
|
|
224
|
+
const forecastHours = this.modelStatus?.[model]?.[date]?.[run];
|
|
225
|
+
if (!forecastHours || forecastHours.length === 0) return;
|
|
226
|
+
|
|
227
|
+
const currentIndex = forecastHours.indexOf(forecastHour);
|
|
228
|
+
console.log(`[Core.step] Model Current Hour: ${forecastHour}, Index: ${currentIndex}`);
|
|
229
|
+
if (currentIndex === -1) return;
|
|
230
|
+
|
|
231
|
+
const maxIndex = forecastHours.length - 1;
|
|
232
|
+
let nextIndex = currentIndex + direction;
|
|
233
|
+
if (nextIndex > maxIndex) nextIndex = 0;
|
|
234
|
+
if (nextIndex < 0) nextIndex = maxIndex;
|
|
235
|
+
|
|
236
|
+
const newHour = forecastHours[nextIndex];
|
|
237
|
+
console.log(`[Core.step] Model New Index: ${nextIndex}, New Hour: ${newHour}`);
|
|
238
|
+
this.setState({ forecastHour: newHour });
|
|
239
|
+
}
|
|
193
240
|
}
|
|
194
241
|
|
|
195
242
|
setPlaybackSpeed(speed) {
|
|
@@ -364,7 +411,7 @@ export class AguaceroCore extends EventEmitter {
|
|
|
364
411
|
const baseUrl = `${this.baseGridUrl}${resourcePath}`;
|
|
365
412
|
const urlWithApiKeyParam = `${baseUrl}?apiKey=${this.apiKey}`;
|
|
366
413
|
const headers = { 'x-api-key': this.apiKey };
|
|
367
|
-
if (this.bundleId) {
|
|
414
|
+
if (this.bundleId && this.isReactNative) {
|
|
368
415
|
headers['x-app-identifier'] = this.bundleId;
|
|
369
416
|
}
|
|
370
417
|
|
|
@@ -455,12 +502,33 @@ export class AguaceroCore extends EventEmitter {
|
|
|
455
502
|
const index1D = j * nx + i;
|
|
456
503
|
const byteValue = gridData.data[index1D];
|
|
457
504
|
const signedQuantizedValue = byteValue - 128;
|
|
458
|
-
|
|
505
|
+
|
|
506
|
+
// --- START OF FIX ---
|
|
507
|
+
// You were missing 'scale_type' in this destructuring assignment.
|
|
508
|
+
const { scale, offset, missing_quantized, scale_type } = gridData.encoding;
|
|
509
|
+
// --- END OF FIX ---
|
|
459
510
|
|
|
460
511
|
if (signedQuantizedValue === missing_quantized) return null;
|
|
461
512
|
|
|
462
|
-
const
|
|
463
|
-
|
|
513
|
+
const intermediateValue = signedQuantizedValue * scale + offset;
|
|
514
|
+
|
|
515
|
+
// Step 2: Apply non-linear scaling if specified
|
|
516
|
+
let nativeValue = intermediateValue;
|
|
517
|
+
if (scale_type === 'sqrt') {
|
|
518
|
+
// Square the value while preserving its sign
|
|
519
|
+
nativeValue = intermediateValue < 0 ? -(intermediateValue * intermediateValue) : (intermediateValue * intermediateValue);
|
|
520
|
+
}
|
|
521
|
+
const { colormap, baseUnit } = this._getColormapForVariable(variable);
|
|
522
|
+
|
|
523
|
+
// If the value is outside the colormap's bounds, return null.
|
|
524
|
+
if (colormap && colormap.length >= 2) {
|
|
525
|
+
const minBound = colormap[0];
|
|
526
|
+
const maxBound = colormap[colormap.length - 2];
|
|
527
|
+
if (nativeValue < minBound || nativeValue > maxBound) {
|
|
528
|
+
return null;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
464
532
|
let dataNativeUnit = baseUnit || (DICTIONARIES.fld[variable] || {}).defaultUnit || 'none';
|
|
465
533
|
|
|
466
534
|
const displayUnit = this._getTargetUnit(dataNativeUnit, units);
|
package/src/dictionaries.js
CHANGED
|
@@ -278,7 +278,7 @@ export const MODEL_CONFIGS = {
|
|
|
278
278
|
},
|
|
279
279
|
'gfs': {
|
|
280
280
|
max_zoom: 3,
|
|
281
|
-
vars: ['2r_2', '2t_2', 'refd_1000', 'vis_0', 'gust_runmax', "gh_tendency_500", 'bulk_shear_speedmb_500', 'bulk_shear_speedmb_700', 'bulk_shear_speedmb_850', 'bulk_shear_speedmb_925','2t_2iso0', 'crain_total', 'crain_3', 'crain_6', 'crain_12', 'crain_24', 'crain_48', 'cicep_total', 'cicep_3', 'cicep_6', 'cicep_12', 'cicep_24', 'cicep_48', 'cfrzr_total', 'cfrzr_3', 'cfrzr_6', 'cfrzr_12', 'cfrzr_24', 'cfrzr_48', 'csnow_total', 'csnow_3', 'csnow_6', 'csnow_12', 'csnow_24', 'csnow_48', '
|
|
281
|
+
vars: ['tp_0_total', '2r_2', '2t_2', 'refd_1000', 'vis_0', 'gust_runmax', "gh_tendency_500", 'bulk_shear_speedmb_500', 'bulk_shear_speedmb_700', 'bulk_shear_speedmb_850', 'bulk_shear_speedmb_925','2t_2iso0', 'crain_total', 'crain_3', 'crain_6', 'crain_12', 'crain_24', 'crain_48', 'cicep_total', 'cicep_3', 'cicep_6', 'cicep_12', 'cicep_24', 'cicep_48', 'cfrzr_total', 'cfrzr_3', 'cfrzr_6', 'cfrzr_12', 'cfrzr_24', 'cfrzr_48', 'csnow_total', 'csnow_3', 'csnow_6', 'csnow_12', 'csnow_24', 'csnow_48', 'tp_3', 'tp_6', 'tp_12', 'tp_24', 'tp_48', 'cin_0', 'wind_speed_700', 'wind_speed_200', 'divergence_200', 'd_925', 'tadv_300', 'w_850', 'rainRefl', 'icepRefl', 'snowRefl', 'frzrRefl', 'lftx_0', 'refc_0', 'fgen_850', 'hcc_0', 'r_700', 't_850', 't_850iso0', 'r_850', 'tcc_0', 'hlcy_3000', 'thickness', 'vo_850', 'wind_direction_2000', 'r_500', 'gh_500', 'wind_speed_500', '2d_2', 'cape_25500', 'mcc_0', 'w_500', 'pwat_0', 'divergence_850', 't_500', 'wind_speed_850', 'lcl', 'cape_0', 'tadv_850', 'tadv_700', 'theta2PVU', 'wind_speed_2000', 'lapse_rates_500700', 'vo_500', 'irsat', 't_700', 't_700iso0', 'cin_25500', 'ehi_3000', 'lcc_0', 'gh_850', 'wind_speed_925', 'gh_200', 'wind_speed_300', 'fgen_700', 'vo_700', 'd_850', 'thetaE', 'pres2PVU', 'd_700', 'crain', 'csnow', 'cicep', 'cfrzr', 'w_700', 'gust_0', 'ivt', 'atemp', 'cape_9000', 'r_925', 'mslma_0', 'w_925', 'cin_9000', 'mean700300mbRH', 'wind_speed_10', 't_925', 't_925iso0', 'gh_925', 'gh_700', 'gh_300'],
|
|
282
282
|
category: 'Global',
|
|
283
283
|
name: 'GFS',
|
|
284
284
|
bounds: [-180, -90, 180, 90],
|