411 lines
12 KiB
Rust
411 lines
12 KiB
Rust
|
|
pub const DATA_TYPE_UINT8: u8 = 0x10;
|
|
pub const DATA_TYPE_INT16: u8 = 0x11;
|
|
pub const DATA_TYPE_UINT16: u8 = 0x12;
|
|
pub const DATA_TYPE_INT32: u8 = 0x13;
|
|
pub const DATA_TYPE_UINT32: u8 = 0x14;
|
|
pub const DATA_TYPE_FLOAT32: u8 = 0x20;
|
|
pub const DATA_TYPE_FLOAT64: u8 = 0x21;
|
|
|
|
/* 0 dn 1 rad 2 ref 3 irad 4 califile 5 flat_ref 6 dark_dn 7 flat_dn */
|
|
|
|
pub const Target_Spectral_Type_DN:u8 = 0x00;
|
|
pub const Target_Spectral_Type_Rad:u8 = 0x01;
|
|
pub const Target_Spectral_Type_Ref:u8 = 0x02;
|
|
pub const Target_Spectral_Type_IRad:u8 = 0x03;
|
|
pub const Target_Spectral_Type_CaliFile_Gain:u8 = 0x04;
|
|
pub const Target_Spectral_Type_FlatRef:u8 = 0x05;
|
|
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(serde::Serialize,Debug, Clone, PartialEq)]
|
|
pub struct TimeStruct {
|
|
pub time_zone: i8,
|
|
pub year: u16,
|
|
pub month: u8,
|
|
pub day: u8,
|
|
pub hour: u8,
|
|
pub minute: u8,
|
|
pub second: u8,
|
|
pub millisecond: u16,
|
|
}
|
|
|
|
impl TimeStruct {
|
|
pub fn new() -> Self {
|
|
TimeStruct {
|
|
time_zone: 0,
|
|
year: 0,
|
|
month: 1,
|
|
day: 1,
|
|
hour: 0,
|
|
minute: 0,
|
|
second: 0,
|
|
millisecond: 0,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(serde::Serialize,Debug, Clone, PartialEq)]
|
|
pub struct SpectralData {
|
|
pub name: String,
|
|
pub sensor_id: String,
|
|
pub fiber_id: u8,
|
|
pub collection_time: TimeStruct,
|
|
pub exposure: f64,
|
|
pub gain: f32,
|
|
pub data_type: u8,
|
|
pub pixel_size: u8,
|
|
pub ground_type: u8,
|
|
pub bands: u16,
|
|
pub valid_flag: u8,
|
|
pub spectral_data: Vec<u8>,
|
|
}
|
|
|
|
impl SpectralData {
|
|
pub fn new() -> Self {
|
|
SpectralData {
|
|
name: String::new(),
|
|
sensor_id: String::new(),
|
|
fiber_id:0,
|
|
collection_time: TimeStruct::new(),
|
|
exposure: 0.0,
|
|
gain: 0.0,
|
|
data_type: 0,
|
|
pixel_size: 0,
|
|
ground_type: 0,
|
|
bands: 0,
|
|
valid_flag: 0,
|
|
spectral_data: Vec::new(),
|
|
}
|
|
}
|
|
|
|
pub fn Get_Spectral_Data(&self)-> Vec<f64> {
|
|
let mut retrun_data: Vec<f64> = Vec::new();
|
|
let datatype = self.data_type;
|
|
let bands = self.bands as usize;
|
|
match datatype {
|
|
DATA_TYPE_UINT8 => {
|
|
// uint8
|
|
for i in 0..bands {
|
|
retrun_data.push(self.spectral_data[i] as f64);
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
DATA_TYPE_INT16 => {
|
|
// int16
|
|
self.spectral_data.chunks(2).for_each(|chunk| {
|
|
if chunk.len() == 2 {
|
|
let value = i16::from_le_bytes([chunk[0], chunk[1]]);
|
|
retrun_data.push(value as f64);
|
|
}
|
|
});
|
|
|
|
}
|
|
DATA_TYPE_UINT16 => {
|
|
// uint16
|
|
self.spectral_data.chunks(2).for_each(|chunk| {
|
|
if chunk.len() == 2 {
|
|
let value = u16::from_le_bytes([chunk[0], chunk[1]]);
|
|
retrun_data.push(value as f64);
|
|
}
|
|
});
|
|
|
|
}
|
|
DATA_TYPE_INT32 => {
|
|
// int32
|
|
|
|
|
|
self.spectral_data.chunks(4).for_each(|chunk| {
|
|
if chunk.len() == 4 {
|
|
let value = i32::from_le_bytes([
|
|
chunk[0],
|
|
chunk[1],
|
|
chunk[2],
|
|
chunk[3],
|
|
]);
|
|
retrun_data.push(value as f64);
|
|
}
|
|
});
|
|
|
|
}
|
|
DATA_TYPE_UINT32 => {
|
|
// uint32
|
|
for i in (0..self.spectral_data.len()).step_by(4) {
|
|
let value = u32::from_le_bytes([
|
|
self.spectral_data[i],
|
|
self.spectral_data[i + 1],
|
|
self.spectral_data[i + 2],
|
|
self.spectral_data[i + 3],
|
|
]);
|
|
retrun_data.push(value as f64);
|
|
}
|
|
}
|
|
DATA_TYPE_FLOAT32 => {
|
|
// float32
|
|
for i in (0..self.spectral_data.len()).step_by(4) {
|
|
let value = f32::from_le_bytes([
|
|
self.spectral_data[i],
|
|
self.spectral_data[i + 1],
|
|
self.spectral_data[i + 2],
|
|
self.spectral_data[i + 3],
|
|
]);
|
|
retrun_data.push(value as f64);
|
|
}
|
|
}
|
|
DATA_TYPE_FLOAT64 => {
|
|
// float64
|
|
for i in (0..self.spectral_data.len()).step_by(8) {
|
|
let value = f64::from_le_bytes([
|
|
self.spectral_data[i],
|
|
self.spectral_data[i + 1],
|
|
self.spectral_data[i + 2],
|
|
self.spectral_data[i + 3],
|
|
self.spectral_data[i + 4],
|
|
self.spectral_data[i + 5],
|
|
self.spectral_data[i + 6],
|
|
self.spectral_data[i + 7],
|
|
]);
|
|
retrun_data.push(value);
|
|
}
|
|
}
|
|
_ => {
|
|
// Unsupported data type
|
|
panic!("Unsupported data type: {}", datatype);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
retrun_data
|
|
|
|
|
|
}
|
|
pub fn Set_Spectral_Data(&mut self, data: Vec<f64>,datatype: u8) {
|
|
self.data_type = datatype;
|
|
self.bands = data.len() as u16;
|
|
self.spectral_data.clear();
|
|
|
|
// let datatype = self.data_type;
|
|
let bands = self.bands as usize;
|
|
match datatype {
|
|
DATA_TYPE_UINT8 => {
|
|
// uint8
|
|
self.pixel_size = 1;
|
|
self.spectral_data.clear();
|
|
for i in 0..bands {
|
|
if i < data.len() {
|
|
self.spectral_data.push(data[i] as u8);
|
|
} else {
|
|
self.spectral_data.push(0);
|
|
}
|
|
}
|
|
}
|
|
DATA_TYPE_INT16 => {
|
|
// int16
|
|
self.pixel_size = 2;
|
|
self.spectral_data.clear();
|
|
for i in 0..bands {
|
|
if i < data.len() {
|
|
let value = data[i] as i16;
|
|
self.spectral_data.extend_from_slice(&value.to_le_bytes());
|
|
} else {
|
|
self.spectral_data.extend_from_slice(&[0, 0]);
|
|
}
|
|
}
|
|
}
|
|
DATA_TYPE_UINT16 => {
|
|
// uint16
|
|
self.pixel_size = 2;
|
|
self.spectral_data.clear();
|
|
for i in 0..bands {
|
|
if i < data.len() {
|
|
let value = data[i] as u16;
|
|
self.spectral_data.extend_from_slice(&value.to_le_bytes());
|
|
} else {
|
|
self.spectral_data.extend_from_slice(&[0, 0]);
|
|
}
|
|
}
|
|
}
|
|
DATA_TYPE_INT32 => {
|
|
// int32
|
|
self.pixel_size = 4;
|
|
self.spectral_data.clear();
|
|
for i in 0..bands {
|
|
if i < data.len() {
|
|
let value = data[i] as i32;
|
|
self.spectral_data.extend_from_slice(&value.to_le_bytes());
|
|
} else {
|
|
self.spectral_data.extend_from_slice(&[0, 0, 0, 0]);
|
|
}
|
|
}
|
|
}
|
|
DATA_TYPE_UINT32 => {
|
|
// uint32
|
|
self.pixel_size = 4;
|
|
self.spectral_data.clear();
|
|
for i in 0..bands {
|
|
if i < data.len() {
|
|
let value = data[i] as u32;
|
|
self.spectral_data.extend_from_slice(&value.to_le_bytes());
|
|
} else {
|
|
self.spectral_data.extend_from_slice(&[0, 0, 0, 0]);
|
|
}
|
|
}
|
|
}
|
|
DATA_TYPE_FLOAT32 => {
|
|
// float32
|
|
self.pixel_size = 4;
|
|
self.spectral_data.clear();
|
|
for i in 0..bands {
|
|
if i < data.len() {
|
|
let value = data[i] as f32;
|
|
self.spectral_data.extend_from_slice(&value.to_le_bytes());
|
|
} else {
|
|
self.spectral_data.extend_from_slice(&[0, 0, 0, 0]);
|
|
}
|
|
}
|
|
}
|
|
DATA_TYPE_FLOAT64 => {
|
|
// float64
|
|
self.pixel_size = 8;
|
|
self.spectral_data.clear();
|
|
for i in 0..bands {
|
|
if i < data.len() {
|
|
let value = data[i];
|
|
self.spectral_data.extend_from_slice(&value.to_le_bytes());
|
|
} else {
|
|
self.spectral_data.extend_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]);
|
|
}
|
|
}
|
|
}
|
|
_ => {
|
|
// Unsupported data type
|
|
panic!("Unsupported data type: {}", datatype);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// #[derive(Debug, Clone, PartialEq)]
|
|
// pub struct OtherInfo {
|
|
// pub info_type: u8,
|
|
// pub data: Vec<u8>, // Assuming the data is variable length
|
|
// }
|
|
|
|
// impl OtherInfo {
|
|
// pub fn new() -> Self {
|
|
// OtherInfo {
|
|
// info_type: 0,
|
|
// data: Vec::new(),
|
|
// }
|
|
// }
|
|
// }
|
|
#[derive(serde::Serialize, Debug, Clone, PartialEq)]
|
|
pub struct OneIRISData {
|
|
pub spectral_data_section: Vec<SpectralData>,
|
|
pub spectral_info_section: Vec<serde_json::Value>, // Using serde_json::Value for flexibility
|
|
pub other_info_section: Vec<serde_json::Value>,
|
|
pub image_info_section: Vec<ImageInfo>,
|
|
}
|
|
|
|
impl OneIRISData {
|
|
pub fn new() -> Self {
|
|
OneIRISData {
|
|
spectral_data_section: Vec::new(),
|
|
spectral_info_section: Vec::new(),
|
|
other_info_section: Vec::new(),
|
|
image_info_section: Vec::new(),
|
|
}
|
|
}
|
|
}
|
|
|
|
// #[derive(Debug, Clone, PartialEq)]
|
|
// pub struct SpectralInfo {
|
|
// pub sensor_id: String,
|
|
// pub wave_coeff: [f64; 4],
|
|
|
|
// }
|
|
|
|
// impl SpectralInfo {
|
|
// pub fn new() -> Self {
|
|
// SpectralInfo {
|
|
// sensor_id: String::new(),
|
|
// wave_coeff: [0.0; 4],
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
#[derive(serde::Serialize,Debug, Clone, PartialEq)]
|
|
pub struct ImageInfo {
|
|
pub data_length: u64,
|
|
pub name: String,
|
|
pub collection_time: TimeStruct,
|
|
pub info_type: u8,
|
|
pub image_data: Vec<u8>, // Assuming the data is variable length
|
|
}
|
|
|
|
impl ImageInfo {
|
|
pub fn new() -> Self {
|
|
ImageInfo {
|
|
data_length: 0,
|
|
name: String::new(),
|
|
collection_time: TimeStruct::new(),
|
|
info_type: 0,
|
|
image_data: Vec::new(),
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_time_struct() {
|
|
let time = TimeStruct::new();
|
|
assert_eq!(time.time_zone, 0);
|
|
assert_eq!(time.year, 0);
|
|
assert_eq!(time.month, 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_spectral_data() {
|
|
let data = SpectralData::new();
|
|
assert_eq!(data.name, "");
|
|
assert_eq!(data.bands, 0);
|
|
assert!(data.spectral_data.is_empty());
|
|
}
|
|
|
|
// #[test]
|
|
// fn test_spectral_info() {
|
|
// let info = SpectralInfo::new();
|
|
// assert_eq!(info.sensor_id, "");
|
|
// assert_eq!(info.wave_coeff, [0.0; 4]);
|
|
// }
|
|
|
|
// #[test]
|
|
// fn test_other_info() {
|
|
// let info = OtherInfo::new();
|
|
// assert_eq!(info.info_type, 0);
|
|
// assert!(info.data.is_empty());
|
|
// }
|
|
|
|
#[test]
|
|
fn test_image_info() {
|
|
let info = ImageInfo::new();
|
|
assert_eq!(info.data_length, 0);
|
|
assert_eq!(info.name, "");
|
|
assert!(info.image_data.is_empty());
|
|
}
|
|
} |