diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..f01adc2 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,3 @@ +[profile.dev] +opt-level = 1 +incremental = true \ No newline at end of file diff --git a/config.toml b/config.toml index 4725f8a..e38867c 100644 --- a/config.toml +++ b/config.toml @@ -81,4 +81,28 @@ Color: 70 255 255 255 128 128 128 Color: 80 128 128 128 """ missing = -99.0 +no_coverage = -999.0 + +[sources.grib2.noaa_mrms_merged_rhohv_3km_CONUS] +from = "https://mrms.ncep.noaa.gov/3DRhoHV/MergedRhoHV_03.00/MRMS_MergedRhoHV_03.00.latest.grib2.gz" +needs_gzip = true +valid_for = 300 +palette = """ +Color: 0.20 149 148 156 +Color: 0.45 22 20 140 +Color: 0.65 9 2 233 +Color: 0.75 137 135 214 +Color: 0.80 92 255 89 +Color: 0.85 139 207 2 +Color: 0.90 255 251 0 +Color: 0.93 255 196 0 +Color: 0.95 255 137 3 +Color: 0.96 255 43 0 +Color: 0.97 227 0 0 +Color: 0.98 161 0 0 +Color: 0.99 121 0 90 +Color: 1.00 250 172 209 +Color: 1.05 119 0 125 +""" +missing = -99.0 no_coverage = -999.0 \ No newline at end of file diff --git a/wxbox-grib2/src/lib.rs b/wxbox-grib2/src/lib.rs index 101fd79..2f3daac 100644 --- a/wxbox-grib2/src/lib.rs +++ b/wxbox-grib2/src/lib.rs @@ -6,7 +6,7 @@ use std::fmt::{Debug, Formatter}; use std::io::{Cursor, Read}; use std::time::Instant; use image::codecs::png::PngDecoder; -use image::{DynamicImage, ImageBuffer, ImageDecoder, ImageFormat, ImageReader, Luma}; +use image::{DynamicImage, GenericImageView, ImageBuffer, ImageDecoder, ImageFormat, ImageReader, Luma}; use tracing::{debug, warn}; use crate::error::GribError; use crate::LatLongVectorRelativity::{EasterlyAndNortherly, IncreasingXY}; @@ -104,6 +104,8 @@ impl GribMessage { let bitmap = bitmap.ok_or(GribError::MissingBitmap)?; let data = data.ok_or(GribError::MissingData)?; + debug!("{:?}", data_representation); + data_representation.load_data(data.data.clone())?; Ok(Self { @@ -315,7 +317,7 @@ pub struct GridpointPNGDataRepresentation { pub depth: u8, pub type_of_values: u8, - pub image: Option, Vec>> + pub image: Option } impl GridpointPNGDataRepresentation { fn parse(_length: u32, nommer: &mut NomReader) -> Result { @@ -339,7 +341,7 @@ impl GridpointPNGDataRepresentation { let image = image_reader.decode()?; - self.image = Some(image.to_luma16()); + self.image = Some(image); Ok(()) } @@ -347,17 +349,50 @@ impl GridpointPNGDataRepresentation { fn get_image_coordinate(&self, x: u32, y: u32) -> Option { match &self.image { Some(i) => { - if x >= i.width() || y >= i.height() { - None - } else { - let datapoint = i.get_pixel(x, y).0[0] as f32; - let diff = datapoint * 2.0_f32.powi(self.binary_scale_factor as i32); - let dig_factor = 10_f32.powi(-(self.decimal_scale_factor as i32)); - let value = (self.reference_value + diff) * dig_factor; - Some(value) + match self.depth { + 1 | 2 | 4 | 8 | 16 => { + if x >= i.width() || y >= i.height() { + None + } else { + let datapoint = i.as_luma16().unwrap().get_pixel(x, y).0[0] as f32; + let diff = datapoint * 2.0_f32.powi(self.binary_scale_factor as i32); + let dig_factor = 10_f32.powi(-(self.decimal_scale_factor as i32)); + let value = (self.reference_value + diff) * dig_factor; + Some(value) + } + }, + 24 => { + if x >= i.width() || y >= i.height() { + None + } else { + let datapoint_channels = i.as_rgb8().unwrap().get_pixel(x, y).0; + + let datapoint = u32::from_be_bytes([0, datapoint_channels[0], datapoint_channels[1], datapoint_channels[2]]) as f32; + + let diff = datapoint * 2.0_f32.powi(self.binary_scale_factor as i32); + let dig_factor = 10_f32.powi(-(self.decimal_scale_factor as i32)); + let value = (self.reference_value + diff) * dig_factor; + Some(value) + } + }, + 32 => { + if x >= i.width() || y >= i.height() { + None + } else { + let datapoint_channels = i.as_rgba8().unwrap().get_pixel(x, y).0; + + let datapoint = u32::from_be_bytes(datapoint_channels) as f32; + + let diff = datapoint * 2.0_f32.powi(self.binary_scale_factor as i32); + let dig_factor = 10_f32.powi(-(self.decimal_scale_factor as i32)); + let value = (self.reference_value + diff) * dig_factor; + Some(value) + } + }, + _ => panic!("unsupported bit depth") } }, - None => None, + None => None } } } diff --git a/wxbox_client/src/lib.rs b/wxbox_client/src/lib.rs index 5d53d54..bf1bbe7 100644 --- a/wxbox_client/src/lib.rs +++ b/wxbox_client/src/lib.rs @@ -138,6 +138,14 @@ impl eframe::App for WxboxApp { need_to_reset_for_next_frame = true; } }); + + if location == "CONUS" { + ui.collapsing("RhoHV (Correlation Coefficient)", |ui| { + if ui.radio_value(&mut tile_request_options.data, format!("grib2/noaa_mrms_merged_rhohv_3km_{}", location), "RhoHV @ 3.00 KM").changed() { + need_to_reset_for_next_frame = true; + } + }); + } }); } });