formatting
This commit is contained in:
parent
913ec262bd
commit
23571406ea
10 changed files with 152 additions and 105 deletions
|
@ -1,8 +1,8 @@
|
|||
use std::fmt::Debug;
|
||||
use nexrad_data::volume::File;
|
||||
use nexrad_decode::messages::digital_radar_data::{GenericDataBlock, RadialStatus};
|
||||
use nexrad_decode::messages::MessageContents;
|
||||
use nexrad_decode::messages::digital_radar_data::{GenericDataBlock, RadialStatus};
|
||||
use nexrad_decode::result::Error;
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub mod sites;
|
||||
|
||||
|
@ -39,7 +39,7 @@ pub struct MomentData {
|
|||
pub offset: f32,
|
||||
pub values: Vec<u8>,
|
||||
pub start_range: u16,
|
||||
pub sample_interval: u16
|
||||
pub sample_interval: u16,
|
||||
}
|
||||
|
||||
impl MomentData {
|
||||
|
@ -97,8 +97,7 @@ pub fn parse(input: Vec<u8>) -> nexrad_data::result::Result<Scan> {
|
|||
if let MessageContents::DigitalRadarData(radar_data_message) = contents {
|
||||
if vcp.is_none() {
|
||||
if let Some(volume_block) = &radar_data_message.volume_data_block {
|
||||
vcp =
|
||||
Some(volume_block.volume_coverage_pattern_number);
|
||||
vcp = Some(volume_block.volume_coverage_pattern_number);
|
||||
}
|
||||
}
|
||||
radials.push(into_radial(*radar_data_message)?);
|
||||
|
@ -112,9 +111,15 @@ pub fn parse(input: Vec<u8>) -> nexrad_data::result::Result<Scan> {
|
|||
})
|
||||
}
|
||||
|
||||
fn into_radial(message: nexrad_decode::messages::digital_radar_data::Message) -> nexrad_data::result::Result<Radial> {
|
||||
fn into_radial(
|
||||
message: nexrad_decode::messages::digital_radar_data::Message,
|
||||
) -> nexrad_data::result::Result<Radial> {
|
||||
Ok(Radial {
|
||||
collection_timestamp: message.header.date_time().ok_or(Error::MessageMissingDateError)?.timestamp_millis(),
|
||||
collection_timestamp: message
|
||||
.header
|
||||
.date_time()
|
||||
.ok_or(Error::MessageMissingDateError)?
|
||||
.timestamp_millis(),
|
||||
azimuth_number: message.header.azimuth_number,
|
||||
azimuth_angle_degrees: message.header.azimuth_angle,
|
||||
azimuth_spacing_degrees: message.header.azimuth_resolution_spacing as f32 * 0.5,
|
||||
|
@ -123,11 +128,21 @@ fn into_radial(message: nexrad_decode::messages::digital_radar_data::Message) ->
|
|||
elevation_number_degrees: message.header.elevation_angle,
|
||||
reflectivity: message.reflectivity_data_block.map(|u| into_moment_data(u)),
|
||||
velocity: message.velocity_data_block.map(|u| into_moment_data(u)),
|
||||
spectrum_width: message.spectrum_width_data_block.map(|u| into_moment_data(u)),
|
||||
differential_reflectivity: message.differential_reflectivity_data_block.map(|u| into_moment_data(u)),
|
||||
differential_phase: message.differential_phase_data_block.map(|u| into_moment_data(u)),
|
||||
correlation_coefficient: message.correlation_coefficient_data_block.map(|u| into_moment_data(u)),
|
||||
specific_differential_phase: message.specific_diff_phase_data_block.map(|u| into_moment_data(u)),
|
||||
spectrum_width: message
|
||||
.spectrum_width_data_block
|
||||
.map(|u| into_moment_data(u)),
|
||||
differential_reflectivity: message
|
||||
.differential_reflectivity_data_block
|
||||
.map(|u| into_moment_data(u)),
|
||||
differential_phase: message
|
||||
.differential_phase_data_block
|
||||
.map(|u| into_moment_data(u)),
|
||||
correlation_coefficient: message
|
||||
.correlation_coefficient_data_block
|
||||
.map(|u| into_moment_data(u)),
|
||||
specific_differential_phase: message
|
||||
.specific_diff_phase_data_block
|
||||
.map(|u| into_moment_data(u)),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -137,58 +152,41 @@ fn into_moment_data(block: GenericDataBlock) -> MomentData {
|
|||
offset: block.header.offset,
|
||||
values: block.encoded_data,
|
||||
start_range: block.header.data_moment_range,
|
||||
sample_interval: block.header.data_moment_range_sample_interval
|
||||
sample_interval: block.header.data_moment_range_sample_interval,
|
||||
}
|
||||
}
|
||||
|
||||
impl Sweep {
|
||||
pub fn new(elevation_number: u8, radials: Vec<Radial>) -> Self {
|
||||
|
||||
Self {
|
||||
|
||||
elevation_number,
|
||||
|
||||
radials,
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
pub fn from_radials(radials: Vec<Radial>) -> Vec<Self> {
|
||||
|
||||
let mut sweeps = Vec::new();
|
||||
|
||||
|
||||
let mut sweep_elevation_number = None;
|
||||
|
||||
let mut sweep_radials = Vec::new();
|
||||
|
||||
|
||||
for radial in radials {
|
||||
|
||||
if let Some(elevation_number) = sweep_elevation_number {
|
||||
|
||||
if elevation_number != radial.elevation_number {
|
||||
|
||||
sweeps.push(Sweep::new(elevation_number, sweep_radials));
|
||||
|
||||
sweep_radials = Vec::new();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
sweep_elevation_number = Some(radial.elevation_number);
|
||||
|
||||
sweep_radials.push(radial);
|
||||
|
||||
}
|
||||
|
||||
|
||||
sweeps
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub const DATA_BYTES: &[u8] = include_bytes!("../KCRP20170825_235733_V06");
|
||||
pub const DATA_BYTES: &[u8] = include_bytes!("../KCRP20170825_235733_V06");
|
||||
|
|
|
@ -4,5 +4,16 @@ use wxbox_ar2::parse;
|
|||
fn main() {
|
||||
let f = fs::read("KCRP20170825_235733_V06").unwrap();
|
||||
let f = parse(f).unwrap();
|
||||
println!("{:?}", f.sweeps.get(0).unwrap().radials.get(0).unwrap().reflectivity.as_ref().unwrap());
|
||||
}
|
||||
println!(
|
||||
"{:?}",
|
||||
f.sweeps
|
||||
.get(0)
|
||||
.unwrap()
|
||||
.radials
|
||||
.get(0)
|
||||
.unwrap()
|
||||
.reflectivity
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -83,8 +83,10 @@ mod tests {
|
|||
let radar = SITES.sites.get("KCRP").unwrap();
|
||||
let radar_theta = radar.long;
|
||||
let radar_phi = radar.lat;
|
||||
let radar_r = ((A.powi(2) * radar_phi.cos()).powi(2) + (B.powi(2) * radar_phi.sin()).powi(2)
|
||||
/ (A * radar_phi.cos()).powi(2) + (B * radar_phi.sin()).powi(2)).sqrt();
|
||||
let radar_r = ((A.powi(2) * radar_phi.cos()).powi(2)
|
||||
+ (B.powi(2) * radar_phi.sin()).powi(2) / (A * radar_phi.cos()).powi(2)
|
||||
+ (B * radar_phi.sin()).powi(2))
|
||||
.sqrt();
|
||||
|
||||
let radar_x = radar_r * radar_theta.cos() * radar_phi.sin();
|
||||
let radar_y = radar_r * radar_theta.sin() * radar_phi.sin();
|
||||
|
@ -94,7 +96,6 @@ mod tests {
|
|||
let measurement_phi = radar_phi;
|
||||
let measurement_r = radar_r;
|
||||
|
||||
|
||||
let measurement_x = measurement_r * measurement_theta.cos() * measurement_phi.sin();
|
||||
let measurement_y = measurement_r * measurement_theta.sin() * measurement_phi.sin();
|
||||
let measurement_z = measurement_r * measurement_theta.cos();
|
||||
|
@ -103,7 +104,8 @@ mod tests {
|
|||
let radar_local_y = measurement_y - radar_y;
|
||||
let radar_local_z = measurement_z - radar_z;
|
||||
|
||||
let radar_local_r = (radar_local_x.powi(2) + radar_local_y.powi(2) + radar_local_z.powi(2)).sqrt();
|
||||
let radar_local_r =
|
||||
(radar_local_x.powi(2) + radar_local_y.powi(2) + radar_local_z.powi(2)).sqrt();
|
||||
let radar_local_theta = (radar_local_y / radar_local_x).atan();
|
||||
let radar_local_phi = (radar_local_z / radar_local_r).acos();
|
||||
|
||||
|
@ -111,4 +113,4 @@ mod tests {
|
|||
let elevation = radar_local_phi;
|
||||
let distance = radar_local_r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,19 +93,18 @@ pub static NOAA_MRMS_MERGED_RHOHV_3KM_CONUS: LazyLock<LayerSource> =
|
|||
tile_size: 512,
|
||||
max_zoom: 19,
|
||||
});
|
||||
pub static ROC_KCRP_TEST: LazyLock<LayerSource> =
|
||||
LazyLock::new(|| LayerSource {
|
||||
source_id: 0x0EFAF68CB6E30B8E,
|
||||
tile_url: format!(
|
||||
"{}/nexrad/kcrp_ref_test/{{z}}/{{x}}/{{y}}@2x.png",
|
||||
env!("TILER_BASE_URL")
|
||||
),
|
||||
display_name: "KCRP SSR Test".into(),
|
||||
short_name: "KCRP SSR TEST (KCRP)".into(),
|
||||
type_hint: LayerTypeHint::RadarData,
|
||||
location: "KCRP".into(),
|
||||
source: "NOAA / ROC".into(),
|
||||
source_link: "https://roc.noaa.gov".into(),
|
||||
tile_size: 512,
|
||||
max_zoom: 19,
|
||||
});
|
||||
pub static ROC_KCRP_TEST: LazyLock<LayerSource> = LazyLock::new(|| LayerSource {
|
||||
source_id: 0x0EFAF68CB6E30B8E,
|
||||
tile_url: format!(
|
||||
"{}/nexrad/kcrp_ref_test/{{z}}/{{x}}/{{y}}@2x.png",
|
||||
env!("TILER_BASE_URL")
|
||||
),
|
||||
display_name: "KCRP SSR Test".into(),
|
||||
short_name: "KCRP SSR TEST (KCRP)".into(),
|
||||
type_hint: LayerTypeHint::RadarData,
|
||||
location: "KCRP".into(),
|
||||
source: "NOAA / ROC".into(),
|
||||
source_link: "https://roc.noaa.gov".into(),
|
||||
tile_size: 512,
|
||||
max_zoom: 19,
|
||||
});
|
||||
|
|
|
@ -62,7 +62,7 @@ impl LayerManager {
|
|||
&*NOAA_MRMS_MERGED_CREF_QC_GUAM, // Guam
|
||||
// -- NOAA MRMS - Merged RhoHV (Differential Reflectivity) @ 3km
|
||||
&*NOAA_MRMS_MERGED_RHOHV_3KM_CONUS,
|
||||
&*ROC_KCRP_TEST
|
||||
&*ROC_KCRP_TEST,
|
||||
];
|
||||
|
||||
for layer in layers {
|
||||
|
|
|
@ -2,13 +2,13 @@ pub mod error;
|
|||
pub mod wgs84;
|
||||
|
||||
use crate::error::GribError;
|
||||
use wxbox_nommer::NomReader;
|
||||
use crate::wgs84::LatLong;
|
||||
use crate::LatLongVectorRelativity::{EasterlyAndNortherly, IncreasingXY};
|
||||
use image::{DynamicImage, ImageFormat, ImageReader};
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::io::{Cursor, Read};
|
||||
use tracing::warn;
|
||||
use wxbox_nommer::NomReader;
|
||||
|
||||
pub const INDICATOR: u32 = u32::from_be_bytes(*b"GRIB");
|
||||
pub const EDITION: u8 = 2;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::grib2::Grib2DataConfig;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::nexrad::NexradDataConfig;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
|
|
|
@ -9,6 +9,7 @@ use flate2::read::GzDecoder;
|
|||
use image::codecs::png::PngEncoder;
|
||||
use image::{Rgba, RgbaImage};
|
||||
use moka::future::Cache;
|
||||
use rayon::iter::IntoParallelIterator;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::f64::consts::PI;
|
||||
|
@ -17,7 +18,6 @@ use std::io;
|
|||
use std::io::{Cursor, ErrorKind};
|
||||
use std::num::TryFromIntError;
|
||||
use std::sync::Arc;
|
||||
use rayon::iter::IntoParallelIterator;
|
||||
use tokio::io::AsyncReadExt;
|
||||
use tracing::{debug, info_span};
|
||||
use wxbox_grib2::GribMessage;
|
||||
|
@ -146,21 +146,29 @@ async fn render_to_png(
|
|||
let tile_y_times_tilesize = tile_id.y as f64 * tile_id.size as f64;
|
||||
|
||||
let generate_pixels_span = info_span!("generate_pixels");
|
||||
let pixels = (0..tile_id.size).into_par_iter().map(|x| {
|
||||
(0..tile_id.size).into_par_iter().map(|y| {
|
||||
let x_cartesian = (tile_x_times_tilesize + x as f64) / n;
|
||||
let y_cartesian = (tile_y_times_tilesize + y as f64) / n;
|
||||
let pixels = (0..tile_id.size)
|
||||
.into_par_iter()
|
||||
.map(|x| {
|
||||
(0..tile_id.size)
|
||||
.into_par_iter()
|
||||
.map(|y| {
|
||||
let x_cartesian = (tile_x_times_tilesize + x as f64) / n;
|
||||
let y_cartesian = (tile_y_times_tilesize + y as f64) / n;
|
||||
|
||||
let long = (TWO_PI * x_cartesian - PI).to_degrees();
|
||||
let lat = ((PI - TWO_PI * y_cartesian).exp().atan() * 2.0_f64 - HALF_PI).to_degrees();
|
||||
let long = (TWO_PI * x_cartesian - PI).to_degrees();
|
||||
let lat =
|
||||
((PI - TWO_PI * y_cartesian).exp().atan() * 2.0_f64 - HALF_PI).to_degrees();
|
||||
|
||||
let nearest_value = data.value_for(LatLong { lat, long }).map(|u| u as f64);
|
||||
let nearest_value = data.value_for(LatLong { lat, long }).map(|u| u as f64);
|
||||
|
||||
let color = colorize(nearest_value, &data_source).unwrap_or(Rgba::from([0,0,0,0]));
|
||||
let color =
|
||||
colorize(nearest_value, &data_source).unwrap_or(Rgba::from([0, 0, 0, 0]));
|
||||
|
||||
color
|
||||
}).collect::<Vec<_>>()
|
||||
}).collect::<Vec<_>>();
|
||||
color
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
drop(generate_pixels_span);
|
||||
|
||||
let put_pixels_span = info_span!("put_pixels");
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
mod config;
|
||||
mod error;
|
||||
mod grib2;
|
||||
mod tiles;
|
||||
mod nexrad;
|
||||
mod tiles;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::grib2::{Grib2DataCache, Grib2TileCache, grib2_handler};
|
||||
use crate::nexrad::{NexradDataCache, NexradTileCache, nexrad_handler};
|
||||
use crate::tiles::{DataId, TileId};
|
||||
use axum::Router;
|
||||
use axum::routing::get;
|
||||
|
@ -16,7 +17,6 @@ use std::sync::Arc;
|
|||
use tracing_subscriber::fmt::format::FmtSpan;
|
||||
use tracing_subscriber::util::SubscriberInitExt;
|
||||
use wxbox_grib2::GribMessage;
|
||||
use crate::nexrad::{nexrad_handler, NexradDataCache, NexradTileCache};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
|
|
|
@ -6,9 +6,12 @@ use axum::extract::{Path, State};
|
|||
use axum::http::{StatusCode, header};
|
||||
use axum::response::IntoResponse;
|
||||
use flate2::read::GzDecoder;
|
||||
use geographiclib::Geodesic;
|
||||
use image::codecs::png::PngEncoder;
|
||||
use image::{Rgba, RgbaImage};
|
||||
use moka::future::Cache;
|
||||
use rayon::iter::IntoParallelIterator;
|
||||
use rayon::iter::ParallelIterator;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::f64::consts::PI;
|
||||
|
@ -17,14 +20,11 @@ use std::io;
|
|||
use std::io::{Cursor, ErrorKind};
|
||||
use std::num::TryFromIntError;
|
||||
use std::sync::Arc;
|
||||
use geographiclib::Geodesic;
|
||||
use rayon::iter::IntoParallelIterator;
|
||||
use tokio::io::AsyncReadExt;
|
||||
use tracing::{debug, info_span};
|
||||
use wxbox_ar2::{parse, MomentValue, Scan, DATA_BYTES, Radial, Sweep};
|
||||
use wxbox_ar2::sites::wsr88d::{SITES, Wsr88dSite};
|
||||
use wxbox_ar2::{DATA_BYTES, MomentValue, Radial, Scan, Sweep, parse};
|
||||
use wxbox_grib2::GribMessage;
|
||||
use rayon::iter::ParallelIterator;
|
||||
use wxbox_grib2::wgs84::LatLong;
|
||||
use wxbox_pal::{ColorPalette, Palette};
|
||||
|
||||
|
@ -126,7 +126,15 @@ fn radius_at_latitude(phi: f64) -> f64 {
|
|||
(top / bottom).sqrt()
|
||||
}
|
||||
|
||||
fn calculate_inverse(tile_x_times_tilesize: f64, tile_y_times_tilesize: f64, x: usize, y: usize, g: &Geodesic, radar: &Wsr88dSite, n: f64) -> (f64, f64) {
|
||||
fn calculate_inverse(
|
||||
tile_x_times_tilesize: f64,
|
||||
tile_y_times_tilesize: f64,
|
||||
x: usize,
|
||||
y: usize,
|
||||
g: &Geodesic,
|
||||
radar: &Wsr88dSite,
|
||||
n: f64,
|
||||
) -> (f64, f64) {
|
||||
let x_cartesian = (tile_x_times_tilesize + x as f64) / n;
|
||||
let y_cartesian = (tile_y_times_tilesize + y as f64) / n;
|
||||
|
||||
|
@ -145,7 +153,9 @@ fn locate_radial(azimuth: f64, sweep: &Sweep) -> Option<&Radial> {
|
|||
|
||||
for radial in &sweep.radials {
|
||||
let this_dist = (radial.azimuth_angle_degrees as f64 - azimuth).abs();
|
||||
if this_dist.abs() > radial.azimuth_spacing_degrees as f64 { continue; }
|
||||
if this_dist.abs() > radial.azimuth_spacing_degrees as f64 {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(previous_best) = closest_radial {
|
||||
let curr_dist = (previous_best.azimuth_angle_degrees as f64 - azimuth).abs();
|
||||
|
@ -156,8 +166,6 @@ fn locate_radial(azimuth: f64, sweep: &Sweep) -> Option<&Radial> {
|
|||
} else {
|
||||
closest_radial = Some(radial);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
closest_radial
|
||||
|
@ -189,39 +197,58 @@ async fn render_to_png(
|
|||
drop(prep_span);
|
||||
|
||||
let generate_pixels_span = info_span!("generate_pixels");
|
||||
let pixels = (0..tile_id.size).into_par_iter().map(|x| {
|
||||
(0..tile_id.size).into_par_iter().map(|y| {
|
||||
let (d_m, azimuth) = calculate_inverse(tile_x_times_tilesize, tile_y_times_tilesize, x, y, &g, radar, n);
|
||||
let Some(radial) = locate_radial(azimuth, first_sweep) else { return colorize(None, &data_source).unwrap_or(Rgba::from([0,0,0,0])) };
|
||||
let pixels = (0..tile_id.size)
|
||||
.into_par_iter()
|
||||
.map(|x| {
|
||||
(0..tile_id.size)
|
||||
.into_par_iter()
|
||||
.map(|y| {
|
||||
let (d_m, azimuth) = calculate_inverse(
|
||||
tile_x_times_tilesize,
|
||||
tile_y_times_tilesize,
|
||||
x,
|
||||
y,
|
||||
&g,
|
||||
radar,
|
||||
n,
|
||||
);
|
||||
let Some(radial) = locate_radial(azimuth, first_sweep) else {
|
||||
return colorize(None, &data_source).unwrap_or(Rgba::from([0, 0, 0, 0]));
|
||||
};
|
||||
|
||||
let reflectivity = radial.reflectivity.as_ref().unwrap();
|
||||
let reflectivity = radial.reflectivity.as_ref().unwrap();
|
||||
|
||||
let distance_km = d_m / 1000.0;
|
||||
let distance_km = d_m / 1000.0;
|
||||
|
||||
let first_gate_distance = reflectivity.start_range as f64 / 1000.0; // stored in meters
|
||||
let gate_spacing = reflectivity.sample_interval as f64 / 1000.0; // also stored in meters
|
||||
let first_gate_distance = reflectivity.start_range as f64 / 1000.0; // stored in meters
|
||||
let gate_spacing = reflectivity.sample_interval as f64 / 1000.0; // also stored in meters
|
||||
|
||||
if distance_km < first_gate_distance {
|
||||
return colorize(None, &data_source).unwrap_or(Rgba::from([0,0,0,0]))
|
||||
}
|
||||
if distance_km < first_gate_distance {
|
||||
return colorize(None, &data_source).unwrap_or(Rgba::from([0, 0, 0, 0]));
|
||||
}
|
||||
|
||||
let gate = ((distance_km - first_gate_distance) / gate_spacing).round() as usize;
|
||||
let gate =
|
||||
((distance_km - first_gate_distance) / gate_spacing).round() as usize;
|
||||
|
||||
let data = &reflectivity.values;
|
||||
let data = &reflectivity.values;
|
||||
|
||||
if gate > data.len() || gate < 0 {
|
||||
return colorize(None, &data_source).unwrap_or(Rgba::from([0,0,0,0]));
|
||||
}
|
||||
if gate > data.len() || gate < 0 {
|
||||
return colorize(None, &data_source).unwrap_or(Rgba::from([0, 0, 0, 0]));
|
||||
}
|
||||
|
||||
let color = data.get(gate).map(|raw_value| match raw_value {
|
||||
0 => MomentValue::BelowThreshold,
|
||||
1 => MomentValue::RangeFolded,
|
||||
_ => MomentValue::Value((*raw_value as f32 - reflectivity.offset) / reflectivity.scale),
|
||||
});
|
||||
let color = data.get(gate).map(|raw_value| match raw_value {
|
||||
0 => MomentValue::BelowThreshold,
|
||||
1 => MomentValue::RangeFolded,
|
||||
_ => MomentValue::Value(
|
||||
(*raw_value as f32 - reflectivity.offset) / reflectivity.scale,
|
||||
),
|
||||
});
|
||||
|
||||
return colorize(color, &data_source).unwrap_or(Rgba::from([0,0,0,0]));
|
||||
}).collect::<Vec<_>>()
|
||||
}).collect::<Vec<_>>();
|
||||
return colorize(color, &data_source).unwrap_or(Rgba::from([0, 0, 0, 0]));
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
drop(generate_pixels_span);
|
||||
|
||||
let put_pixels_span = info_span!("put_pixels");
|
||||
|
@ -242,7 +269,6 @@ async fn render_to_png(
|
|||
|
||||
let output = Arc::new(result);
|
||||
|
||||
|
||||
drop(encode_span);
|
||||
drop(span);
|
||||
|
||||
|
@ -251,7 +277,10 @@ async fn render_to_png(
|
|||
Ok(output)
|
||||
}
|
||||
|
||||
fn colorize(value: Option<MomentValue>, data_source: &NexradDataSource) -> anyhow::Result<Rgba<u8>> {
|
||||
fn colorize(
|
||||
value: Option<MomentValue>,
|
||||
data_source: &NexradDataSource,
|
||||
) -> anyhow::Result<Rgba<u8>> {
|
||||
Ok(match value {
|
||||
Some(MomentValue::BelowThreshold) => Rgba([0, 0, 0, 0]),
|
||||
Some(MomentValue::RangeFolded) => Rgba([119, 0, 125, 255]),
|
||||
|
|
Loading…
Add table
Reference in a new issue