@aguacerowx/react-native 0.0.21 → 0.0.23

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.
Files changed (100) hide show
  1. package/aguacerowx-react-native.podspec +5 -20
  2. package/android/build/.transforms/42e9b8fa82d77a1c205db5bf0d0ed519/transformed/classes/classes_dex/classes.dex +0 -0
  3. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.dex +0 -0
  4. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/aguacerowx/reactnative/GridRenderLayer.dex +0 -0
  5. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  6. package/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_fragment_shader.glsl.flat +0 -0
  7. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
  8. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
  9. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  10. package/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/fragment_shader.glsl +18 -8
  11. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
  12. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  13. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  14. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer$VertexInfo.class.uniqueId0 +0 -0
  15. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId1 +0 -0
  16. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  17. package/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +8 -1
  18. package/android/src/main/res/raw/fragment_shader.glsl +18 -8
  19. package/ios/FragmentUniforms.swift +1 -0
  20. package/ios/GridRenderLayer.swift +117 -109
  21. package/ios/GridRenderLayerBridge.swift +11 -3
  22. package/ios/GridRenderLayerView.h +15 -1
  23. package/ios/GridRenderLayerView.m +65 -28
  24. package/ios/Shaders.metal +25 -13
  25. package/ios/compiled-shaders/Shaders-device.metallib +0 -0
  26. package/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  27. package/lib/commonjs/aguacerowx-react-native.podspec +5 -20
  28. package/lib/commonjs/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  29. package/lib/commonjs/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_fragment_shader.glsl.flat +0 -0
  30. package/lib/commonjs/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
  31. package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
  32. package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  33. package/lib/commonjs/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/fragment_shader.glsl +18 -8
  34. package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
  35. package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  36. package/lib/commonjs/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  37. package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer$VertexInfo.class.uniqueId0 +0 -0
  38. package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId1 +0 -0
  39. package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  40. package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +8 -1
  41. package/lib/commonjs/android/src/main/res/raw/fragment_shader.glsl +18 -8
  42. package/lib/commonjs/ios/FragmentUniforms.swift +1 -0
  43. package/lib/commonjs/ios/GridRenderLayer.swift +117 -109
  44. package/lib/commonjs/ios/GridRenderLayerBridge.swift +11 -3
  45. package/lib/commonjs/ios/GridRenderLayerView.h +15 -1
  46. package/lib/commonjs/ios/GridRenderLayerView.m +65 -28
  47. package/lib/commonjs/ios/Shaders.metal +25 -13
  48. package/lib/commonjs/ios/compiled-shaders/Shaders-device.metallib +0 -0
  49. package/lib/commonjs/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  50. package/lib/commonjs/package.json +2 -2
  51. package/lib/commonjs/scripts/compile-shaders.js.map +1 -1
  52. package/lib/commonjs/src/WeatherLayerManager.js +50 -5
  53. package/lib/commonjs/src/WeatherLayerManager.js.map +1 -1
  54. package/lib/module/aguacerowx-react-native.podspec +5 -20
  55. package/lib/module/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  56. package/lib/module/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_fragment_shader.glsl.flat +0 -0
  57. package/lib/module/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
  58. package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
  59. package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  60. package/lib/module/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/fragment_shader.glsl +18 -8
  61. package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
  62. package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  63. package/lib/module/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  64. package/lib/module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer$VertexInfo.class.uniqueId0 +0 -0
  65. package/lib/module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId1 +0 -0
  66. package/lib/module/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  67. package/lib/module/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +8 -1
  68. package/lib/module/android/src/main/res/raw/fragment_shader.glsl +18 -8
  69. package/lib/module/ios/FragmentUniforms.swift +1 -0
  70. package/lib/module/ios/GridRenderLayer.swift +117 -109
  71. package/lib/module/ios/GridRenderLayerBridge.swift +11 -3
  72. package/lib/module/ios/GridRenderLayerView.h +15 -1
  73. package/lib/module/ios/GridRenderLayerView.m +65 -28
  74. package/lib/module/ios/Shaders.metal +25 -13
  75. package/lib/module/ios/compiled-shaders/Shaders-device.metallib +0 -0
  76. package/lib/module/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  77. package/lib/module/lib/commonjs/aguacerowx-react-native.podspec +5 -20
  78. package/lib/module/lib/commonjs/ios/FragmentUniforms.swift +1 -0
  79. package/lib/module/lib/commonjs/ios/GridRenderLayer.swift +117 -109
  80. package/lib/module/lib/commonjs/ios/GridRenderLayerBridge.swift +11 -3
  81. package/lib/module/lib/commonjs/ios/GridRenderLayerView.h +15 -1
  82. package/lib/module/lib/commonjs/ios/GridRenderLayerView.m +65 -28
  83. package/lib/module/lib/commonjs/ios/Shaders.metal +25 -13
  84. package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders-device.metallib +0 -0
  85. package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  86. package/lib/module/lib/commonjs/package.json +2 -2
  87. package/lib/module/lib/commonjs/scripts/compile-shaders.js.map +1 -1
  88. package/lib/module/lib/commonjs/src/WeatherLayerManager.js +50 -5
  89. package/lib/module/lib/commonjs/src/WeatherLayerManager.js.map +1 -1
  90. package/lib/module/package.json +2 -2
  91. package/lib/module/scripts/compile-shaders.js.map +1 -1
  92. package/lib/module/src/WeatherLayerManager.js +50 -5
  93. package/lib/module/src/WeatherLayerManager.js.map +1 -1
  94. package/lib/typescript/src/WeatherLayerManager.d.ts.map +1 -1
  95. package/package.json +2 -2
  96. package/src/WeatherLayerManager.js +208 -165
  97. package/ios/compiled-shaders/Shaders.metallib +0 -0
  98. package/lib/commonjs/ios/compiled-shaders/Shaders.metallib +0 -0
  99. package/lib/module/ios/compiled-shaders/Shaders.metallib +0 -0
  100. package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders.metallib +0 -0
