diff --git a/Cargo.lock b/Cargo.lock index 882460c..11885ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -214,6 +214,7 @@ dependencies = [ "npyz", "num-traits", "proj", + "proj-sys", "quadtree_rs", "shapefile", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index 2420575..13e0db2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ num-traits = "0.2.15" npyz = { version = "0.8.0", features = ["npz"] } ndarray = "0.15.6" quadtree_rs = "0.1.2" +proj-sys = "0.23.1" [build-dependencies] glib-build-tools = "0.17.0" diff --git a/p.py b/p.py new file mode 100644 index 0000000..80c382a --- /dev/null +++ b/p.py @@ -0,0 +1,12 @@ +import numpy as np + +a = np.load("/home/ruomu/Desktop/test.npz") + +b = a['value'] +lon = a['lon'] +lat = a['lat'] + +a = np.load("/home/ruomu/Desktop/test2.npz")['value'] + + +np.savez("/home/ruomu/Desktop/test2.npz", value=np.max(b,axis=0), lon=lon, lat=lat) \ No newline at end of file diff --git a/src/data.rs b/src/data.rs index 6e24f42..2a0be4d 100644 --- a/src/data.rs +++ b/src/data.rs @@ -1,16 +1,10 @@ -use ndarray::{ - arr2, array, s, Array, Array1, Array2, Array3, ArrayBase, ArrayView2, Axis, Ix2, OwnedRepr, - RawDataClone, Slice, ViewRepr, -}; -use npyz::{npz::NpzArchive, DType, Deserialize, TypeChar}; -use num_traits::{AsPrimitive, FromPrimitive, Num, ToPrimitive}; +use ndarray::{s, Array1, Array2, Array3, ArrayBase, Ix1, Ix2, OwnedRepr, RawDataClone}; +use npyz::{npz::NpzArchive, Deserialize}; +use num_traits::{AsPrimitive, FromPrimitive, Num}; use quadtree_rs::{area::AreaBuilder, Quadtree}; -use std::{self, borrow::Borrow, f64::consts::PI, io::BufReader, path::Path}; +use std::{self, f64::consts::PI, fmt::Debug, io::BufReader, path::Path}; use thiserror::Error; -type Lon = f64; -type Lat = f64; - #[derive(Error, Debug)] pub enum DataError { #[error("value")] @@ -42,7 +36,7 @@ where pub coord_type: CoorType, } -pub struct RadarData3d +struct RadarData3d where T: Num, X: Num, @@ -59,7 +53,7 @@ trait MultiDimensionData {} impl RadarData2d where - T: Num + AsPrimitive + FromPrimitive + Clone, + T: Num + AsPrimitive + FromPrimitive + Clone + Debug, Raw: ndarray::Data + Clone + ndarray::RawDataClone, { fn value_to_owned(self) -> RadarData2d> { @@ -83,22 +77,25 @@ where CoorType::Polar => Err(DataError::FormatError), CoorType::LatLon => { let width_filtered: ArrayBase, Ix2> = - Self::_resample(&self.data, width_rate, filter_len, false); + Self::_resample(&self.data, width_rate, filter_len); - let new_dim1 = Self::_resample( + let result: ArrayBase, Ix2> = + Self::_resample(&width_filtered.t(), height_rate, filter_len) + .t() + .to_owned(); + + let new_dim1: ArrayBase, Ix1> = Self::_resample( &Array2::from_shape_vec((1, self.dim1.len()), self.dim1.to_vec()).unwrap(), width_rate, filter_len, - false, ) .slice(s![0, ..]) .to_owned(); - let new_dim2 = Self::_resample( + let new_dim2: ArrayBase, Ix1> = Self::_resample( &Array2::from_shape_vec((1, self.dim2.len()), self.dim2.to_vec()).unwrap(), - width_rate, + height_rate, filter_len, - false, ) .slice(s![0, ..]) .to_owned(); @@ -106,7 +103,7 @@ where Ok(RadarData2d { dim1: new_dim1, dim2: new_dim2, - data: Self::_resample(&width_filtered, height_rate, filter_len, true), + data: result, coord_type: self.coord_type.to_owned(), }) } @@ -154,13 +151,12 @@ where data: &'a ArrayBase, rate: f64, filter_len: f64, - reverse: bool, ) -> Array2 where V: Num + Clone + AsPrimitive + FromPrimitive, { - let ori_width = if reverse { data.nrows() } else { data.ncols() }; - let ori_height = if reverse { data.ncols() } else { data.nrows() }; + let ori_width = data.ncols(); + let ori_height = data.nrows(); let new_width = (ori_width as f64 * rate).ceil() as usize; let mut result: Array2 = Array2::zeros((ori_height, new_width)); @@ -202,11 +198,11 @@ fn windowed_sinc(x: f64, y: f64) -> f64 { sinc * window } -pub struct LevelData(Quadtree>>); +pub struct LevelData(pub Quadtree>>); impl LevelData where - T: Num + Clone + AsPrimitive + FromPrimitive, + T: Num + Clone + AsPrimitive + FromPrimitive + Debug, { fn value( level_data: Vec>>, @@ -218,19 +214,22 @@ where let mut result: Vec>> = Vec::with_capacity(level_data.len() * 4); - let a = level_data.first().unwrap().split(); - result.extend(a.into_iter().map(|x| x.value_to_owned())); + let results = level_data + .iter() + .flat_map(|v| v.split().into_iter().map(|x| x.value_to_owned())); + + result.extend(results); return Self::value(result, level_num - 1); } - fn new(data: RadarData2d>, level: usize) -> Self { - let rate = 1.0 / level as f64; + fn new(data: &RadarData2d>, level: usize, rate: f64) -> Self { + // let rate = 1.0 / level as f64; let resampled = data.resample(rate, rate, 2.0).unwrap(); let blocks = Self::value(vec![resampled], level); let mut tree: Quadtree>> = - quadtree_rs::Quadtree::new(blocks.len()); + quadtree_rs::Quadtree::new(level); blocks.into_iter().for_each(|block| { tree.insert( @@ -250,13 +249,14 @@ where } } -pub fn levels(data: RadarData2d>, levels: usize) -> Vec> +pub fn levels(data: Radar2d, levels: usize) -> Vec> where - T: Num + Clone + AsPrimitive + FromPrimitive, + T: Num + Clone + AsPrimitive + FromPrimitive + Debug, { + let numerator = 1.0 / levels as f64; (0..levels) .into_iter() - .map(|level| LevelData::new(data.clone(), level)) + .map(|level| LevelData::new(&data.0, level + 1, 1.0 - level as f64 * numerator)) .collect() } @@ -311,23 +311,9 @@ where { fn load>(&self, path: P) -> Result>, DataError> { let mut data: NpzArchive> = npyz::npz::NpzArchive::open(path)?; - if let DType::Plain(type_str) = data.by_name("val")?.unwrap().dtype() { - let bytes_num = type_str.num_bytes().unwrap(); - match type_str.type_char() { - TypeChar::Float => match bytes_num { - 4 => self.load_2d::(&mut data, "val")?, - 8 => self.load_2d::(&mut data, "val")?, - _ => {} - }, - - TypeChar::Int => {} - - _ => {} - } - } - let dim1 = self.load_1d::(&mut data, "dim1")?; - let dim2 = self.load_1d::(&mut data, "dim2")?; - let value = self.load_2d::(&mut data, "val")?; + let dim1 = self.load_1d::(&mut data, "lon")?; + let dim2 = self.load_1d::(&mut data, "lat")?; + let value = self.load_2d::(&mut data, "value")?; Ok(RadarData2d { dim1: dim1, @@ -337,3 +323,20 @@ where }) } } + +impl RadarData2d> { + pub fn load, M: DataLoader>(p: P, meth: M) -> Self { + meth.load(p).unwrap() + } +} + +pub struct Radar2d(RadarData2d>); + +impl Radar2d { + pub fn load( + path: impl AsRef, + meth: impl DataLoader>>, + ) -> Result { + Ok(Radar2d(meth.load(path)?)) + } +} diff --git a/src/main.rs b/src/main.rs index c194dc8..281fc71 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,8 @@ mod data; // mod trees; mod window; +use data::{Npz,Radar2d, levels}; + const APP_ID: &str = "org.gtk_rs.HelloWorld2"; fn main() -> glib::ExitCode { @@ -26,6 +28,16 @@ fn main() -> glib::ExitCode { // Connect to "activate" signal of `app` app.connect_activate(build_ui); + let path = "/home/ruomu/Desktop/test.npz"; + + let data = Radar2d::::load(path, Npz).unwrap(); + + let result = levels(data, 3); + + for i in result.iter(){ + println!("{:?}", i.0.depth()); + } + // Run the application app.run() }