189 lines
5.8 KiB
Rust
189 lines
5.8 KiB
Rust
mod error;
|
|
use geo::{algorithm::haversine_destination::HaversineDestination, Point};
|
|
mod parser;
|
|
use abi_stable::{
|
|
export_root_module,
|
|
prefix_type::PrefixTypeTrait,
|
|
sabi_extern_fn,
|
|
sabi_trait::prelude::TD_Opaque,
|
|
std_types::{
|
|
RNone, ROk,
|
|
ROption::RSome,
|
|
RResult::{self, RErr},
|
|
RStr, RString, RVec,
|
|
},
|
|
};
|
|
use parser::{Record, ValueResult};
|
|
|
|
use radarg_plugin_interface::{
|
|
DataLoaderPlugin, DataLoaderPlugin_TO, Error, GridDataInfo, LoadedData, PluginId, PluginMod,
|
|
PluginMod_Ref, PluginType, ProbeDataType, RadarGridData, VecResult,
|
|
};
|
|
|
|
macro_rules! data_rvec {
|
|
($data:ident, $({$parsed_vec:tt => $abi_stable_rvec:tt}),+) => {
|
|
match $data {
|
|
$(
|
|
ValueResult::$parsed_vec(data) => VecResult::$abi_stable_rvec(RVec::from(data)),
|
|
)+
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! data_type {
|
|
($datetype:ident, $({ $($name:literal)|+ => $type:tt }),+) => {
|
|
|
|
match $datetype {
|
|
$(
|
|
$($name)|+ => ProbeDataType::$type,
|
|
)+
|
|
_ => ProbeDataType::Unknown
|
|
}
|
|
|
|
};
|
|
}
|
|
|
|
#[export_root_module]
|
|
fn instantiate_root_module() -> PluginMod_Ref {
|
|
PluginMod { new }.leak_into_prefix()
|
|
}
|
|
|
|
struct ETWSLoader {
|
|
id: PluginId,
|
|
}
|
|
|
|
impl DataLoaderPlugin for ETWSLoader {
|
|
fn plugin_id(&self) -> &PluginId {
|
|
&self.id
|
|
}
|
|
|
|
fn load(&self, path: RStr<'_>) -> RResult<RVec<LoadedData>, Error> where {
|
|
if let Ok(record) = Record::parse_from_path(path.to_string()) {
|
|
let result = record
|
|
.blocks
|
|
.into_iter()
|
|
.map(|b| {
|
|
let data = b.data;
|
|
let converted_data = data_rvec!(
|
|
data,
|
|
{I16 => I16},
|
|
{F32 => F32},
|
|
{F64 => F64},
|
|
{I32 => I32},
|
|
{U32 => U32},
|
|
{I64 => I64},
|
|
{U64 => U64},
|
|
{I8 => I8},
|
|
{U8 => U8}
|
|
);
|
|
|
|
let dimension_values = convert_nested_vec_to_rvec(b.info.dimension_values);
|
|
let dimension_size = convert_vec_to_rvec(
|
|
b.info
|
|
.dimension_size
|
|
.into_iter()
|
|
.map(|p| p as usize)
|
|
.collect::<Vec<_>>(),
|
|
);
|
|
let dimension_names = convert_vec_to_rvec(
|
|
b.info
|
|
.dimension_des
|
|
.into_iter()
|
|
.map(RString::from)
|
|
.collect::<Vec<_>>(),
|
|
);
|
|
|
|
let fill_value = b.info.fill_value;
|
|
let value_name = RString::from(b.info.value_name);
|
|
let value_description = RString::from(b.info.value_des);
|
|
let datetime = record.filetime.timestamp();
|
|
|
|
let value_key = value_name.as_str();
|
|
|
|
let data_type = data_type!(
|
|
value_key,
|
|
{ "ET" => ET },
|
|
{ "DBZ" | "CR" | "FR" | "R" => DBZ},
|
|
{ "VIL" => VIL},
|
|
{ "EB" => EB},
|
|
{ "V" => V},
|
|
{ "ZDR" => ZDR},
|
|
{ "PHIDP" => PHIDP},
|
|
{ "KDP" => KDP},
|
|
{ "CC" =>CC},
|
|
{ "HCA" => HCA},
|
|
{ "QPE" => QPE},
|
|
{ "QPF" => QPF}
|
|
);
|
|
|
|
let grid_info = GridDataInfo {
|
|
shape: dimension_size,
|
|
dimensions: dimension_values,
|
|
dimension_names,
|
|
fill_value,
|
|
datetime: RSome(datetime),
|
|
value_description: RSome(value_description),
|
|
maybe_probe_data_type: RSome(data_type),
|
|
value_name,
|
|
dimension_description: "Wrong".into(),
|
|
};
|
|
|
|
LoadedData::RadarGridData(RadarGridData {
|
|
data: converted_data,
|
|
info: grid_info,
|
|
})
|
|
})
|
|
.collect::<RVec<_>>();
|
|
|
|
ROk(result)
|
|
} else {
|
|
RErr(Error::UnsupportedFormat)
|
|
}
|
|
}
|
|
|
|
fn plugin_info(&self) -> radarg_plugin_interface::PluginInfo where {
|
|
radarg_plugin_interface::PluginInfo {
|
|
plugin_type: "DataLoader".into(),
|
|
name: "ETWS_Loader".into(),
|
|
version: "0.1.0".into(),
|
|
author: "Tsuki".into(),
|
|
description: RSome("ETWS Loader".into()),
|
|
url: RSome("https://keitsuki.club".into()),
|
|
}
|
|
}
|
|
}
|
|
|
|
fn convert_iter_to_rvec<T>(raw: impl Iterator<Item = T>) -> RVec<T> {
|
|
RVec::from(raw.collect::<Vec<_>>())
|
|
}
|
|
|
|
fn convert_vec_to_rvec<T>(raw: Vec<T>) -> RVec<T> {
|
|
RVec::from(raw)
|
|
}
|
|
|
|
fn convert_nested_vec_to_rvec<T>(raw: Vec<Vec<T>>) -> RVec<RVec<T>> {
|
|
RVec::from(raw.into_iter().map(RVec::from).collect::<Vec<_>>())
|
|
}
|
|
|
|
#[sabi_extern_fn]
|
|
pub fn new(plugin_id: PluginId) -> RResult<PluginType, Error> {
|
|
let this = ETWSLoader { id: plugin_id };
|
|
ROk(DataLoaderPlugin_TO::from_value(this, TD_Opaque))
|
|
}
|
|
|
|
// 测试模块
|
|
#[cfg(test)]
|
|
mod tests {
|
|
// 导入外部作用域中的所有项
|
|
use super::*;
|
|
|
|
// 一个简单的测试
|
|
#[test]
|
|
|
|
fn test() {
|
|
let result =
|
|
Record::parse_from_path("/Volumes/data2/RadarArray/ShaoXing/radarData/OutputProducts/RadarProducts/BasicProductsX/20230627/20230627163400/ZJSXAA_20230627163400_VIL.dat.gz")
|
|
.unwrap();
|
|
}
|
|
}
|