@@ -67,13 +67,19 @@ AguaceroCore.prototype.setMapCenter = function(center) {
67
67
  };
68
68
 
69
69
  export const WeatherLayerManager = forwardRef((props, ref) => {
70
- const { inspectorEnabled, onInspect, apiKey, customColormaps, ...restProps } = props;
70
+ // EDIT: Destructure the new props
71
+ const { inspectorEnabled, onInspect, apiKey, customColormaps, initialMode, initialVariable, ...restProps } = props;
71
72
  const context = useContext(AguaceroContext);
72
73
 
73
74
  // Create the core here instead of getting it from context
74
75
  const core = useMemo(() => new AguaceroCore({
75
76
  apiKey: apiKey,
76
- customColormaps: customColormaps
77
+ customColormaps: customColormaps,
78
+ // ADD: Pass layerOptions to the core's constructor
79
+ layerOptions: {
80
+ mode: initialMode,
81
+ variable: initialVariable
82
+ }
77
83
  }), [apiKey]);
78
84
 
79
85
  const gridLayerRef = useRef(null);
@@ -134,183 +140,202 @@ export const WeatherLayerManager = forwardRef((props, ref) => {
134
140
  };
135
141
  }, [core]);
136
142
 
137
- const preloadAllFramesToDisk = (state) => {
138
-
139
- if (hasPreloadedRef.current) {
140
- console.log('✅ [Preload] Gating preload; already initiated for this dataset.');
141
- return;
142
- }
143
- hasPreloadedRef.current = true;
144
- console.log('🚀 [Preload] Initiating parallel preload for new dataset...');
145
-
146
- const { isMRMS, model, date, run, variable, units, availableHours, availableTimestamps, forecastHour, mrmsTimestamp } = state;
147
-
148
- // NEW: Fix the current forecast hour if it's invalid for this variable/model combo
149
- let effectiveForecastHour = forecastHour;
150
- if (!isMRMS && variable === 'ptypeRefl' && model === 'hrrr' && forecastHour === 0) {
151
- const validHours = availableHours.filter(hour => hour !== 0);
152
- effectiveForecastHour = validHours.length > 0 ? validHours[0] : 0;
153
- console.log(`⚠️ [Preload] Correcting invalid hour 0 to ${effectiveForecastHour} for HRRR ptypeRefl`);
154
- }
155
-
156
- if (!cachedGeometry.current || !cachedColormap.current) {
157
- const gridModel = isMRMS ? 'mrms' : model;
158
- const { corners, gridDef } = core._getGridCornersAndDef(gridModel);
159
- gridLayerRef.current.updateGeometry(corners, gridDef);
160
- cachedGeometry.current = { model: gridModel, variable };
161
-
162
- const { colormap, baseUnit } = core._getColormapForVariable(variable);
163
- const toUnit = core._getTargetUnit(baseUnit, units);
164
- const finalColormap = core._convertColormapUnits(colormap, baseUnit, toUnit);
165
- const dataRange = [finalColormap[0], finalColormap[finalColormap.length - 2]];
166
- const colormapBytes = _generateColormapBytes(finalColormap);
167
- const colormapAsBase64 = fromByteArray(colormapBytes);
168
-
169
- gridLayerRef.current.updateColormapTexture(colormapAsBase64);
170
- cachedColormap.current = { key: `${variable}-${units}` };
171
- cachedDataRange.current = dataRange;
143
+ const preloadAllFramesToDisk = (state) => {
172
144
 
173
- setRenderProps({ opacity: state.opacity, dataRange: dataRange });
174
- hasInitialLoad.current = true;
175
- }
145
+ if (hasPreloadedRef.current) {
146
+ console.log('✅ [Preload] Gating preload; already initiated for this dataset.');
147
+ return;
148
+ }
149
+ hasPreloadedRef.current = true;
150
+ console.log('🚀 [Preload] Initiating parallel preload for new dataset...');
176
151
 
177
- // Apply the same filtering logic as in AguaceroCore._emitStateChange
178
- let filteredHours = availableHours;
179
- if (!isMRMS && variable === 'ptypeRefl' && model === 'hrrr' && availableHours && availableHours.length > 0) {
180
- filteredHours = availableHours.filter(hour => hour !== 0);
181
- }
152
+ const { isMRMS, model, date, run, variable, units, availableHours, availableTimestamps, forecastHour, mrmsTimestamp } = state;
182
153
 
183
- const allFrames = isMRMS ? availableTimestamps : filteredHours;
184
- if (!allFrames || allFrames.length === 0) {
185
- console.warn('🟡 [preloadAllFramesToDisk] No frames available to download.');
186
- return;
187
- }
154
+ // NEW: Fix the current forecast hour if it's invalid for this variable/model combo
155
+ let effectiveForecastHour = forecastHour;
156
+ if (!isMRMS && variable === 'ptypeRefl' && model === 'hrrr' && forecastHour === 0) {
157
+ const validHours = availableHours.filter(hour => hour !== 0);
158
+ effectiveForecastHour = validHours.length > 0 ? validHours[0] : 0;
159
+ console.log(`⚠️ [Preload] Correcting invalid hour 0 to ${effectiveForecastHour} for HRRR ptypeRefl`);
160
+ }
188
161
 
189
- const currentFrame = isMRMS ? mrmsTimestamp : effectiveForecastHour;
190
- const prioritizedFrames = [
191
- currentFrame,
192
- ...allFrames.filter(frame => frame !== currentFrame)
193
- ];
194
- console.log(`[Preload] Prioritizing frame: ${currentFrame}. Total frames: ${prioritizedFrames.length}`);
162
+ if (!cachedGeometry.current || !cachedColormap.current) {
163
+ const gridModel = isMRMS ? 'mrms' : model;
164
+ const { corners, gridDef } = core._getGridCornersAndDef(gridModel);
165
+ gridLayerRef.current.updateGeometry(corners, gridDef);
166
+ cachedGeometry.current = { model: gridModel, variable };
195
167
 
196
- const { corners, gridDef } = core._getGridCornersAndDef(isMRMS ? 'mrms' : model);
197
- const { nx, ny } = gridDef.grid_params;
168
+ const { colormap, baseUnit } = core._getColormapForVariable(variable);
169
+ const toUnit = core._getTargetUnit(baseUnit, units);
170
+ const finalColormap = core._convertColormapUnits(colormap, baseUnit, toUnit);
171
+ let dataRange;
172
+ if (variable === 'ptypeRefl' || variable === 'ptypeRate') {
173
+ if (isMRMS) {
174
+ console.log('🔧 Using MRMS ptype data range: 5-380');
175
+ dataRange = [5, 380];
176
+ } else {
177
+ console.log('🔧 Using Model ptype data range: 5-380');
178
+ dataRange = [5, 380];
179
+ }
180
+ } else {
181
+ dataRange = [finalColormap[0], finalColormap[finalColormap.length - 2]];
182
+ }
183
+ const colormapBytes = _generateColormapBytes(finalColormap);
184
+ const colormapAsBase64 = fromByteArray(colormapBytes);
185
+
186
+ gridLayerRef.current.updateColormapTexture(colormapAsBase64);
187
+ cachedColormap.current = { key: `${variable}-${units}` };
188
+ cachedDataRange.current = dataRange;
189
+
190
+ setRenderProps({ opacity: state.opacity, dataRange: dataRange });
191
+ hasInitialLoad.current = true;
192
+ }
198
193
 
199
- prioritizedFrames.forEach((frame, index) => {
200
- const cacheKey = isMRMS ? `mrms-${frame}-${variable}` : `${model}-${date}-${run}-${frame}-${variable}`;
201
- if (preloadedDataCache.current.has(cacheKey)) {
202
- return;
194
+ // Apply the same filtering logic as in AguaceroCore._emitStateChange
195
+ let filteredHours = availableHours;
196
+ if (!isMRMS && variable === 'ptypeRefl' && model === 'hrrr' && availableHours && availableHours.length > 0) {
197
+ filteredHours = availableHours.filter(hour => hour !== 0);
203
198
  }
204
199
 
205
- let resourcePath;
206
- if (isMRMS) {
207
- const frameDate = new Date(frame * 1000);
208
- const y = frameDate.getUTCFullYear();
209
- const m = (frameDate.getUTCMonth() + 1).toString().padStart(2, '0');
210
- const d = frameDate.getUTCDate().toString().padStart(2, '0');
211
- resourcePath = `/grids/mrms/${y}${m}${d}/${frame}/0/${variable}/0`;
212
- } else {
213
- resourcePath = `/grids/${model}/${date}/${run}/${frame}/${variable}/0`;
200
+ const allFrames = isMRMS ? availableTimestamps : filteredHours;
201
+ if (!allFrames || allFrames.length === 0) {
202
+ console.warn('🟡 [preloadAllFramesToDisk] No frames available to download.');
203
+ return;
214
204
  }
215
205
 
216
- const url = `${core.baseGridUrl}${resourcePath}?apiKey=${core.apiKey}`;
217
- const options = { url, apiKey: core.apiKey, bundleId: core.bundleId };
206
+ const currentFrame = isMRMS ? mrmsTimestamp : effectiveForecastHour;
218
207
 
219
- WeatherFrameProcessorModule.processFrame(options)
220
- .then(result => {
221
- if (!result || !result.filePath) {
222
- console.warn(`⚠️ [preloadAllFramesToDisk] Failed frame ${frame}: No filePath`);
223
- return;
224
- }
225
-
226
- const { baseUnit } = core._getColormapForVariable(variable);
227
- const toUnit = core._getTargetUnit(baseUnit, units);
228
-
229
- let dataScale = result.scale;
230
- let dataOffset = result.offset;
231
-
232
- let convertedScale = dataScale;
233
- let convertedOffset = dataOffset;
234
-
235
- if (baseUnit !== toUnit) {
236
- const conversionFunc = getUnitConversionFunction(baseUnit, toUnit);
237
- if (conversionFunc) {
238
- if (result.scaleType === 'sqrt') {
239
- const physicalAtOffset = dataOffset * dataOffset;
240
- const physicalAtOffsetPlusScale = (dataOffset + dataScale) * (dataOffset + dataScale);
241
- const convertedPhysicalAtOffset = conversionFunc(physicalAtOffset);
242
- const convertedPhysicalAtOffsetPlusScale = conversionFunc(physicalAtOffsetPlusScale);
243
- convertedOffset = Math.sqrt(Math.abs(convertedPhysicalAtOffset)) * Math.sign(convertedPhysicalAtOffset);
244
- const newOffsetPlusScale = Math.sqrt(Math.abs(convertedPhysicalAtOffsetPlusScale)) * Math.sign(convertedPhysicalAtOffsetPlusScale);
245
- convertedScale = newOffsetPlusScale - convertedOffset;
246
- } else {
247
- convertedOffset = conversionFunc(dataOffset);
248
- const convertedOffsetPlusScale = conversionFunc(dataOffset + dataScale);
249
- convertedScale = convertedOffsetPlusScale - convertedOffset;
208
+ // --- EDIT: Reverse the frame order to load from last to first ---
209
+ const reversedFrames = [...allFrames].reverse();
210
+ const framesToPreload = reversedFrames.filter(frame => frame !== currentFrame);
211
+
212
+ // The final array will process the current frame first, then the rest in reverse chronological order.
213
+ const prioritizedFrames = [
214
+ currentFrame,
215
+ ...framesToPreload
216
+ ];
217
+ // --- END EDIT ---
218
+
219
+ console.log(`[Preload] Prioritizing frame: ${currentFrame}. Total frames: ${prioritizedFrames.length}`);
220
+
221
+ const { corners, gridDef } = core._getGridCornersAndDef(isMRMS ? 'mrms' : model);
222
+ const { nx, ny } = gridDef.grid_params;
223
+
224
+ prioritizedFrames.forEach((frame, index) => {
225
+ const cacheKey = isMRMS ? `mrms-${frame}-${variable}` : `${model}-${date}-${run}-${frame}-${variable}`;
226
+ if (preloadedDataCache.current.has(cacheKey)) {
227
+ return;
228
+ }
229
+
230
+ let resourcePath;
231
+ if (isMRMS) {
232
+ const frameDate = new Date(frame * 1000);
233
+ const y = frameDate.getUTCFullYear();
234
+ const m = (frameDate.getUTCMonth() + 1).toString().padStart(2, '0');
235
+ const d = frameDate.getUTCDate().toString().padStart(2, '0');
236
+ resourcePath = `/grids/mrms/${y}${m}${d}/${frame}/0/${variable}/0`;
237
+ } else {
238
+ resourcePath = `/grids/${model}/${date}/${run}/${frame}/${variable}/0`;
239
+ }
240
+
241
+ const url = `${core.baseGridUrl}${resourcePath}?apiKey=${core.apiKey}`;
242
+ const options = { url, apiKey: core.apiKey, bundleId: core.bundleId };
243
+
244
+ WeatherFrameProcessorModule.processFrame(options)
245
+ .then(result => {
246
+ if (!result || !result.filePath) {
247
+ console.warn(`⚠️ [preloadAllFramesToDisk] Failed frame ${frame}: No filePath`);
248
+ return;
249
+ }
250
+
251
+ const { baseUnit } = core._getColormapForVariable(variable);
252
+ const toUnit = core._getTargetUnit(baseUnit, units);
253
+
254
+ let dataScale = result.scale;
255
+ let dataOffset = result.offset;
256
+
257
+ let convertedScale = dataScale;
258
+ let convertedOffset = dataOffset;
259
+
260
+ if (baseUnit !== toUnit) {
261
+ const conversionFunc = getUnitConversionFunction(baseUnit, toUnit);
262
+ if (conversionFunc) {
263
+ if (result.scaleType === 'sqrt') {
264
+ const physicalAtOffset = dataOffset * dataOffset;
265
+ const physicalAtOffsetPlusScale = (dataOffset + dataScale) * (dataOffset + dataScale);
266
+ const convertedPhysicalAtOffset = conversionFunc(physicalAtOffset);
267
+ const convertedPhysicalAtOffsetPlusScale = conversionFunc(physicalAtOffsetPlusScale);
268
+ convertedOffset = Math.sqrt(Math.abs(convertedPhysicalAtOffset)) * Math.sign(convertedPhysicalAtOffset);
269
+ const newOffsetPlusScale = Math.sqrt(Math.abs(convertedPhysicalAtOffsetPlusScale)) * Math.sign(convertedPhysicalAtOffsetPlusScale);
270
+ convertedScale = newOffsetPlusScale - convertedOffset;
271
+ } else {
272
+ convertedOffset = conversionFunc(dataOffset);
273
+ const convertedOffsetPlusScale = conversionFunc(dataOffset + dataScale);
274
+ convertedScale = convertedOffsetPlusScale - convertedOffset;
275
+ }
250
276
  }
251
277
  }
252
- }
253
-
254
- const frameData = {
255
- filePath: result.filePath,
256
- nx, ny,
257
- scale: convertedScale,
258
- offset: convertedOffset,
259
- missing: result.missing,
260
- corners,
261
- gridDef,
262
- scaleType: result.scaleType,
263
- originalScale: result.scale,
264
- originalOffset: result.offset
265
- };
266
-
267
- preloadedDataCache.current.set(cacheKey, frameData);
268
-
269
- const isCurrentFrame = index === 0;
270
-
271
- if (isCurrentFrame) {
272
- console.log(`🎯 [Preload] Using FAST LANE to process and draw current frame (${frame}) immediately.`);
273
- gridLayerRef.current.updateDataTextureFromFile(
274
- frameData.filePath,
275
- frameData.nx, frameData.ny,
276
- frameData.scale, frameData.offset, frameData.missing,
277
- frameData.scaleType
278
- );
279
-
280
- currentGridDataRef.current = {
281
- nx: frameData.nx,
282
- ny: frameData.ny,
283
- scale: frameData.scale,
284
- offset: frameData.offset,
285
- missing: frameData.missing,
286
- gridDef: frameData.gridDef,
287
- variable: variable,
288
- units: units
278
+
279
+ const frameData = {
280
+ filePath: result.filePath,
281
+ nx, ny,
282
+ scale: convertedScale,
283
+ offset: convertedOffset,
284
+ missing: result.missing,
285
+ corners,
286
+ gridDef,
287
+ scaleType: result.scaleType,
288
+ originalScale: result.scale,
289
+ originalOffset: result.offset
289
290
  };
290
- } else {
291
- if (Platform.OS === 'ios' && gridLayerRef.current.primeGpuCache) {
292
- const frameInfoForGpu = {
293
- [cacheKey]: {
294
- filePath: frameData.filePath,
295
- nx: frameData.nx,
296
- ny: frameData.ny,
297
- scale: frameData.scale,
298
- offset: frameData.offset,
299
- missing: frameData.missing,
300
- scaleType: frameData.scaleType || 'linear',
301
- originalScale: frameData.originalScale,
302
- originalOffset: frameData.originalOffset
303
- }
291
+
292
+ preloadedDataCache.current.set(cacheKey, frameData);
293
+
294
+ const isCurrentFrame = index === 0;
295
+
296
+ if (isCurrentFrame) {
297
+ console.log(`🎯 [Preload] Using FAST LANE to process and draw current frame (${frame}) immediately.`);
298
+ gridLayerRef.current.updateDataTextureFromFile(
299
+ frameData.filePath,
300
+ frameData.nx, frameData.ny,
301
+ frameData.scale, frameData.offset, frameData.missing,
302
+ frameData.scaleType
303
+ );
304
+
305
+ currentGridDataRef.current = {
306
+ nx: frameData.nx,
307
+ ny: frameData.ny,
308
+ scale: frameData.scale,
309
+ offset: frameData.offset,
310
+ missing: frameData.missing,
311
+ gridDef: frameData.gridDef,
312
+ variable: variable,
313
+ units: units
304
314
  };
305
- gridLayerRef.current.primeGpuCache(frameInfoForGpu);
315
+ } else {
316
+ if (Platform.OS === 'ios' && gridLayerRef.current.primeGpuCache) {
317
+ const frameInfoForGpu = {
318
+ [cacheKey]: {
319
+ filePath: frameData.filePath,
320
+ nx: frameData.nx,
321
+ ny: frameData.ny,
322
+ scale: frameData.scale,
323
+ offset: frameData.offset,
324
+ missing: frameData.missing,
325
+ scaleType: frameData.scaleType || 'linear',
326
+ originalScale: frameData.originalScale,
327
+ originalOffset: frameData.originalOffset
328
+ }
329
+ };
330
+ gridLayerRef.current.primeGpuCache(frameInfoForGpu);
331
+ }
306
332
  }
307
- }
308
- })
309
- .catch(error => {
310
- console.warn(`⚠️ [preloadAllFramesToDisk] Failed frame ${frame}:`, error);
311
- });
312
- });
313
- };
333
+ })
334
+ .catch(error => {
335
+ console.warn(`⚠️ [preloadAllFramesToDisk] Failed frame ${frame}:`, error);
336
+ });
337
+ });
338
+ };
314
339
 
315
340
  const updateGPUWithCachedData = (state) => {
316
341
  const { model, date, run, forecastHour, variable, units, isMRMS, mrmsTimestamp } = state;
@@ -371,7 +396,16 @@ const preloadAllFramesToDisk = (state) => {
371
396
  const { colormap, baseUnit } = core._getColormapForVariable(variable);
372
397
  const toUnit = core._getTargetUnit(baseUnit, units);
373
398
  const finalColormap = core._convertColormapUnits(colormap, baseUnit, toUnit);
374
- const dataRange = [finalColormap[0], finalColormap[finalColormap.length - 2]];
399
+ let dataRange;
400
+ if (variable === 'ptypeRefl' || variable === 'ptypeRate') {
401
+ if (isMRMS) {
402
+ dataRange = [5, 380];
403
+ } else {
404
+ dataRange = [5, 380];
405
+ }
406
+ } else {
407
+ dataRange = [finalColormap[0], finalColormap[finalColormap.length - 2]];
408
+ }
375
409
  const colormapBytes = _generateColormapBytes(finalColormap);
376
410
  const colormapAsBase64 = fromByteArray(colormapBytes);
377
411
 
@@ -618,7 +652,16 @@ const preloadAllFramesToDisk = (state) => {
618
652
  // Update the colormap AND data range
619
653
  const { colormap } = core._getColormapForVariable(variable);
620
654
  const finalColormap = core._convertColormapUnits(colormap, baseUnit, toUnit);
621
- const dataRange = [finalColormap[0], finalColormap[finalColormap.length - 2]];
655
+ let dataRange;
656
+ if (variable === 'ptypeRefl' || variable === 'ptypeRate') {
657
+ if (isMRMS) {
658
+ dataRange = [5, 380];
659
+ } else {
660
+ dataRange = [5, 380];
661
+ }
662
+ } else {
663
+ dataRange = [finalColormap[0], finalColormap[finalColormap.length - 2]];
664
+ }
622
665
 
623
666
  const colormapBytes = _generateColormapBytes(finalColormap);
624
667
  const colormapAsBase64 = fromByteArray(colormapBytes);