From 613a219a49b63d1a799c6188f6713bacc0845000 Mon Sep 17 00:00:00 2001 From: xin Date: Fri, 27 Jun 2025 15:46:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=A5=E4=BA=86=E5=85=B3?= =?UTF-8?q?=E4=BA=8Einfo=E4=BF=A1=E6=81=AF=E4=B8=BAjson=E5=86=85=E9=83=A8?= =?UTF-8?q?=E7=AE=A1=E7=90=86=20=E8=AF=A5=E9=A1=B9=E7=9B=AE=E5=8F=AA?= =?UTF-8?q?=E9=80=82=E7=94=A8=E4=BA=8Ewindows=E6=88=96linux=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=BA=86c++=E5=8F=8A=E7=9B=B8=E5=BA=94=E7=9A=84rust?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=20=E4=B8=8D=E9=80=82=E7=94=A8=E4=BA=8Earm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...高光谱数据文件格式规范文档.md | 2 +- rust/iris_rust/Cargo.toml | 3 +- rust/iris_rust/src/examples.rs | 2 +- rust/iris_rust/src/lib.rs | 132 ++++++++++++++++++ rust/iris_rust/src/main.rs | 72 ++++++++-- rust/iris_rust/src/read.rs | 3 +- rust/iris_rust/src/structures.rs | 11 +- source/iris_format/iris_deffine.cpp | 9 +- 8 files changed, 215 insertions(+), 19 deletions(-) diff --git a/doc/高光谱数据文件格式规范文档.md b/doc/高光谱数据文件格式规范文档.md index b603f31..fb5da1d 100644 --- a/doc/高光谱数据文件格式规范文档.md +++ b/doc/高光谱数据文件格式规范文档.md @@ -113,7 +113,7 @@ struct IRIS_Time_Struct "latitude":115.01, "longitude": 39.01, "altitude": 100.0 - }, + } }, { "info_type": "devinfo", // 0 for device info diff --git a/rust/iris_rust/Cargo.toml b/rust/iris_rust/Cargo.toml index d33e75d..4188062 100644 --- a/rust/iris_rust/Cargo.toml +++ b/rust/iris_rust/Cargo.toml @@ -1,7 +1,8 @@ [package] -name = "iris_rust" +name = "iris_converter" version = "0.1.0" edition = "2024" [dependencies] +serde = { version = "1", features = ["derive"] } serde_json = "1.0.140" diff --git a/rust/iris_rust/src/examples.rs b/rust/iris_rust/src/examples.rs index dc415de..b3be110 100644 --- a/rust/iris_rust/src/examples.rs +++ b/rust/iris_rust/src/examples.rs @@ -85,7 +85,7 @@ pub fn read_iris_file_example() { // } // Now read it back - let path = "output_iris_data1.iris"; + let path = "data46.iris"; // let path = "output_iris_data.iris"; let mut read=match read::read_iris_file(path) { Ok(data) => { diff --git a/rust/iris_rust/src/lib.rs b/rust/iris_rust/src/lib.rs index fd17318..34a8a46 100644 --- a/rust/iris_rust/src/lib.rs +++ b/rust/iris_rust/src/lib.rs @@ -2,8 +2,140 @@ pub mod structures; pub mod read; pub mod write; pub mod examples; +use std::vec; +use serde::{Deserialize, Serialize}; +use serde_json::json; pub use structures::{TimeStruct, SpectralData, ImageInfo, OneIRISData}; pub use read::{read_time, read_spectral_data, read_image_info, read_iris_file}; pub use write::*; pub use examples::{spectral_data_roundtrip}; + +pub fn explortirisdatatojson(path:&String)->(){ + let irisdata=read_iris_file(path).unwrap(); + + // let irisjson=serde_json::to_string(&irisdata).unwrap(); 转字符串是用两个空格 + let irisjson = serde_json::to_string_pretty(&irisdata).unwrap(); + //将irisjson写入到path中 后缀iris改成.json + let json_path = path.replace(".iris", ".json"); + + std::fs::write(json_path, irisjson).expect("Unable to write JSON file"); + println!("IRIS data exported to JSON successfully!"); + + + +} + +pub fn explortirisdatatocsv(path:&String)->(){ + let irisdata=read_iris_file(path).unwrap(); + + //将irisdata转换为csv格式 + let mut csv_data = String::new(); + + let mut envermentinfo=serde_json::json!({}); + let mut devinfo=Vec::new(); + for spectral_info in &irisdata.spectral_info_section { + if spectral_info["info_type"] == "environment" { + envermentinfo = spectral_info.clone(); + } else { + devinfo.push(spectral_info.clone()); + } + } + // 添加环境信息 第一行 + csv_data.push_str("EnvironmentalContext"); + //获取环境信息的所有键和值 + for (key, value) in envermentinfo.as_object().unwrap() { + if key == "info_type" { + continue; // 跳过info_type + + } + if key == "date"{ + //将 yyyy-mm-dd hh:mm:ss 转换为 yyyy_mm_dd hh:mm:ss + let date_str = value.as_str().unwrap_or(""); + let formatted_date = date_str.replace("-", "_"); + csv_data.push_str(&format!(",{},{}", key, formatted_date)); + continue; // 跳过date + + } + //如果value是object类型,则将其转换为字符串 + if value.is_object() { + for (key1,value1) in value.as_object().unwrap() { + csv_data.push_str(&format!(",{}", key1)); + csv_data.push_str(&format!(",{}", value1)); + } + continue; // 跳过object类型的value + } + csv_data.push_str(&format!(",{},{}", key, value)); + } + csv_data.push_str("\n"); + // 添加设备信息 + let mut indexofdevinfo = 1; + for info in devinfo { + csv_data.push_str(&format!("FS{}_Info", indexofdevinfo)); + indexofdevinfo += 1; + //获取设备信息的所有键和值 + for (key, value) in info.as_object().unwrap() { + if key == "info_type" { + continue; // 跳过info_type + } + if key=="wave_coeff" { + continue; // 跳过wave_coeff + } + if value.is_object() { + // 如果value是object类型,则将其转换为字符串 + for (key1, value1) in value.as_object().unwrap() { + csv_data.push_str(&format!(",{}", key1)); + csv_data.push_str(&format!(",{}", value1)); + } + continue; // 跳过object类型的value + } + csv_data.push_str(&format!(",{},{}", key, value)); + } + csv_data.push_str("\n"); + let wavecoeff1=info["wave_coeff"]["a1"].as_f64().unwrap_or(0.0); + let wavecoeff2=info["wave_coeff"]["a2"].as_f64().unwrap_or(0.0); + let wavecoeff3=info["wave_coeff"]["a3"].as_f64().unwrap_or(0.0); + let wavecoeff4=info["wave_coeff"]["a4"].as_f64().unwrap_or(0.0); + let bandnum= info["bandnum"].as_u64().unwrap_or(0); + let wavelist: Vec = (0..bandnum) + .map(|i| wavecoeff4 + wavecoeff3 * (i as f64) + wavecoeff2 * (i as f64).powi(2) + wavecoeff1 * (i as f64).powi(3)) + .collect(); + // 添加波长信息 + csv_data.push_str(&format!("Wavelength")); + for (i, wave) in wavelist.iter().enumerate() { + csv_data.push_str(&format!(",{}" ,wave)); + } + csv_data.push_str("\n"); + + + + + } + // 添加光谱数据 + csv_data.push_str("Data Section\n"); + for SpectralData in &irisdata.spectral_data_section { + csv_data.push_str(&format!("{}_P{}", SpectralData.sensor_id,SpectralData.fiber_id)); + if SpectralData.valid_flag== 1 { + csv_data.push_str(",Valid"); + } else { + csv_data.push_str(",Invalid"); + } + csv_data.push_str(&format!(",{}", SpectralData.exposure)); + let vector_size = SpectralData.Get_Spectral_Data(); + + for value in &vector_size { + csv_data.push_str(&format!(",{}", value)); + } + csv_data.push_str("\n"); + } + + + + + //将csv_data写入到path中 后缀iris改成.csv + let csv_path = path.replace(".iris", ".csv"); + + std::fs::write(csv_path, csv_data).expect("Unable to write CSV file"); + println!("IRIS data exported to CSV successfully!"); + +} \ No newline at end of file diff --git a/rust/iris_rust/src/main.rs b/rust/iris_rust/src/main.rs index 5d09e62..4074d12 100644 --- a/rust/iris_rust/src/main.rs +++ b/rust/iris_rust/src/main.rs @@ -1,8 +1,6 @@ -use iris_rust::examples::{ - spectral_data_roundtrip, - image_info_roundtrip, - read_iris_file_example -}; +use iris_converter::{examples::{ + image_info_roundtrip, read_iris_file_example, spectral_data_roundtrip +}, explortirisdatatocsv, explortirisdatatojson}; fn main() { // println!("Running iris_rust examples..."); @@ -19,8 +17,66 @@ fn main() { // println!("\nTesting image info..."); // image_info_roundtrip(); - println!("\nReading IRIS file..."); + // println!("\nReading IRIS file..."); read_iris_file_example(); - + //explortirisdatatojson(&"iris_data_example.iris".to_string()); + // explortirisdatatocsv( &"iris_data_example.iris".to_string()); println!("\nAll examples completed successfully!"); -} \ No newline at end of file +} +use std::env; // 引入 env 模块以访问命令行参数 + +// fn main() { +// // 收集所有命令行参数 + +// let args: Vec = env::args().collect(); + + + +// // 检查参数数量 +// // 程序的第一个参数是它自己的名称,所以我们期望至少有两个参数 (程序名 + 文件路径) +// // 最多三个参数 (程序名 + 文件路径 + 转换类型) +// if args.len() < 2 || args.len() > 3 { +// println!("Usage: {} [output_type (json|csv)]", args[0]); +// println!(" output_type defaults to 'csv'"); +// return; // 参数数量不正确,打印使用说明并退出 +// } + +// // 获取文件路径 (第二个参数) +// let file_path = &args[1]; +// // 检查文件路径是否以 ".iris" 结尾 +// if !file_path.ends_with(".iris") { +// println!("Error: The file path must end with '.iris'."); +// println!("Usage: {} [output_type (json|csv)]", args[0]); +// return; // 文件路径不正确,打印错误信息并退出 +// } + + +// // 获取转换类型 (第三个参数,如果存在) +// // 如果没有提供第三个参数,则 output_type_str 为 None +// let output_type_str = if args.len() == 3 { +// Some(args[2].as_str()) // 将 String 转换为 &str +// } else { +// None // 没有提供转换类型 +// }; + +// // 根据转换类型执行相应的导出函数 +// match output_type_str { +// Some("json") => { +// println!("Exporting '{}' to JSON...", file_path); +// explortirisdatatojson(file_path); +// }, +// // 如果是 "csv" 或没有指定类型,则默认为 CSV +// Some("csv") | None => { +// println!("Exporting '{}' to CSV (default)...", file_path); +// explortirisdatatocsv(file_path); +// }, +// _ => { +// // 处理无效的转换类型 +// println!("Error: Invalid output type. Please use 'json' or 'csv'."); +// println!("Usage: {} [output_type (json|csv)]", args[0]); +// } +// } + +// println!("\nAll operations completed successfully!"); +// } + diff --git a/rust/iris_rust/src/read.rs b/rust/iris_rust/src/read.rs index 2d96edb..cf9c18b 100644 --- a/rust/iris_rust/src/read.rs +++ b/rust/iris_rust/src/read.rs @@ -102,7 +102,7 @@ pub fn read_iris_file(path: &str) -> Result { reader.read_exact(&mut tempvector)?; // Convert to String let json_string = String::from_utf8(tempvector).unwrap_or_default(); - let json_string = json_string.trim_end_matches('\0').to_string(); + //let json_string = json_string.trim_end_matches('\0').to_string(); //print!("JSON String: {}", json_string); let json:Value = match serde_json::from_str(&json_string){ Ok(json) => json, @@ -160,6 +160,7 @@ pub fn read_iris_file(path: &str) -> Result { } */ //如果info_type是infolist 则需要逐个解析 if json.get("info_type").and_then(Value::as_str) == Some("infolist") { + //println!("Found infolist type JSON: {}", json); let info_number = json.get("info_number").and_then(Value::as_u64).unwrap_or(0) as usize; for i in 0 ..info_number{ //将对应的info加入到data中 diff --git a/rust/iris_rust/src/structures.rs b/rust/iris_rust/src/structures.rs index 880069f..584e4f2 100644 --- a/rust/iris_rust/src/structures.rs +++ b/rust/iris_rust/src/structures.rs @@ -19,12 +19,12 @@ pub const Target_Spectral_Type_DarkDN:u8 = 0x06; pub const Target_Spectral_Type_FlatDN:u8 = 0x07; pub const Target_LAMP_VALUE_SCALED:u8 = 0x08; - +use serde::Serialize; use serde_json::json; -#[derive(Debug, Clone, PartialEq)] +#[derive(serde::Serialize,Debug, Clone, PartialEq)] pub struct TimeStruct { pub time_zone: i8, pub year: u16, @@ -51,7 +51,7 @@ impl TimeStruct { } } -#[derive(Debug, Clone, PartialEq)] +#[derive(serde::Serialize,Debug, Clone, PartialEq)] pub struct SpectralData { pub name: String, pub sensor_id: String, @@ -310,8 +310,7 @@ impl SpectralData { // } // } // } - -#[derive(Debug, Clone, PartialEq)] +#[derive(serde::Serialize, Debug, Clone, PartialEq)] pub struct OneIRISData { pub spectral_data_section: Vec, pub spectral_info_section: Vec, // Using serde_json::Value for flexibility @@ -346,7 +345,7 @@ impl OneIRISData { // } // } -#[derive(Debug, Clone, PartialEq)] +#[derive(serde::Serialize,Debug, Clone, PartialEq)] pub struct ImageInfo { pub data_length: u64, pub name: String, diff --git a/source/iris_format/iris_deffine.cpp b/source/iris_format/iris_deffine.cpp index 6e6d908..aa2eb36 100644 --- a/source/iris_format/iris_deffine.cpp +++ b/source/iris_format/iris_deffine.cpp @@ -100,7 +100,7 @@ void IRIS_DATA_example() { One_Spectral_Info_Struct &tempspectralinfo=mydata.SepctralInfoSection.SectionContent.SepctralInfoAddressList[0]; tempspectralinfo.Info = json::object(); // 初始化为一个空的JSON对象 tempspectralinfo.Info["info_type"] = "infolist"; // 设置info_type为infolist - tempspectralinfo.Info["info_number"] = 3; // 设置光谱信息数量 + tempspectralinfo.Info["info_number"] = 4; // 设置光谱信息数量 tempspectralinfo.Info["info_list"] = json::array(); // 初始化为一个空的JSON数组 // 添加光谱信息到info_list tempspectralinfo.Info["info_list"].push_back({ @@ -136,6 +136,13 @@ void IRIS_DATA_example() { {"a4", 1.2} }} }); + tempspectralinfo.Info["info_list"].push_back({ + {"info_type","environment"}, + {"date", "2000-01-00 00:00:00"}, + {"temperature", 35.0} + + +}); // //输出info std::cout << tempspectralinfo.Info.dump(4) << std::endl; // 打印JSON对象 // strcpy(tempspectralinfo.SensorId, "HH3_IRIS");