Skip to main content

egml_io/geometry/
direct_position.rs

1use crate::Error;
2use crate::Error::{MissingElements, UnsupportedDimension};
3use crate::util::{deserialize_space_separated_f64, serialize_space_separated_f64};
4use egml_core::model::geometry::DirectPosition;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
8pub struct GmlDirectPosition {
9    #[serde(rename = "@srsDimension")]
10    pub(crate) srs_dimension: Option<u32>,
11
12    #[serde(
13        rename = "$value",
14        deserialize_with = "deserialize_space_separated_f64",
15        serialize_with = "serialize_space_separated_f64"
16    )]
17    value: Vec<f64>,
18}
19
20impl TryFrom<GmlDirectPosition> for DirectPosition {
21    type Error = Error;
22
23    fn try_from(item: GmlDirectPosition) -> Result<Self, Self::Error> {
24        if item.srs_dimension.unwrap_or(3) != 3 {
25            return Err(UnsupportedDimension());
26        }
27
28        if item.value.len() != 3 {
29            return Err(MissingElements("not a multiple of 3".to_string()));
30        }
31
32        let position = DirectPosition::new(item.value[0], item.value[1], item.value[2])?;
33        Ok(position)
34    }
35}
36
37impl From<&DirectPosition> for GmlDirectPosition {
38    fn from(pos: &DirectPosition) -> Self {
39        Self {
40            srs_dimension: Some(3),
41            value: vec![pos.x(), pos.y(), pos.z()],
42        }
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use crate::GmlDirectPosition;
49    use egml_core::model::geometry::DirectPosition;
50    use quick_xml::{DeError, de};
51
52    #[test]
53    fn deserialize_direct_position() {
54        let xml_document = "<gml:pos srsDimension=\"3\" gml:id=\"UUID_6b33ecfa-6e08-4e8e-a4b5-e1d06540faf0\">678000.9484065345 5403659.060043676 417.3802376791456</gml:pos>";
55
56        let parsed_result: Result<GmlDirectPosition, DeError> =
57            de::from_reader(xml_document.as_ref());
58        let parsed_gml = parsed_result.expect("parsing should work");
59        let direct_position: DirectPosition = parsed_gml.try_into().unwrap();
60
61        assert_eq!(direct_position.x(), 678000.9484065345);
62        assert_eq!(direct_position.y(), 5403659.060043676);
63        assert_eq!(direct_position.z(), 417.3802376791456);
64    }
65}