@aguacerowx/react-native 0.0.33 → 0.0.35

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 (82) hide show
  1. package/android/build/.transforms/42e9b8fa82d77a1c205db5bf0d0ed519/transformed/classes/classes_dex/classes.dex +0 -0
  2. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/aguacerowx/reactnative/GridRenderLayer.dex +0 -0
  3. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  4. package/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_fragment_shader.glsl.flat +0 -0
  5. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
  6. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  7. package/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/fragment_shader.glsl +54 -27
  8. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  9. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  10. package/{lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer$VertexInfo.class.uniqueId2 → android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer$VertexInfo.class.uniqueId0} +0 -0
  11. package/{lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId3 → android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId1} +0 -0
  12. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayerView.class.uniqueId2 +0 -0
  13. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  14. package/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +30 -14
  15. package/android/src/main/res/raw/fragment_shader.glsl +54 -27
  16. package/ios/GridRenderLayer.swift +21 -3
  17. package/ios/Shaders.metal +156 -19
  18. package/ios/compiled-shaders/Shaders-device.metallib +0 -0
  19. package/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  20. package/lib/commonjs/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  21. package/lib/commonjs/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_fragment_shader.glsl.flat +0 -0
  22. package/lib/commonjs/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
  23. package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  24. package/lib/commonjs/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/fragment_shader.glsl +54 -27
  25. package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  26. package/lib/commonjs/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  27. package/{android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer$VertexInfo.class.uniqueId2 → lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer$VertexInfo.class.uniqueId0} +0 -0
  28. package/lib/{module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId3 → commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId1} +0 -0
  29. package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayerView.class.uniqueId2 +0 -0
  30. package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  31. package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +30 -14
  32. package/lib/commonjs/android/src/main/res/raw/fragment_shader.glsl +54 -27
  33. package/lib/commonjs/ios/GridRenderLayer.swift +21 -3
  34. package/lib/commonjs/ios/Shaders.metal +156 -19
  35. package/lib/commonjs/ios/compiled-shaders/Shaders-device.metallib +0 -0
  36. package/lib/commonjs/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  37. package/lib/commonjs/package.json +1 -1
  38. package/lib/commonjs/src/WeatherLayerManager.js +3 -16
  39. package/lib/commonjs/src/WeatherLayerManager.js.map +1 -1
  40. package/lib/module/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  41. package/lib/module/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_fragment_shader.glsl.flat +0 -0
  42. package/lib/module/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
  43. package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  44. package/lib/module/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/fragment_shader.glsl +54 -27
  45. package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  46. package/lib/module/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  47. package/lib/module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/{GridRenderLayer$VertexInfo.class.uniqueId2 → GridRenderLayer$VertexInfo.class.uniqueId0} +0 -0
  48. package/{android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId3 → lib/module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId1} +0 -0
  49. package/lib/module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayerView.class.uniqueId2 +0 -0
  50. package/lib/module/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  51. package/lib/module/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +30 -14
  52. package/lib/module/android/src/main/res/raw/fragment_shader.glsl +54 -27
  53. package/lib/module/ios/GridRenderLayer.swift +21 -3
  54. package/lib/module/ios/Shaders.metal +156 -19
  55. package/lib/module/ios/compiled-shaders/Shaders-device.metallib +0 -0
  56. package/lib/module/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  57. package/lib/module/lib/commonjs/ios/GridRenderLayer.swift +21 -3
  58. package/lib/module/lib/commonjs/ios/Shaders.metal +156 -19
  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/package.json +1 -1
  62. package/lib/module/lib/commonjs/src/WeatherLayerManager.js +3 -16
  63. package/lib/module/lib/commonjs/src/WeatherLayerManager.js.map +1 -1
  64. package/lib/module/package.json +1 -1
  65. package/lib/module/src/WeatherLayerManager.js +3 -16
  66. package/lib/module/src/WeatherLayerManager.js.map +1 -1
  67. package/lib/typescript/src/WeatherLayerManager.d.ts.map +1 -1
  68. package/package.json +1 -1
  69. package/src/WeatherLayerManager.js +6 -20
  70. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/AguaceroPackage.class.uniqueId1 +0 -0
  71. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayerView.class.uniqueId4 +0 -0
  72. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderManager.class.uniqueId0 +0 -0
  73. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/InspectorModule.class.uniqueId5 +0 -0
  74. package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/AguaceroPackage.class.uniqueId1 +0 -0
  75. package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayerView.class.uniqueId4 +0 -0
  76. package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderManager.class.uniqueId0 +0 -0
  77. package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/InspectorModule.class.uniqueId5 +0 -0
  78. package/lib/module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/AguaceroPackage.class.uniqueId1 +0 -0
  79. package/lib/module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayerView.class.uniqueId4 +0 -0
  80. package/lib/module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderManager.class.uniqueId0 +0 -0
  81. package/lib/module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/InspectorModule.class.uniqueId5 +0 -0
  82. package/lib/module/lib/commonjs/ios/generated/AguaceroWxReactNativeSpec.h +0 -0
