stac_extensions/
projection.rs

1//! The Projection extension.
2
3use super::Extension;
4use geojson::Geometry;
5use serde::{Deserialize, Serialize};
6use serde_json::{Map, Value};
7
8/// The projection extension fields.
9#[derive(Debug, Serialize, Deserialize, Default, PartialEq, Clone)]
10pub struct Projection {
11    /// EPSG code of the datasource
12    #[serde(skip_serializing_if = "Option::is_none")]
13    pub code: Option<String>,
14
15    /// WKT2 string representing the Coordinate Reference System (CRS) that the
16    /// proj:geometry and proj:bbox fields represent
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub wkt2: Option<String>,
19
20    /// PROJJSON object representing the Coordinate Reference System (CRS) that
21    /// the proj:geometry and proj:bbox fields represent
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub projjson: Option<Map<String, Value>>,
24
25    /// Defines the footprint of this Item.
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub geometry: Option<Geometry>,
28
29    /// Bounding box of the Item in the asset CRS in 2 or 3 dimensions.
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub bbox: Option<Vec<f64>>,
32
33    /// Coordinates representing the centroid of the Item (in lat/long)
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub centroid: Option<Centroid>,
36
37    /// Number of pixels in Y and X directions for the default grid
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub shape: Option<Vec<usize>>,
40
41    /// The affine transformation coefficients for the default grid
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub transform: Option<Vec<f64>>,
44}
45
46/// This object represents the centroid of the Item Geometry.
47#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
48pub struct Centroid {
49    /// The latitude of the centroid.
50    pub lat: f64,
51
52    /// The longitude of the centroid.
53    pub lon: f64,
54}
55
56impl Projection {
57    /// Returns true if this projection structure is empty.
58    ///
59    /// # Examples
60    ///
61    /// ```
62    /// use stac_extensions::Projection;
63    ///
64    /// let projection = Projection::default();
65    /// assert!(projection.is_empty());
66    /// ```
67    pub fn is_empty(&self) -> bool {
68        serde_json::to_value(self)
69            .map(|v| v == Value::Object(Default::default()))
70            .unwrap_or(true)
71    }
72}
73
74impl Extension for Projection {
75    const IDENTIFIER: &'static str =
76        "https://stac-extensions.github.io/projection/v2.0.0/schema.json";
77    const PREFIX: &'static str = "proj";
78}
79
80#[cfg(test)]
81mod tests {
82    use super::Projection;
83    use crate::{Extensions, Item};
84
85    #[test]
86    fn example() {
87        let item: Item =
88            stac::read("examples/extensions-collection/proj-example/proj-example.json").unwrap();
89        let projection = item.extension::<Projection>().unwrap();
90        assert_eq!(projection.code.unwrap(), "EPSG:32614");
91    }
92}