1use crate::geokeys::{self, GeoKeyDirectory, GeoKeyValue};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum ModelType {
8 Projected,
9 Geographic,
10 Geocentric,
11 Unknown(u16),
12}
13
14impl ModelType {
15 pub fn from_code(code: u16) -> Self {
16 match code {
17 1 => Self::Projected,
18 2 => Self::Geographic,
19 3 => Self::Geocentric,
20 other => Self::Unknown(other),
21 }
22 }
23
24 pub fn code(&self) -> u16 {
25 match self {
26 Self::Projected => 1,
27 Self::Geographic => 2,
28 Self::Geocentric => 3,
29 Self::Unknown(v) => *v,
30 }
31 }
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
36pub enum RasterType {
37 PixelIsArea,
38 PixelIsPoint,
39 Unknown(u16),
40}
41
42impl RasterType {
43 pub fn from_code(code: u16) -> Self {
44 match code {
45 1 => Self::PixelIsArea,
46 2 => Self::PixelIsPoint,
47 other => Self::Unknown(other),
48 }
49 }
50
51 pub fn code(&self) -> u16 {
52 match self {
53 Self::PixelIsArea => 1,
54 Self::PixelIsPoint => 2,
55 Self::Unknown(v) => *v,
56 }
57 }
58}
59
60#[derive(Debug, Clone)]
62pub struct CrsInfo {
63 pub model_type: u16,
65 pub raster_type: u16,
67 pub projected_epsg: Option<u16>,
69 pub geographic_epsg: Option<u16>,
71 pub projection_citation: Option<String>,
73 pub geographic_citation: Option<String>,
75}
76
77impl CrsInfo {
78 pub fn from_geokeys(geokeys: &GeoKeyDirectory) -> Self {
80 Self {
81 model_type: geokeys.get_short(geokeys::GT_MODEL_TYPE).unwrap_or(0),
82 raster_type: geokeys.get_short(geokeys::GT_RASTER_TYPE).unwrap_or(1),
83 projected_epsg: geokeys.get_short(geokeys::PROJECTED_CS_TYPE),
84 geographic_epsg: geokeys.get_short(geokeys::GEOGRAPHIC_TYPE),
85 projection_citation: geokeys.get_ascii(geokeys::PROJ_CITATION).map(String::from),
86 geographic_citation: geokeys.get_ascii(geokeys::GEOG_CITATION).map(String::from),
87 }
88 }
89
90 pub fn epsg(&self) -> Option<u32> {
92 self.projected_epsg
93 .or(self.geographic_epsg)
94 .map(|e| e as u32)
95 }
96
97 pub fn raster_type_enum(&self) -> RasterType {
99 RasterType::from_code(self.raster_type)
100 }
101
102 pub fn model_type_enum(&self) -> ModelType {
104 ModelType::from_code(self.model_type)
105 }
106
107 pub fn apply_to_geokeys(&self, geokeys: &mut GeoKeyDirectory) {
109 geokeys.set(geokeys::GT_MODEL_TYPE, GeoKeyValue::Short(self.model_type));
110 geokeys.set(
111 geokeys::GT_RASTER_TYPE,
112 GeoKeyValue::Short(self.raster_type),
113 );
114 if let Some(epsg) = self.projected_epsg {
115 geokeys.set(geokeys::PROJECTED_CS_TYPE, GeoKeyValue::Short(epsg));
116 }
117 if let Some(epsg) = self.geographic_epsg {
118 geokeys.set(geokeys::GEOGRAPHIC_TYPE, GeoKeyValue::Short(epsg));
119 }
120 if let Some(ref citation) = self.projection_citation {
121 geokeys.set(geokeys::PROJ_CITATION, GeoKeyValue::Ascii(citation.clone()));
122 }
123 if let Some(ref citation) = self.geographic_citation {
124 geokeys.set(geokeys::GEOG_CITATION, GeoKeyValue::Ascii(citation.clone()));
125 }
126 }
127}