@@ -695,8 +695,21 @@ public class GridRenderLayer: NSObject {
695
695
  let lat_span = lat_last - lat_first
696
696
  let isSouthToNorth = lat_span > 0
697
697
 
698
- let data_lon_first_180 = lon_first > 180 ? lon_first - 360 : lon_first
699
- let data_lon_last_180 = lon_last > 180 ? lon_last - 360 : lon_last
698
+ // Check if this is ECMWF and normalize longitudes
699
+ let isECMWF = isECMWFType(gridParams: gridParams)
700
+ var data_lon_first_180 = lon_first
701
+ var data_lon_last_180 = lon_last
702
+
703
+ if isECMWF {
704
+ // Convert ECMWF's 180 to -180 range to -180 to 180
705
+ data_lon_first_180 = lon_first >= 180 ? lon_first - 360 : lon_first
706
+ data_lon_last_180 = lon_last >= 180 ? lon_last - 360 : lon_last
707
+ } else {
708
+ // For GFS and other models
709
+ data_lon_first_180 = lon_first > 180 ? lon_first - 360 : lon_first
710
+ data_lon_last_180 = lon_last > 180 ? lon_last - 360 : lon_last
711
+ }
712
+
700
713
  let data_lon_range = data_lon_last_180 - data_lon_first_180
701
714
 
702
715
  let subdivisions_x = 120
@@ -705,7 +718,7 @@ public class GridRenderLayer: NSObject {
705
718
  let TILE_SIZE: Double = 512.0
706
719
 
707
720
  let worldCopies = (data_lon_range > 300) ? [-1, 0, 1] : [0]
708
-
721
+
709
722
  for world_copy in worldCopies {
710
723
  let vertexStartIndex = UInt16(vertices.count / 4)
711
724
  let lon_offset = Double(world_copy) * 360.0
@@ -755,6 +768,11 @@ public class GridRenderLayer: NSObject {
755
768
  return (gridParams["lon_first"] as? Double) == 0.0 &&
756
769
  abs((gridParams["lat_first"] as? Double) ?? -1) == 90.0
757
770
  }
771
+
772
+ private func isECMWFType(gridParams: [String: Any]) -> Bool {
773
+ return (gridParams["lon_first"] as? Double) == 180.0 &&
774
+ (gridParams["lat_first"] as? Double) == 90.0
775
+ }
758
776
 
759
777
  private func lonLatToMercator(lon: Double, lat: Double, tileSize: Double) -> (x: Float, y: Float) {
760
778
  let mercX_normalized = (lon + 180.0) / 360.0
@@ -116,7 +116,7 @@ fragment float4 fragment_main(RasterizerData in [[stage_in]],
116
116
  float2 v11_coord = (bl_texel_index + float2(1.5, 1.5)) * texel_size;
117
117
 
118
118
  if (uniforms.isPtype == 1) {
119
- // --- PTYPE-SPECIFIC INTERPOLATION (CATEGORICAL) ---
119
+ // --- ENHANCED PTYPE-SPECIFIC INTERPOLATION ---
120
120
  float v00 = dequantize_val(get_value(dataTexture, dataSampler, v00_coord, uniforms), uniforms);
121
121
  float v10 = dequantize_val(get_value(dataTexture, dataSampler, v10_coord, uniforms), uniforms);
122
122
  float v01 = dequantize_val(get_value(dataTexture, dataSampler, v01_coord, uniforms), uniforms);
@@ -127,25 +127,162 @@ fragment float4 fragment_main(RasterizerData in [[stage_in]],
127
127
  float p01 = get_ptype_from_physical(v01, uniforms);
128
128
  float p11 = get_ptype_from_physical(v11, uniforms);
129
129
 
130
- // Determine the dominant precipitation type for this pixel
131
- float dominant_ptype = -1.0;
132
- if (p00 != -1.0) dominant_ptype = p00;
133
- else if (p10 != -1.0) dominant_ptype = p10;
134
- else if (p01 != -1.0) dominant_ptype = p01;
135
- else if (p11 != -1.0) dominant_ptype = p11;
130
+ // Count unique valid precipitation types
131
+ bool has_type_0 = false;
132
+ bool has_type_1 = false;
133
+ bool has_type_2 = false;
134
+ bool has_type_3 = false;
135
+ int valid_count = 0;
136
136
 
137
- if (dominant_ptype == -1.0) discard_fragment();
138
-
139
- // Interpolate ONLY the values that match the dominant ptype
140
- float total_value = 0.0;
141
- float total_weight = 0.0;
142
- if (p00 == dominant_ptype) { float w = (1.0-f.x)*(1.0-f.y); total_value+=v00*w; total_weight+=w; }
143
- if (p10 == dominant_ptype) { float w = f.x*(1.0-f.y); total_value+=v10*w; total_weight+=w; }
144
- if (p01 == dominant_ptype) { float w = (1.0-f.x)*f.y; total_value+=v01*w; total_weight+=w; }
145
- if (p11 == dominant_ptype) { float w = f.x*f.y; total_value+=v11*w; total_weight+=w; }
146
-
147
- if (total_weight <= 0.0) discard_fragment();
148
- raw_value = total_value / total_weight;
137
+ if (p00 >= 0.0) {
138
+ int ptype = int(p00);
139
+ if (ptype == 0) has_type_0 = true;
140
+ else if (ptype == 1) has_type_1 = true;
141
+ else if (ptype == 2) has_type_2 = true;
142
+ else if (ptype == 3) has_type_3 = true;
143
+ valid_count++;
144
+ }
145
+ if (p10 >= 0.0) {
146
+ int ptype = int(p10);
147
+ if (ptype == 0) has_type_0 = true;
148
+ else if (ptype == 1) has_type_1 = true;
149
+ else if (ptype == 2) has_type_2 = true;
150
+ else if (ptype == 3) has_type_3 = true;
151
+ valid_count++;
152
+ }
153
+ if (p01 >= 0.0) {
154
+ int ptype = int(p01);
155
+ if (ptype == 0) has_type_0 = true;
156
+ else if (ptype == 1) has_type_1 = true;
157
+ else if (ptype == 2) has_type_2 = true;
158
+ else if (ptype == 3) has_type_3 = true;
159
+ valid_count++;
160
+ }
161
+ if (p11 >= 0.0) {
162
+ int ptype = int(p11);
163
+ if (ptype == 0) has_type_0 = true;
164
+ else if (ptype == 1) has_type_1 = true;
165
+ else if (ptype == 2) has_type_2 = true;
166
+ else if (ptype == 3) has_type_3 = true;
167
+ valid_count++;
168
+ }
169
+
170
+ if (valid_count == 0) discard_fragment();
171
+
172
+ // Count how many unique types we have
173
+ int unique_types = 0;
174
+ if (has_type_0) unique_types++;
175
+ if (has_type_1) unique_types++;
176
+ if (has_type_2) unique_types++;
177
+ if (has_type_3) unique_types++;
178
+
179
+ if (unique_types == 1) {
180
+ // ALL SAME TYPE - smooth interpolation across all valid pixels
181
+ float total_value = 0.0;
182
+ float total_weight = 0.0;
183
+
184
+ if (p00 >= 0.0) {
185
+ float weight = (1.0 - f.x) * (1.0 - f.y);
186
+ total_value += v00 * weight;
187
+ total_weight += weight;
188
+ }
189
+ if (p10 >= 0.0) {
190
+ float weight = f.x * (1.0 - f.y);
191
+ total_value += v10 * weight;
192
+ total_weight += weight;
193
+ }
194
+ if (p01 >= 0.0) {
195
+ float weight = (1.0 - f.x) * f.y;
196
+ total_value += v01 * weight;
197
+ total_weight += weight;
198
+ }
199
+ if (p11 >= 0.0) {
200
+ float weight = f.x * f.y;
201
+ total_value += v11 * weight;
202
+ total_weight += weight;
203
+ }
204
+
205
+ if (total_weight <= 0.0) discard_fragment();
206
+ raw_value = total_value / total_weight;
207
+
208
+ } else {
209
+ // MULTIPLE TYPES - weighted voting to determine dominant type
210
+ float type_weight_0 = 0.0;
211
+ float type_weight_1 = 0.0;
212
+ float type_weight_2 = 0.0;
213
+ float type_weight_3 = 0.0;
214
+
215
+ if (p00 >= 0.0) {
216
+ float w = (1.0 - f.x) * (1.0 - f.y);
217
+ int ptype = int(p00);
218
+ if (ptype == 0) type_weight_0 += w;
219
+ else if (ptype == 1) type_weight_1 += w;
220
+ else if (ptype == 2) type_weight_2 += w;
221
+ else if (ptype == 3) type_weight_3 += w;
222
+ }
223
+ if (p10 >= 0.0) {
224
+ float w = f.x * (1.0 - f.y);
225
+ int ptype = int(p10);
226
+ if (ptype == 0) type_weight_0 += w;
227
+ else if (ptype == 1) type_weight_1 += w;
228
+ else if (ptype == 2) type_weight_2 += w;
229
+ else if (ptype == 3) type_weight_3 += w;
230
+ }
231
+ if (p01 >= 0.0) {
232
+ float w = (1.0 - f.x) * f.y;
233
+ int ptype = int(p01);
234
+ if (ptype == 0) type_weight_0 += w;
235
+ else if (ptype == 1) type_weight_1 += w;
236
+ else if (ptype == 2) type_weight_2 += w;
237
+ else if (ptype == 3) type_weight_3 += w;
238
+ }
239
+ if (p11 >= 0.0) {
240
+ float w = f.x * f.y;
241
+ int ptype = int(p11);
242
+ if (ptype == 0) type_weight_0 += w;
243
+ else if (ptype == 1) type_weight_1 += w;
244
+ else if (ptype == 2) type_weight_2 += w;
245
+ else if (ptype == 3) type_weight_3 += w;
246
+ }
247
+
248
+ // Find the type with the highest weight at this pixel location
249
+ float max_type_weight = 0.0;
250
+ float winning_type = -1.0;
251
+ if (type_weight_0 > max_type_weight) { max_type_weight = type_weight_0; winning_type = 0.0; }
252
+ if (type_weight_1 > max_type_weight) { max_type_weight = type_weight_1; winning_type = 1.0; }
253
+ if (type_weight_2 > max_type_weight) { max_type_weight = type_weight_2; winning_type = 2.0; }
254
+ if (type_weight_3 > max_type_weight) { max_type_weight = type_weight_3; winning_type = 3.0; }
255
+
256
+ if (winning_type == -1.0) discard_fragment();
257
+
258
+ // Now smoothly interpolate only among pixels of the winning type
259
+ float total_value = 0.0;
260
+ float total_weight = 0.0;
261
+
262
+ if (p00 == winning_type) {
263
+ float weight = (1.0 - f.x) * (1.0 - f.y);
264
+ total_value += v00 * weight;
265
+ total_weight += weight;
266
+ }
267
+ if (p10 == winning_type) {
268
+ float weight = f.x * (1.0 - f.y);
269
+ total_value += v10 * weight;
270
+ total_weight += weight;
271
+ }
272
+ if (p01 == winning_type) {
273
+ float weight = (1.0 - f.x) * f.y;
274
+ total_value += v01 * weight;
275
+ total_weight += weight;
276
+ }
277
+ if (p11 == winning_type) {
278
+ float weight = f.x * f.y;
279
+ total_value += v11 * weight;
280
+ total_weight += weight;
281
+ }
282
+
283
+ if (total_weight <= 0.0) discard_fragment();
284
+ raw_value = total_value / total_weight;
285
+ }
149
286
 
150
287
  // Force full alpha to prevent dark borders between ptype regions
151
288
  alpha_multiplier = 1.0;
@@ -695,8 +695,21 @@ public class GridRenderLayer: NSObject {
695
695
  let lat_span = lat_last - lat_first
696
696
  let isSouthToNorth = lat_span > 0
697
697
 
698
- let data_lon_first_180 = lon_first > 180 ? lon_first - 360 : lon_first
699
- let data_lon_last_180 = lon_last > 180 ? lon_last - 360 : lon_last
698
+ // Check if this is ECMWF and normalize longitudes
699
+ let isECMWF = isECMWFType(gridParams: gridParams)
700
+ var data_lon_first_180 = lon_first
701
+ var data_lon_last_180 = lon_last
702
+
703
+ if isECMWF {
704
+ // Convert ECMWF's 180 to -180 range to -180 to 180
705
+ data_lon_first_180 = lon_first >= 180 ? lon_first - 360 : lon_first
706
+ data_lon_last_180 = lon_last >= 180 ? lon_last - 360 : lon_last
707
+ } else {
708
+ // For GFS and other models
709
+ data_lon_first_180 = lon_first > 180 ? lon_first - 360 : lon_first
710
+ data_lon_last_180 = lon_last > 180 ? lon_last - 360 : lon_last
711
+ }
712
+
700
713
  let data_lon_range = data_lon_last_180 - data_lon_first_180
701
714
 
702
715
  let subdivisions_x = 120
@@ -705,7 +718,7 @@ public class GridRenderLayer: NSObject {
705
718
  let TILE_SIZE: Double = 512.0
706
719
 
707
720
  let worldCopies = (data_lon_range > 300) ? [-1, 0, 1] : [0]
708
-
721
+
709
722
  for world_copy in worldCopies {
710
723
  let vertexStartIndex = UInt16(vertices.count / 4)
711
724
  let lon_offset = Double(world_copy) * 360.0
@@ -755,6 +768,11 @@ public class GridRenderLayer: NSObject {
755
768
  return (gridParams["lon_first"] as? Double) == 0.0 &&
756
769
  abs((gridParams["lat_first"] as? Double) ?? -1) == 90.0
757
770
  }
771
+
772
+ private func isECMWFType(gridParams: [String: Any]) -> Bool {
773
+ return (gridParams["lon_first"] as? Double) == 180.0 &&
774
+ (gridParams["lat_first"] as? Double) == 90.0
775
+ }
758
776
 
759
777
  private func lonLatToMercator(lon: Double, lat: Double, tileSize: Double) -> (x: Float, y: Float) {
760
778
  let mercX_normalized = (lon + 180.0) / 360.0
@@ -116,7 +116,7 @@ fragment float4 fragment_main(RasterizerData in [[stage_in]],
116
116
  float2 v11_coord = (bl_texel_index + float2(1.5, 1.5)) * texel_size;
117
117
 
118
118
  if (uniforms.isPtype == 1) {
119
- // --- PTYPE-SPECIFIC INTERPOLATION (CATEGORICAL) ---
119
+ // --- ENHANCED PTYPE-SPECIFIC INTERPOLATION ---
120
120
  float v00 = dequantize_val(get_value(dataTexture, dataSampler, v00_coord, uniforms), uniforms);
121
121
  float v10 = dequantize_val(get_value(dataTexture, dataSampler, v10_coord, uniforms), uniforms);
122
122
  float v01 = dequantize_val(get_value(dataTexture, dataSampler, v01_coord, uniforms), uniforms);
@@ -127,25 +127,162 @@ fragment float4 fragment_main(RasterizerData in [[stage_in]],
127
127
  float p01 = get_ptype_from_physical(v01, uniforms);
128
128
  float p11 = get_ptype_from_physical(v11, uniforms);
129
129
 
130
- // Determine the dominant precipitation type for this pixel
131
- float dominant_ptype = -1.0;
132
- if (p00 != -1.0) dominant_ptype = p00;
133
- else if (p10 != -1.0) dominant_ptype = p10;
134
- else if (p01 != -1.0) dominant_ptype = p01;
135
- else if (p11 != -1.0) dominant_ptype = p11;
130
+ // Count unique valid precipitation types
131
+ bool has_type_0 = false;
132
+ bool has_type_1 = false;
133
+ bool has_type_2 = false;
134
+ bool has_type_3 = false;
135
+ int valid_count = 0;
136
136
 
137
- if (dominant_ptype == -1.0) discard_fragment();
138
-
139
- // Interpolate ONLY the values that match the dominant ptype
140
- float total_value = 0.0;
141
- float total_weight = 0.0;
142
- if (p00 == dominant_ptype) { float w = (1.0-f.x)*(1.0-f.y); total_value+=v00*w; total_weight+=w; }
143
- if (p10 == dominant_ptype) { float w = f.x*(1.0-f.y); total_value+=v10*w; total_weight+=w; }
144
- if (p01 == dominant_ptype) { float w = (1.0-f.x)*f.y; total_value+=v01*w; total_weight+=w; }
145
- if (p11 == dominant_ptype) { float w = f.x*f.y; total_value+=v11*w; total_weight+=w; }
146
-
147
- if (total_weight <= 0.0) discard_fragment();
148
- raw_value = total_value / total_weight;
137
+ if (p00 >= 0.0) {
138
+ int ptype = int(p00);
139
+ if (ptype == 0) has_type_0 = true;
140
+ else if (ptype == 1) has_type_1 = true;
141
+ else if (ptype == 2) has_type_2 = true;
142
+ else if (ptype == 3) has_type_3 = true;
143
+ valid_count++;
144
+ }
145
+ if (p10 >= 0.0) {
146
+ int ptype = int(p10);
147
+ if (ptype == 0) has_type_0 = true;
148
+ else if (ptype == 1) has_type_1 = true;
149
+ else if (ptype == 2) has_type_2 = true;
150
+ else if (ptype == 3) has_type_3 = true;
151
+ valid_count++;
152
+ }
153
+ if (p01 >= 0.0) {
154
+ int ptype = int(p01);
155
+ if (ptype == 0) has_type_0 = true;
156
+ else if (ptype == 1) has_type_1 = true;
157
+ else if (ptype == 2) has_type_2 = true;
158
+ else if (ptype == 3) has_type_3 = true;
159
+ valid_count++;
160
+ }
161
+ if (p11 >= 0.0) {
162
+ int ptype = int(p11);
163
+ if (ptype == 0) has_type_0 = true;
164
+ else if (ptype == 1) has_type_1 = true;
165
+ else if (ptype == 2) has_type_2 = true;
166
+ else if (ptype == 3) has_type_3 = true;
167
+ valid_count++;
168
+ }
169
+
170
+ if (valid_count == 0) discard_fragment();
171
+
172
+ // Count how many unique types we have
173
+ int unique_types = 0;
174
+ if (has_type_0) unique_types++;
175
+ if (has_type_1) unique_types++;
176
+ if (has_type_2) unique_types++;
177
+ if (has_type_3) unique_types++;
178
+
179
+ if (unique_types == 1) {
180
+ // ALL SAME TYPE - smooth interpolation across all valid pixels
181
+ float total_value = 0.0;
182
+ float total_weight = 0.0;
183
+
184
+ if (p00 >= 0.0) {
185
+ float weight = (1.0 - f.x) * (1.0 - f.y);
186
+ total_value += v00 * weight;
187
+ total_weight += weight;
188
+ }
189
+ if (p10 >= 0.0) {
190
+ float weight = f.x * (1.0 - f.y);
191
+ total_value += v10 * weight;
192
+ total_weight += weight;
193
+ }
194
+ if (p01 >= 0.0) {
195
+ float weight = (1.0 - f.x) * f.y;
196
+ total_value += v01 * weight;
197
+ total_weight += weight;
198
+ }
199
+ if (p11 >= 0.0) {
200
+ float weight = f.x * f.y;
201
+ total_value += v11 * weight;
202
+ total_weight += weight;
203
+ }
204
+
205
+ if (total_weight <= 0.0) discard_fragment();
206
+ raw_value = total_value / total_weight;
207
+
208
+ } else {
209
+ // MULTIPLE TYPES - weighted voting to determine dominant type
210
+ float type_weight_0 = 0.0;
211
+ float type_weight_1 = 0.0;
212
+ float type_weight_2 = 0.0;
213
+ float type_weight_3 = 0.0;
214
+
215
+ if (p00 >= 0.0) {
216
+ float w = (1.0 - f.x) * (1.0 - f.y);
217
+ int ptype = int(p00);
218
+ if (ptype == 0) type_weight_0 += w;
219
+ else if (ptype == 1) type_weight_1 += w;
220
+ else if (ptype == 2) type_weight_2 += w;
221
+ else if (ptype == 3) type_weight_3 += w;
222
+ }
223
+ if (p10 >= 0.0) {
224
+ float w = f.x * (1.0 - f.y);
225
+ int ptype = int(p10);
226
+ if (ptype == 0) type_weight_0 += w;
227
+ else if (ptype == 1) type_weight_1 += w;
228
+ else if (ptype == 2) type_weight_2 += w;
229
+ else if (ptype == 3) type_weight_3 += w;
230
+ }
231
+ if (p01 >= 0.0) {
232
+ float w = (1.0 - f.x) * f.y;
233
+ int ptype = int(p01);
234
+ if (ptype == 0) type_weight_0 += w;
235
+ else if (ptype == 1) type_weight_1 += w;
236
+ else if (ptype == 2) type_weight_2 += w;
237
+ else if (ptype == 3) type_weight_3 += w;
238
+ }
239
+ if (p11 >= 0.0) {
240
+ float w = f.x * f.y;
241
+ int ptype = int(p11);
242
+ if (ptype == 0) type_weight_0 += w;
243
+ else if (ptype == 1) type_weight_1 += w;
244
+ else if (ptype == 2) type_weight_2 += w;
245
+ else if (ptype == 3) type_weight_3 += w;
246
+ }
247
+
248
+ // Find the type with the highest weight at this pixel location
249
+ float max_type_weight = 0.0;
250
+ float winning_type = -1.0;
251
+ if (type_weight_0 > max_type_weight) { max_type_weight = type_weight_0; winning_type = 0.0; }
252
+ if (type_weight_1 > max_type_weight) { max_type_weight = type_weight_1; winning_type = 1.0; }
253
+ if (type_weight_2 > max_type_weight) { max_type_weight = type_weight_2; winning_type = 2.0; }
254
+ if (type_weight_3 > max_type_weight) { max_type_weight = type_weight_3; winning_type = 3.0; }
255
+
256
+ if (winning_type == -1.0) discard_fragment();
257
+
258
+ // Now smoothly interpolate only among pixels of the winning type
259
+ float total_value = 0.0;
260
+ float total_weight = 0.0;
261
+
262
+ if (p00 == winning_type) {
263
+ float weight = (1.0 - f.x) * (1.0 - f.y);
264
+ total_value += v00 * weight;
265
+ total_weight += weight;
266
+ }
267
+ if (p10 == winning_type) {
268
+ float weight = f.x * (1.0 - f.y);
269
+ total_value += v10 * weight;
270
+ total_weight += weight;
271
+ }
272
+ if (p01 == winning_type) {
273
+ float weight = (1.0 - f.x) * f.y;
274
+ total_value += v01 * weight;
275
+ total_weight += weight;
276
+ }
277
+ if (p11 == winning_type) {
278
+ float weight = f.x * f.y;
279
+ total_value += v11 * weight;
280
+ total_weight += weight;
281
+ }
282
+
283
+ if (total_weight <= 0.0) discard_fragment();
284
+ raw_value = total_value / total_weight;
285
+ }
149
286
 
150
287
  // Force full alpha to prevent dark borders between ptype regions
151
288
  alpha_multiplier = 1.0;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aguacerowx/react-native",
3
- "version": "0.0.33",
3
+ "version": "0.0.35",
4
4
  "description": "Native weather rendering for React Native",
5
5
  "license": "ISC",
6
6
  "author": "Michael Barletta",
@@ -745,7 +745,7 @@ const WeatherLayerManager = exports.WeatherLayerManager = /*#__PURE__*/(0, _reac
745
745
  run
746
746
  } = core.state;
747
747
  if (isMRMS) {
748
- // --- MRMS LOGIC WITH PRE-LOADING ---
748
+ // --- MRMS LOGIC (Keep existing logic) ---
749
749
  const oldTimestamps = new Set(core.mrmsStatus?.[currentVariable] || []);
750
750
  const mrmsStatus = await core.fetchMRMSStatus(true);
751
751
  const newTimestamps = mrmsStatus?.[currentVariable] || [];
@@ -755,6 +755,7 @@ const WeatherLayerManager = exports.WeatherLayerManager = /*#__PURE__*/(0, _reac
755
755
  core.mrmsStatus = mrmsStatus;
756
756
  core._emitStateChange(); // Update UI slider without changing selection
757
757
 
758
+ // ... (Keep your existing preloading logic here) ...
758
759
  const {
759
760
  corners,
760
761
  gridDef
@@ -770,12 +771,7 @@ const WeatherLayerManager = exports.WeatherLayerManager = /*#__PURE__*/(0, _reac
770
771
  const y = frameDate.getUTCFullYear(),
771
772
  m = (frameDate.getUTCMonth() + 1).toString().padStart(2, '0'),
772
773
  d = frameDate.getUTCDate().toString().padStart(2, '0');
773
-
774
- // --- THIS IS THE FIX ---
775
- // Changed 'variable' to 'currentVariable'
776
774
  const resourcePath = `/grids/mrms/${y}${m}${d}/${frame}/0/${currentVariable}/0`;
777
- // --- END FIX ---
778
-
779
775
  const url = `${core.baseGridUrl}${resourcePath}?apiKey=${core.apiKey}`;
780
776
  WeatherFrameProcessorModule.processFrame({
781
777
  url,
@@ -813,19 +809,10 @@ const WeatherLayerManager = exports.WeatherLayerManager = /*#__PURE__*/(0, _reac
813
809
  });
814
810
  }
815
811
  } else {
816
- // --- MODEL LOGIC ---
817
812
  const modelStatus = await core.fetchModelStatus(true);
813
+ core._emitStateChange();
818
814
  const latestRun = findLatestModelRun(modelStatus, currentModel);
819
815
  if (!latestRun) return;
820
- const currentRunKey = `${date}:${run}`;
821
- const latestRunKey = `${latestRun.date}:${latestRun.run}`;
822
- if (latestRunKey > currentRunKey) {
823
- // This preserves the current forecastHour while changing the run
824
- await core.setState({
825
- date: latestRun.date,
826
- run: latestRun.run
827
- });
828
- }
829
816
  }
830
817
  }, [core]);
831
818
  (0, _react.useEffect)(() => {