@aguacerowx/react-native 0.0.17 → 0.0.20

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 (108) hide show
  1. package/README.md +66 -0
  2. package/aguacerowx-react-native.podspec +27 -9
  3. package/android/build.gradle +31 -7
  4. package/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +17 -1
  5. package/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayerView.java +5 -0
  6. package/android/src/main/java/com/aguacerowx/reactnative/GridRenderManager.java +8 -0
  7. package/android/src/main/res/raw/fragment_shader.glsl +120 -66
  8. package/ios/GridRenderLayer.swift +113 -92
  9. package/ios/compiled-shaders/Shaders-device.metallib +0 -0
  10. package/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  11. package/ios/compiled-shaders/Shaders.metallib +0 -0
  12. package/lib/commonjs/README.md +66 -0
  13. package/lib/commonjs/aguacerowx-react-native.podspec +27 -9
  14. package/lib/commonjs/android/build.gradle +31 -7
  15. package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +17 -1
  16. package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayerView.java +5 -0
  17. package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/GridRenderManager.java +8 -0
  18. package/lib/commonjs/android/src/main/res/raw/fragment_shader.glsl +120 -66
  19. package/lib/commonjs/ios/GridRenderLayer.swift +113 -92
  20. package/lib/commonjs/ios/compiled-shaders/Shaders-device.metallib +0 -0
  21. package/lib/commonjs/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  22. package/lib/commonjs/ios/compiled-shaders/Shaders.metallib +0 -0
  23. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/AguaceroCore.js +128 -68
  24. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/AguaceroCore.js.map +1 -1
  25. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/default-colormaps.js +39 -12
  26. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/default-colormaps.js.map +1 -1
  27. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/dictionaries.js +38 -20
  28. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/dictionaries.js.map +1 -1
  29. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/index.js +0 -6
  30. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/index.js.map +1 -1
  31. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/package.json +1 -1
  32. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/AguaceroCore.js +28 -2
  33. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/AguaceroCore.js.map +1 -1
  34. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/default-colormaps.js +35 -8
  35. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/default-colormaps.js.map +1 -1
  36. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/dictionaries.js +38 -20
  37. package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/dictionaries.js.map +1 -1
  38. package/lib/commonjs/package.json +9 -4
  39. package/lib/commonjs/scripts/compile-shaders.sh +27 -0
  40. package/lib/commonjs/src/GridRenderLayer.js +8 -0
  41. package/lib/commonjs/src/GridRenderLayer.js.map +1 -1
  42. package/lib/commonjs/src/WeatherLayerManager.js +5 -0
  43. package/lib/commonjs/src/WeatherLayerManager.js.map +1 -1
  44. package/lib/module/README.md +66 -0
  45. package/lib/module/aguacerowx-react-native.podspec +27 -9
  46. package/lib/module/android/build.gradle +31 -7
  47. package/lib/module/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +17 -1
  48. package/lib/module/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayerView.java +5 -0
  49. package/lib/module/android/src/main/java/com/aguacerowx/reactnative/GridRenderManager.java +8 -0
  50. package/lib/module/android/src/main/res/raw/fragment_shader.glsl +120 -66
  51. package/lib/module/ios/GridRenderLayer.swift +113 -92
  52. package/lib/module/ios/compiled-shaders/Shaders-device.metallib +0 -0
  53. package/lib/module/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  54. package/lib/module/ios/compiled-shaders/Shaders.metallib +0 -0
  55. package/lib/module/lib/commonjs/README.md +66 -0
  56. package/lib/module/lib/commonjs/aguacerowx-react-native.podspec +27 -9
  57. package/lib/module/lib/commonjs/android/build.gradle +31 -7
  58. package/lib/module/lib/commonjs/ios/GridRenderLayer.swift +113 -92
  59. package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders-device.metallib +0 -0
  60. package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  61. package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders.metallib +0 -0
  62. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/AguaceroCore.js +128 -68
  63. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/AguaceroCore.js.map +1 -1
  64. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/default-colormaps.js +39 -12
  65. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/default-colormaps.js.map +1 -1
  66. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/dictionaries.js +38 -20
  67. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/dictionaries.js.map +1 -1
  68. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/index.js +0 -6
  69. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/index.js.map +1 -1
  70. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/package.json +1 -1
  71. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/AguaceroCore.js +28 -2
  72. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/AguaceroCore.js.map +1 -1
  73. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/default-colormaps.js +35 -8
  74. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/default-colormaps.js.map +1 -1
  75. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/dictionaries.js +38 -20
  76. package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/dictionaries.js.map +1 -1
  77. package/lib/module/lib/commonjs/package.json +9 -4
  78. package/lib/module/lib/commonjs/scripts/compile-shaders.sh +27 -0
  79. package/lib/module/lib/commonjs/src/GridRenderLayer.js +8 -0
  80. package/lib/module/lib/commonjs/src/GridRenderLayer.js.map +1 -1
  81. package/lib/module/lib/commonjs/src/WeatherLayerManager.js +5 -0
  82. package/lib/module/lib/commonjs/src/WeatherLayerManager.js.map +1 -1
  83. package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/AguaceroCore.js +128 -68
  84. package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/AguaceroCore.js.map +1 -1
  85. package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/default-colormaps.js +39 -12
  86. package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/default-colormaps.js.map +1 -1
  87. package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/dictionaries.js +38 -20
  88. package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/dictionaries.js.map +1 -1
  89. package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/index.js +0 -6
  90. package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/index.js.map +1 -1
  91. package/lib/module/node_modules/@aguacerowx/javascript-sdk/package.json +1 -1
  92. package/lib/module/node_modules/@aguacerowx/javascript-sdk/src/AguaceroCore.js +28 -2
  93. package/lib/module/node_modules/@aguacerowx/javascript-sdk/src/AguaceroCore.js.map +1 -1
  94. package/lib/module/node_modules/@aguacerowx/javascript-sdk/src/default-colormaps.js +35 -8
  95. package/lib/module/node_modules/@aguacerowx/javascript-sdk/src/default-colormaps.js.map +1 -1
  96. package/lib/module/node_modules/@aguacerowx/javascript-sdk/src/dictionaries.js +38 -20
  97. package/lib/module/node_modules/@aguacerowx/javascript-sdk/src/dictionaries.js.map +1 -1
  98. package/lib/module/package.json +9 -4
  99. package/lib/module/scripts/compile-shaders.sh +27 -0
  100. package/lib/module/src/GridRenderLayer.js +8 -0
  101. package/lib/module/src/GridRenderLayer.js.map +1 -1
  102. package/lib/module/src/WeatherLayerManager.js +5 -0
  103. package/lib/module/src/WeatherLayerManager.js.map +1 -1
  104. package/lib/typescript/src/GridRenderLayer.d.ts.map +1 -1
  105. package/lib/typescript/src/WeatherLayerManager.d.ts.map +1 -1
  106. package/package.json +9 -4
  107. package/src/GridRenderLayer.js +13 -0
  108. package/src/WeatherLayerManager.js +7 -0
