120 lines
5.7 KiB
Rust
120 lines
5.7 KiB
Rust
use ordered_float::OrderedFloat;
|
|
use crate::cif::cif_container::MessageType;
|
|
use crate::{AsCif, cif};
|
|
use nexrad_decode::messages::digital_radar_data::RadialStatus;
|
|
use wxbox_ar2::{MomentData, Radial, Scan};
|
|
|
|
pub struct Ar2AsCifParams {
|
|
pub requested_elevation: u8,
|
|
pub requested_product: String,
|
|
}
|
|
|
|
impl AsCif for Scan {
|
|
type Params = Ar2AsCifParams;
|
|
fn as_cif(&self, params: &Self::Params) -> cif::CifContainer {
|
|
let mut digital_radar_data = cif::digital_radar_data::DigitalRadarData::default();
|
|
digital_radar_data.elevation_number = params.requested_elevation as i32;
|
|
digital_radar_data.vcp_number = self.coverage_pattern_number as i32;
|
|
|
|
// find the elevation
|
|
let mut maybe_elevation = self
|
|
.sweeps
|
|
.iter()
|
|
.find(|u| u.elevation_number == params.requested_elevation);
|
|
if let Some(elevation) = maybe_elevation {
|
|
// parse out the radials
|
|
let mut radials_we_can_use: Vec<(&Radial, &MomentData)> = vec![];
|
|
let mut elevation = elevation.clone();
|
|
elevation.radials.sort_by_key(|u| OrderedFloat(u.azimuth_angle_degrees));
|
|
for radial in &elevation.radials {
|
|
match params.requested_product.as_str() {
|
|
"REF" if radial.reflectivity.is_some() => {
|
|
radials_we_can_use.push((&radial, &radial.reflectivity.as_ref().unwrap()));
|
|
}
|
|
"VEL" if radial.velocity.is_some() => {
|
|
radials_we_can_use.push((&radial, &radial.velocity.as_ref().unwrap()));
|
|
}
|
|
"SW" if radial.spectrum_width.is_some() => {
|
|
radials_we_can_use
|
|
.push((&radial, &radial.spectrum_width.as_ref().unwrap()));
|
|
}
|
|
"ZDR" if radial.differential_reflectivity.is_some() => {
|
|
radials_we_can_use
|
|
.push((&radial, &radial.differential_reflectivity.as_ref().unwrap()));
|
|
}
|
|
"PHI" if radial.differential_phase.is_some() => {
|
|
radials_we_can_use
|
|
.push((&radial, &radial.differential_phase.as_ref().unwrap()));
|
|
}
|
|
"RHO" if radial.correlation_coefficient.is_some() => {
|
|
radials_we_can_use
|
|
.push((&radial, &radial.correlation_coefficient.as_ref().unwrap()));
|
|
}
|
|
"CFP" if radial.specific_differential_phase.is_some() => {
|
|
radials_we_can_use.push((
|
|
&radial,
|
|
&radial.specific_differential_phase.as_ref().unwrap(),
|
|
));
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
digital_radar_data.radials = radials_we_can_use
|
|
.iter()
|
|
.map(|u| {
|
|
let mut radial = cif::digital_radar_data::Radial::default();
|
|
radial.elevation_number = u.0.elevation_number as i32;
|
|
radial.azimuth_angle_degrees = u.0.azimuth_angle_degrees;
|
|
radial.azimuth_number = u.0.azimuth_number as i32;
|
|
radial.azimuth_spacing_degrees = u.0.azimuth_spacing_degrees;
|
|
radial.collection_timestamp = u.0.collection_timestamp as u64;
|
|
radial.elevation_degrees = u.0.elevation_number_degrees;
|
|
radial.radial_status = match u.0.radial_status {
|
|
RadialStatus::ElevationStart => {
|
|
cif::digital_radar_data::RadialStatus::ElevationStart
|
|
}
|
|
RadialStatus::IntermediateRadialData => {
|
|
cif::digital_radar_data::RadialStatus::IntermediateRadialData
|
|
}
|
|
RadialStatus::ElevationEnd => {
|
|
cif::digital_radar_data::RadialStatus::ElevationEnd
|
|
}
|
|
RadialStatus::VolumeScanStart => {
|
|
cif::digital_radar_data::RadialStatus::VolumeScanStart
|
|
}
|
|
RadialStatus::VolumeScanEnd => {
|
|
cif::digital_radar_data::RadialStatus::VolumeScanEnd
|
|
}
|
|
RadialStatus::ElevationStartVCPFinal => {
|
|
cif::digital_radar_data::RadialStatus::ElevationStartVcpFinal
|
|
}
|
|
}
|
|
.into();
|
|
|
|
let mut moment_meta = cif::digital_radar_data::MomentaryMeta::default();
|
|
moment_meta.product_name = params.requested_product.clone();
|
|
|
|
let mut moment_data = cif::digital_radar_data::MomentaryData::default();
|
|
moment_data.offset = u.1.offset;
|
|
moment_data.sample_interval = u.1.sample_interval as i32;
|
|
moment_data.scale = u.1.scale;
|
|
moment_data.start_range = u.1.start_range as i32;
|
|
moment_data.data = u.1.values.iter().map(|u| *u as i32).collect();
|
|
|
|
let mut moment_product = cif::digital_radar_data::MomentaryProduct::default();
|
|
moment_product.product_metadata = Some(moment_meta);
|
|
moment_product.data = Some(moment_data);
|
|
|
|
radial.product = Some(moment_product);
|
|
|
|
radial
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
let mut container = cif::CifContainer::default();
|
|
container.message_type = Some(MessageType::DigitalRadarData(digital_radar_data));
|
|
container
|
|
}
|
|
}
|