kit_ais_dataset/
lib.rs

1use anyhow::Result;
2use chrono::NaiveDateTime;
3use noisy_float::prelude::*;
4use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
5use std::path::PathBuf;
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
8#[serde(rename = "dataset")]
9pub struct Dataset {
10    #[serde(rename = "$value")]
11    pub frames: Vec<Frame>,
12}
13
14#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
15#[serde(rename = "frame")]
16pub struct Frame {
17    pub number: usize,
18    pub file: PathBuf,
19    #[serde(with = "serde_utc")]
20    pub utc: NaiveDateTime,
21    pub color: Option<Color>,
22    pub depth: Option<Depth>,
23    pub gsd: R64,
24    pub x: R64,
25    pub y: R64,
26    pub lat: R64,
27    pub lon: R64,
28    #[serde(with = "serde_zero_one_bool")]
29    pub sunny: bool,
30    #[serde(rename = "$value")]
31    pub object_list: ObjectList,
32}
33
34#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
35#[serde(rename = "objectlist")]
36pub struct ObjectList {
37    #[serde(rename = "$value")]
38    pub objects: Vec<Object>,
39}
40
41#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
42#[serde(rename = "object")]
43pub struct Object {
44    pub id: usize,
45    pub r#box: Box,
46    pub representation: Representation,
47}
48
49#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
50#[serde(rename = "box")]
51pub struct Box {
52    pub xc: R64,
53    pub yc: R64,
54    pub w: R64,
55    pub h: R64,
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
59#[serde(rename = "representation")]
60pub struct Representation {
61    pub r#type: RepresentationType,
62    pub xc: R64,
63    pub yc: R64,
64    pub w: R64,
65    pub h: R64,
66    pub o: R64,
67}
68
69#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
70pub enum RepresentationType {
71    RotatedRectangle,
72}
73
74#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
75pub enum Color {
76    #[serde(rename = "rgb")]
77    Rgb,
78}
79
80#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
81pub enum Depth {
82    #[serde(rename = "byte")]
83    Byte,
84}
85
86mod serde_utc {
87    use super::*;
88
89    const FORMAT: &str = "%Y-%b-%d %H:%M:%S%.f";
90
91    pub fn serialize<S>(value: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
92    where
93        S: Serializer,
94    {
95        format!("{}", value.format(FORMAT)).serialize(serializer)
96    }
97
98    pub fn deserialize<'de, D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
99    where
100        D: Deserializer<'de>,
101    {
102        let text = String::deserialize(deserializer)?;
103        NaiveDateTime::parse_from_str(&text, FORMAT).map_err(|err| {
104            D::Error::custom(format!(
105                "unable to deserialize string '{}' to date: {:?}",
106                text, err
107            ))
108        })
109    }
110}
111
112mod serde_zero_one_bool {
113    use super::*;
114
115    pub fn serialize<S>(value: &bool, serializer: S) -> Result<S::Ok, S::Error>
116    where
117        S: Serializer,
118    {
119        if *value { "1" } else { "0" }.serialize(serializer)
120    }
121
122    pub fn deserialize<'de, D>(deserializer: D) -> Result<bool, D::Error>
123    where
124        D: Deserializer<'de>,
125    {
126        let text = String::deserialize(deserializer)?;
127        let value = match &*text {
128            "0" => false,
129            "1" => true,
130            text => {
131                return Err(D::Error::custom(format!(
132                    r#"expect "0" or "1", but get "{}""#,
133                    text
134                )))
135            }
136        };
137        Ok(value)
138    }
139}
140
141// #[cfg(test)]
142// mod tests {
143//     use super::*;
144
145//     #[test]
146//     fn dataset_test() -> Result<()> {
147//         let dir = "/mnt/bbf98471-db16-4e2e-99df-ccd245253072/kit-ais-dataset/Training Data Set/StuttgartCrossroad01";
148
149//         for path in glob::glob(&format!("{}/*.xml", dir))? {
150//             let path = path?;
151//             let text = std::fs::read_to_string(path)?;
152//             let _: Dataset = serde_xml_rs::from_str(&text)?;
153//         }
154
155//         Ok(())
156//     }
157// }