@@ -783,99 +783,120 @@ public class GridRenderLayer: NSObject {
783
783
 
784
784
  // MARK: - Internal methods for CustomLayerHost (called by wrapper)
785
785
 
786
- internal func internalRenderingWillStart(_ metalDevice: MTLDevice, colorPixelFormat: UInt, depthStencilPixelFormat: UInt) {
787
- print("🟢 [GridRenderLayer] renderingWillStart called")
788
- self.device = metalDevice
789
- self.commandQueue = metalDevice.makeCommandQueue()
790
-
791
- let bundle = Bundle(for: GridRenderLayer.self)
792
- guard let shadersUrl = bundle.url(forResource: "AguaceroMetalShaders", withExtension: "bundle") else {
793
- print("❌ [GridRenderLayer] Could not find shader bundle")
794
- return
795
- }
796
- guard let metalBundle = Bundle(url: shadersUrl) else {
797
- print("❌ [GridRenderLayer] Could not load shader bundle")
798
- return
799
- }
800
- guard let defaultLibrary = try? metalDevice.makeDefaultLibrary(bundle: metalBundle) else {
801
- print("❌ [GridRenderLayer] Could not create Metal library")
802
- return
803
- }
804
-
805
- let vertexFunction = defaultLibrary.makeFunction(name: "vertex_main")
806
- let fragmentFunction = defaultLibrary.makeFunction(name: "fragment_main")
807
-
808
- // Set up vertex descriptor
809
- let vertexDescriptor = MTLVertexDescriptor()
810
- vertexDescriptor.attributes[0].format = .float2 // position (x, y)
811
- vertexDescriptor.attributes[0].offset = 0
812
- vertexDescriptor.attributes[0].bufferIndex = 0
813
-
814
- vertexDescriptor.attributes[1].format = .float2 // texCoord (u, v)
815
- vertexDescriptor.attributes[1].offset = MemoryLayout<Float>.size * 2
816
- vertexDescriptor.attributes[1].bufferIndex = 0
817
-
818
- vertexDescriptor.layouts[0].stride = MemoryLayout<Float>.size * 4 // 2 floats for pos + 2 for texCoord
819
- vertexDescriptor.layouts[0].stepFunction = .perVertex
820
-
821
- let pipelineDescriptor = MTLRenderPipelineDescriptor()
822
- pipelineDescriptor.vertexDescriptor = vertexDescriptor // ADD THIS LINE
823
- pipelineDescriptor.vertexFunction = vertexFunction
824
- pipelineDescriptor.fragmentFunction = fragmentFunction
825
-
826
- pipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormat(rawValue: colorPixelFormat) ?? .bgra8Unorm
827
- pipelineDescriptor.depthAttachmentPixelFormat = MTLPixelFormat(rawValue: depthStencilPixelFormat) ?? .depth32Float_stencil8
828
- pipelineDescriptor.stencilAttachmentPixelFormat = MTLPixelFormat(rawValue: depthStencilPixelFormat) ?? .depth32Float_stencil8
829
-
830
- pipelineDescriptor.colorAttachments[0].isBlendingEnabled = true
831
- pipelineDescriptor.colorAttachments[0].rgbBlendOperation = .add
832
- pipelineDescriptor.colorAttachments[0].alphaBlendOperation = .add
833
- pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
834
- pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
835
- pipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
836
- pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha
837
-
838
- do {
839
- self.pipelineState = try metalDevice.makeRenderPipelineState(descriptor: pipelineDescriptor)
840
- } catch {
841
- print("❌ [GridRenderLayer] Failed to create pipeline state: \(error)")
842
- return
843
- }
844
-
845
- let dataSamplerDesc = MTLSamplerDescriptor()
846
- dataSamplerDesc.minFilter = .nearest
847
- dataSamplerDesc.magFilter = .nearest
848
- self.dataSamplerState = metalDevice.makeSamplerState(descriptor: dataSamplerDesc)
849
-
850
- let colormapSamplerDesc = MTLSamplerDescriptor()
851
- colormapSamplerDesc.minFilter = .nearest
852
- colormapSamplerDesc.magFilter = .nearest
853
- colormapSamplerDesc.sAddressMode = .clampToEdge
854
- self.colormapSamplerState = metalDevice.makeSamplerState(descriptor: colormapSamplerDesc)
855
-
856
- print("🟢 [GridRenderLayer] Metal setup complete")
857
-
858
- // Process any pending updates that came in before Metal was ready
859
- if let pendingGeometry = pendingGeometryUpdate {
860
- print("🟡 [GridRenderLayer] Processing pending geometry update")
861
- updateGeometry(corners: pendingGeometry.corners, gridDef: pendingGeometry.gridDef)
862
- pendingGeometryUpdate = nil
863
- }
864
-
865
- if let pendingColormap = pendingColormapUpdate {
866
- print("🟡 [GridRenderLayer] Processing pending colormap update")
867
- updateColormapTexture(colormapAsBase64: pendingColormap)
868
- pendingColormapUpdate = nil
869
- }
870
-
871
- if let pendingData = pendingDataUpdate {
872
- print("🟡 [GridRenderLayer] Processing pending data update")
873
- updateDataTexture(data: pendingData.data, nx: pendingData.nx, ny: pendingData.ny,
874
- scale: pendingData.scale, offset: pendingData.offset,
875
- missing: pendingData.missing, scaleType: pendingData.scaleType)
876
- pendingDataUpdate = nil
877
- }
786
+ internal func internalRenderingWillStart(_ metalDevice: MTLDevice, colorPixelFormat: UInt, depthStencilPixelFormat: UInt) {
787
+ print("🟢 [GridRenderLayer] renderingWillStart called")
788
+ self.device = metalDevice
789
+ self.commandQueue = metalDevice.makeCommandQueue()
790
+
791
+ let bundle = Bundle(for: GridRenderLayer.self)
792
+
793
+ // Determine if we're running on simulator or device
794
+ #if targetEnvironment(simulator)
795
+ let metallibName = "Shaders-simulator"
796
+ #else
797
+ let metallibName = "Shaders-device"
798
+ #endif
799
+
800
+ // Try to load pre-compiled metallib for the current platform
801
+ let defaultLibrary: MTLLibrary?
802
+ if let metallibUrl = bundle.url(forResource: metallibName, withExtension: "metallib"),
803
+ let library = try? metalDevice.makeLibrary(URL: metallibUrl) {
804
+ print("✅ [GridRenderLayer] Loaded pre-compiled metallib (\(metallibName))")
805
+ defaultLibrary = library
806
+ }
807
+ // Fall back to compiling from .metal source (for development with npm link)
808
+ else if let metalUrl = bundle.url(forResource: "Shaders", withExtension: "metal"),
809
+ let source = try? String(contentsOf: metalUrl),
810
+ let library = try? metalDevice.makeLibrary(source: source, options: nil) {
811
+ print("✅ [GridRenderLayer] Compiled Metal shader from source")
812
+ defaultLibrary = library
813
+ }
814
+ // Neither worked
815
+ else {
816
+ print("❌ [GridRenderLayer] Could not find or compile Metal shaders")
817
+ print(" Bundle path: \(bundle.bundlePath)")
818
+ return
819
+ }
820
+
821
+ guard let library = defaultLibrary else {
822
+ print("❌ [GridRenderLayer] Failed to create Metal library")
823
+ return
824
+ }
825
+
826
+ let vertexFunction = library.makeFunction(name: "vertex_main")
827
+ let fragmentFunction = library.makeFunction(name: "fragment_main")
828
+
829
+ // Set up vertex descriptor
830
+ let vertexDescriptor = MTLVertexDescriptor()
831
+ vertexDescriptor.attributes[0].format = .float2 // position (x, y)
832
+ vertexDescriptor.attributes[0].offset = 0
833
+ vertexDescriptor.attributes[0].bufferIndex = 0
834
+
835
+ vertexDescriptor.attributes[1].format = .float2 // texCoord (u, v)
836
+ vertexDescriptor.attributes[1].offset = MemoryLayout<Float>.size * 2
837
+ vertexDescriptor.attributes[1].bufferIndex = 0
838
+
839
+ vertexDescriptor.layouts[0].stride = MemoryLayout<Float>.size * 4 // 2 floats for pos + 2 for texCoord
840
+ vertexDescriptor.layouts[0].stepFunction = .perVertex
841
+
842
+ let pipelineDescriptor = MTLRenderPipelineDescriptor()
843
+ pipelineDescriptor.vertexDescriptor = vertexDescriptor
844
+ pipelineDescriptor.vertexFunction = vertexFunction
845
+ pipelineDescriptor.fragmentFunction = fragmentFunction
846
+
847
+ pipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormat(rawValue: colorPixelFormat) ?? .bgra8Unorm
848
+ pipelineDescriptor.depthAttachmentPixelFormat = MTLPixelFormat(rawValue: depthStencilPixelFormat) ?? .depth32Float_stencil8
849
+ pipelineDescriptor.stencilAttachmentPixelFormat = MTLPixelFormat(rawValue: depthStencilPixelFormat) ?? .depth32Float_stencil8
850
+
851
+ pipelineDescriptor.colorAttachments[0].isBlendingEnabled = true
852
+ pipelineDescriptor.colorAttachments[0].rgbBlendOperation = .add
853
+ pipelineDescriptor.colorAttachments[0].alphaBlendOperation = .add
854
+ pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
855
+ pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
856
+ pipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
857
+ pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha
858
+
859
+ do {
860
+ self.pipelineState = try metalDevice.makeRenderPipelineState(descriptor: pipelineDescriptor)
861
+ } catch {
862
+ print("❌ [GridRenderLayer] Failed to create pipeline state: \(error)")
863
+ return
878
864
  }
865
+
866
+ let dataSamplerDesc = MTLSamplerDescriptor()
867
+ dataSamplerDesc.minFilter = .nearest
868
+ dataSamplerDesc.magFilter = .nearest
869
+ self.dataSamplerState = metalDevice.makeSamplerState(descriptor: dataSamplerDesc)
870
+
871
+ let colormapSamplerDesc = MTLSamplerDescriptor()
872
+ colormapSamplerDesc.minFilter = .nearest
873
+ colormapSamplerDesc.magFilter = .nearest
874
+ colormapSamplerDesc.sAddressMode = .clampToEdge
875
+ self.colormapSamplerState = metalDevice.makeSamplerState(descriptor: colormapSamplerDesc)
876
+
877
+ print("🟢 [GridRenderLayer] Metal setup complete")
878
+
879
+ // Process any pending updates that came in before Metal was ready
880
+ if let pendingGeometry = pendingGeometryUpdate {
881
+ print("🟡 [GridRenderLayer] Processing pending geometry update")
882
+ updateGeometry(corners: pendingGeometry.corners, gridDef: pendingGeometry.gridDef)
883
+ pendingGeometryUpdate = nil
884
+ }
885
+
886
+ if let pendingColormap = pendingColormapUpdate {
887
+ print("🟡 [GridRenderLayer] Processing pending colormap update")
888
+ updateColormapTexture(colormapAsBase64: pendingColormap)
889
+ pendingColormapUpdate = nil
890
+ }
891
+
892
+ if let pendingData = pendingDataUpdate {
893
+ print("🟡 [GridRenderLayer] Processing pending data update")
894
+ updateDataTexture(data: pendingData.data, nx: pendingData.nx, ny: pendingData.ny,
895
+ scale: pendingData.scale, offset: pendingData.offset,
896
+ missing: pendingData.missing, scaleType: pendingData.scaleType)
897
+ pendingDataUpdate = nil
898
+ }
899
+ }
879
900
  internal func internalRender(_ parameters: CustomLayerRenderParameters, mtlCommandBuffer: MTLCommandBuffer, mtlRenderPassDescriptor: MTLRenderPassDescriptor) {
880
901
  guard isVisible,
881
902
  let pipeline = pipelineState,
@@ -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) {
16
15
  return e && e.__esModule ? e : {
@@ -96,7 +95,7 @@ class AguaceroCore extends _events.EventEmitter {
96
95
  run: null,
97
96
  forecastHour: 0,
98
97
  visible: true,
99
- opacity: userLayerOptions.opacity ?? 0.85,
98
+ opacity: userLayerOptions.opacity ?? 1,
100
99
  units: options.initialUnit || 'imperial',
101
100
  shaderSmoothingEnabled: options.shaderSmoothingEnabled ?? true
102
101
  };
@@ -194,24 +193,60 @@ class AguaceroCore extends _events.EventEmitter {
194
193
  this.isPlaying ? this.pause() : this.play();
195
194
  }
196
195
  step(direction = 1) {
197
- var _this$modelStatus3;
198
- const {
199
- model,
200
- date,
201
- run,
202
- forecastHour
203
- } = this.state;
204
- 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];
205
- if (!forecastHours || forecastHours.length === 0) return;
206
- const currentIndex = forecastHours.indexOf(forecastHour);
207
- if (currentIndex === -1) return;
208
- const maxIndex = forecastHours.length - 1;
209
- let nextIndex = currentIndex + direction;
210
- if (nextIndex > maxIndex) nextIndex = 0;
211
- if (nextIndex < 0) nextIndex = maxIndex;
212
- this.setState({
213
- forecastHour: forecastHours[nextIndex]
214
- });
196
+ // --- THIS IS THE CORRECTED MRMS LOGIC ---
197
+ if (this.state.isMRMS) {
198
+ const {
199
+ variable,
200
+ mrmsTimestamp
201
+ } = this.state;
202
+ if (!this.mrmsStatus || !this.mrmsStatus[variable]) {
203
+ console.warn('[Core.step] MRMS status or variable not available.');
204
+ return;
205
+ }
206
+
207
+ // CRITICAL FIX: The UI and state emissions use a REVERSED array (newest first).
208
+ // The step logic MUST use the same reversed array for indexes to match.
209
+ const availableTimestamps = [...(this.mrmsStatus[variable] || [])].reverse();
210
+ if (availableTimestamps.length === 0) return;
211
+ const currentIndex = availableTimestamps.indexOf(mrmsTimestamp);
212
+ if (currentIndex === -1) {
213
+ // If not found, reset to the first (newest) frame
214
+ this.setState({
215
+ mrmsTimestamp: availableTimestamps[0]
216
+ });
217
+ return;
218
+ }
219
+ const maxIndex = availableTimestamps.length - 1;
220
+ let nextIndex = currentIndex + direction;
221
+
222
+ // Loop animation
223
+ if (nextIndex > maxIndex) nextIndex = 0;
224
+ if (nextIndex < 0) nextIndex = maxIndex;
225
+ const newTimestamp = availableTimestamps[nextIndex];
226
+ this.setState({
227
+ mrmsTimestamp: newTimestamp
228
+ });
229
+ } else {
230
+ var _this$modelStatus3;
231
+ const {
232
+ model,
233
+ date,
234
+ run,
235
+ forecastHour
236
+ } = this.state;
237
+ 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];
238
+ if (!forecastHours || forecastHours.length === 0) return;
239
+ const currentIndex = forecastHours.indexOf(forecastHour);
240
+ if (currentIndex === -1) return;
241
+ const maxIndex = forecastHours.length - 1;
242
+ let nextIndex = currentIndex + direction;
243
+ if (nextIndex > maxIndex) nextIndex = 0;
244
+ if (nextIndex < 0) nextIndex = maxIndex;
245
+ const newHour = forecastHours[nextIndex];
246
+ this.setState({
247
+ forecastHour: newHour
248
+ });
249
+ }
215
250
  }
216
251
  setPlaybackSpeed(speed) {
217
252
  if (speed > 0) {
@@ -354,6 +389,10 @@ class AguaceroCore extends _events.EventEmitter {
354
389
  return new Uint8Array(reconstructedData.buffer);
355
390
  }
356
391
  async _loadGridData(state) {
392
+ if (this.isReactNative) {
393
+ console.warn(`[AguaceroCore] _loadGridData was called in React Native. This is a bypass. Data loading is handled natively.`);
394
+ return null;
395
+ }
357
396
  const {
358
397
  model,
359
398
  date,
@@ -408,7 +447,7 @@ class AguaceroCore extends _events.EventEmitter {
408
447
  const headers = {
409
448
  'x-api-key': this.apiKey
410
449
  };
411
- if (this.bundleId) {
450
+ if (this.bundleId && this.isReactNative) {
412
451
  headers['x-app-identifier'] = this.bundleId;
413
452
  }
414
453
  const response = await fetch(urlWithApiKeyParam, {
@@ -508,20 +547,68 @@ class AguaceroCore extends _events.EventEmitter {
508
547
  const index1D = j * nx + i;
509
548
  const byteValue = gridData.data[index1D];
510
549
  const signedQuantizedValue = byteValue - 128;
550
+
551
+ // --- START OF FIX ---
552
+ // You were missing 'scale_type' in this destructuring assignment.
511
553
  const {
512
554
  scale,
513
555
  offset,
514
- missing_quantized
556
+ missing_quantized,
557
+ scale_type
515
558
  } = gridData.encoding;
559
+ // --- END OF FIX ---
560
+
516
561
  if (signedQuantizedValue === missing_quantized) return null;
517
- const nativeValue = signedQuantizedValue * scale + offset;
562
+ const intermediateValue = signedQuantizedValue * scale + offset;
563
+
564
+ // Step 2: Apply non-linear scaling if specified
565
+ let nativeValue = intermediateValue;
566
+ if (scale_type === 'sqrt') {
567
+ // Square the value while preserving its sign
568
+ nativeValue = intermediateValue < 0 ? -(intermediateValue * intermediateValue) : intermediateValue * intermediateValue;
569
+ }
518
570
  const {
571
+ colormap,
519
572
  baseUnit
520
573
  } = this._getColormapForVariable(variable);
574
+
575
+ // If the value is outside the colormap's bounds, return null.
576
+ if (colormap && colormap.length >= 2) {
577
+ const minBound = colormap[0];
578
+ const maxBound = colormap[colormap.length - 2];
579
+ if (nativeValue < minBound || nativeValue > maxBound) {
580
+ return null;
581
+ }
582
+ }
521
583
  let dataNativeUnit = baseUnit || (_dictionaries.DICTIONARIES.fld[variable] || {}).defaultUnit || 'none';
522
584
  const displayUnit = this._getTargetUnit(dataNativeUnit, units);
523
585
  const conversionFunc = (0, _unitConversions.getUnitConversionFunction)(dataNativeUnit, displayUnit);
524
- const displayValue = conversionFunc ? conversionFunc(nativeValue) : nativeValue;
586
+ let displayValue = conversionFunc ? conversionFunc(nativeValue) : nativeValue;
587
+
588
+ // --- START: ADDED CODE ---
589
+
590
+ // Create a variable to hold the precipitation type, if any.
591
+ let precipType = null;
592
+
593
+ // Check if the current variable is one of the special ptype variables.
594
+ if (variable === 'ptypeRefl' || variable === 'ptypeRate') {
595
+ const value = nativeValue; // Use the raw, unconverted value for ptype logic
596
+
597
+ if (value >= 100 && value < 200) {
598
+ displayValue -= 100;
599
+ precipType = 'Snow';
600
+ } else if (value >= 200 && value < 300) {
601
+ displayValue -= 200;
602
+ precipType = 'Frzg Rain'; // Abbreviated for tooltips
603
+ } else if (value >= 300 && value < 400) {
604
+ displayValue -= 300;
605
+ precipType = 'Ice Pellets';
606
+ } else {
607
+ precipType = 'Rain';
608
+ }
609
+ }
610
+
611
+ // Return the final payload, now including the precipType.
525
612
  return {
526
613
  lngLat: {
527
614
  lng,
@@ -532,7 +619,8 @@ class AguaceroCore extends _events.EventEmitter {
532
619
  name: this.getVariableDisplayName(variable)
533
620
  },
534
621
  value: displayValue,
535
- unit: displayUnit
622
+ unit: displayUnit,
623
+ precipType: precipType // NEW: Add this to the return object
536
624
  };
537
625
  } catch (error) {
538
626
  return null;
@@ -552,9 +640,6 @@ class AguaceroCore extends _events.EventEmitter {
552
640
  colormap: [],
553
641
  baseUnit: ''
554
642
  };
555
-
556
- // This logic for user-provided custom colormaps is correct.
557
- // If a user provides a custom map, it should always take top priority.
558
643
  if (this.customColormaps[variable] && this.customColormaps[variable].colormap) {
559
644
  return {
560
645
  colormap: this.customColormaps[variable].colormap,
@@ -570,45 +655,18 @@ class AguaceroCore extends _events.EventEmitter {
570
655
  };
571
656
  }
572
657
  const defaultColormapData = _defaultColormaps.DEFAULT_COLORMAPS[colormapKey];
573
-
574
- // --- START OF THE BUG FIX ---
575
- // This block handles the "default" case when no custom colormap is provided.
576
658
  if (defaultColormapData && defaultColormapData.units) {
577
- var _DICTIONARIES$fld$var;
578
- // 1. EDITED: Explicitly look up the CORRECT default unit from the main dictionary.
579
- // This is the information source we were previously ignoring.
580
- const preferredUnit = (_DICTIONARIES$fld$var = _dictionaries.DICTIONARIES.fld[variable]) === null || _DICTIONARIES$fld$var === void 0 ? void 0 : _DICTIONARIES$fld$var.defaultUnit; // e.g., '°C' for '2t_2'
581
-
582
- // 2. EDITED: Check if that preferred unit exists in the colormap definitions.
583
- if (preferredUnit && defaultColormapData.units[preferredUnit]) {
584
- const unitData = defaultColormapData.units[preferredUnit];
585
- if (unitData && unitData.colormap) {
586
- // 3. EDITED: If it exists, return ITS data. This is the correct path.
587
- console.log(`[AguaceroCore] Using dictionary default unit '${preferredUnit}' for variable '${variable}'.`);
588
- return {
589
- colormap: unitData.colormap,
590
- baseUnit: preferredUnit
591
- };
592
- }
593
- }
594
-
595
- // 4. EDITED: The old, buggy logic now serves as a FALLBACK ONLY.
596
- // This will only run if the specified defaultUnit is missing from the colormap data.
597
- console.warn(`[AguaceroCore] Default unit for '${variable}' not found in colormap. Using fallback.`);
598
- const availableUnits = Object.keys(defaultColormapData.units);
599
- if (availableUnits.length > 0) {
600
- const fallbackUnit = availableUnits[0]; // e.g., '°F'
601
- const unitData = defaultColormapData.units[fallbackUnit];
602
- if (unitData && unitData.colormap) {
603
- return {
604
- colormap: unitData.colormap,
605
- baseUnit: fallbackUnit
606
- };
607
- }
659
+ // ✅ Get defaultUnit from the field dictionary
660
+ const fieldInfo = _dictionaries.DICTIONARIES.fld[variable] || {};
661
+ const baseUnit = fieldInfo.defaultUnit || Object.keys(defaultColormapData.units)[0];
662
+ const unitData = defaultColormapData.units[baseUnit];
663
+ if (unitData && unitData.colormap) {
664
+ return {
665
+ colormap: unitData.colormap,
666
+ baseUnit: baseUnit
667
+ };
608
668
  }
609
669
  }
610
- // --- END OF THE BUG FIX ---
611
-
612
670
  return {
613
671
  colormap: [],
614
672
  baseUnit: ''
@@ -717,13 +775,15 @@ class AguaceroCore extends _events.EventEmitter {
717
775
  }
718
776
  _getTargetUnit(defaultUnit, system) {
719
777
  if (system === 'metric') {
720
- if (['°F', '°C'].includes(defaultUnit)) return 'celsius';
778
+ if (['°F', '°C', 'fahrenheit', 'celsius'].includes(defaultUnit)) return '°C';
721
779
  if (['kts', 'mph', 'm/s'].includes(defaultUnit)) return 'km/h';
722
780
  if (['in', 'mm', 'cm'].includes(defaultUnit)) return 'mm';
723
781
  }
724
- if (['°F', '°C'].includes(defaultUnit)) return 'fahrenheit';
725
- if (['kts', 'mph', 'm/s'].includes(defaultUnit)) return 'mph';
726
- if (['in', 'mm', 'cm'].includes(defaultUnit)) return 'in';
782
+ if (system === 'imperial') {
783
+ if (['°F', '°C', 'fahrenheit', 'celsius'].includes(defaultUnit)) return '°F';
784
+ if (['kts', 'mph', 'm/s'].includes(defaultUnit)) return 'mph';
785
+ if (['in', 'mm', 'cm'].includes(defaultUnit)) return 'in';
786
+ }
727
787
  return defaultUnit;
728
788
  }
729
789
  _getGridIndexFromLngLat(lng, lat) {