use crate::geokeys::{self, GeoKeyDirectory, GeoKeyValue};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ModelType {
Projected,
Geographic,
Geocentric,
Unknown(u16),
}
impl ModelType {
pub fn from_code(code: u16) -> Self {
match code {
1 => Self::Projected,
2 => Self::Geographic,
3 => Self::Geocentric,
other => Self::Unknown(other),
}
}
pub fn code(&self) -> u16 {
match self {
Self::Projected => 1,
Self::Geographic => 2,
Self::Geocentric => 3,
Self::Unknown(v) => *v,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RasterType {
PixelIsArea,
PixelIsPoint,
Unknown(u16),
}
impl RasterType {
pub fn from_code(code: u16) -> Self {
match code {
1 => Self::PixelIsArea,
2 => Self::PixelIsPoint,
other => Self::Unknown(other),
}
}
pub fn code(&self) -> u16 {
match self {
Self::PixelIsArea => 1,
Self::PixelIsPoint => 2,
Self::Unknown(v) => *v,
}
}
}
#[derive(Debug, Clone)]
pub struct CrsInfo {
pub model_type: u16,
pub raster_type: u16,
pub projected_epsg: Option<u16>,
pub geographic_epsg: Option<u16>,
pub projection_citation: Option<String>,
pub geographic_citation: Option<String>,
}
impl CrsInfo {
pub fn from_geokeys(geokeys: &GeoKeyDirectory) -> Self {
Self {
model_type: geokeys.get_short(geokeys::GT_MODEL_TYPE).unwrap_or(0),
raster_type: geokeys.get_short(geokeys::GT_RASTER_TYPE).unwrap_or(1),
projected_epsg: geokeys.get_short(geokeys::PROJECTED_CS_TYPE),
geographic_epsg: geokeys.get_short(geokeys::GEOGRAPHIC_TYPE),
projection_citation: geokeys.get_ascii(geokeys::PROJ_CITATION).map(String::from),
geographic_citation: geokeys.get_ascii(geokeys::GEOG_CITATION).map(String::from),
}
}
pub fn epsg(&self) -> Option<u32> {
self.projected_epsg
.or(self.geographic_epsg)
.map(|e| e as u32)
}
pub fn raster_type_enum(&self) -> RasterType {
RasterType::from_code(self.raster_type)
}
pub fn model_type_enum(&self) -> ModelType {
ModelType::from_code(self.model_type)
}
pub fn apply_to_geokeys(&self, geokeys: &mut GeoKeyDirectory) {
geokeys.set(geokeys::GT_MODEL_TYPE, GeoKeyValue::Short(self.model_type));
geokeys.set(
geokeys::GT_RASTER_TYPE,
GeoKeyValue::Short(self.raster_type),
);
if let Some(epsg) = self.projected_epsg {
geokeys.set(geokeys::PROJECTED_CS_TYPE, GeoKeyValue::Short(epsg));
}
if let Some(epsg) = self.geographic_epsg {
geokeys.set(geokeys::GEOGRAPHIC_TYPE, GeoKeyValue::Short(epsg));
}
if let Some(ref citation) = self.projection_citation {
geokeys.set(geokeys::PROJ_CITATION, GeoKeyValue::Ascii(citation.clone()));
}
if let Some(ref citation) = self.geographic_citation {
geokeys.set(geokeys::GEOG_CITATION, GeoKeyValue::Ascii(citation.clone()));
}
}
}