Skip to main content

geotiff_reader/
crs.rs

1//! Coordinate Reference System extraction from GeoKeys.
2
3use crate::geokeys::{self, GeoKeyDirectory};
4
5/// GeoTIFF raster-space interpretation.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum RasterType {
8    PixelIsArea,
9    PixelIsPoint,
10    Unknown(u16),
11}
12
13impl RasterType {
14    pub fn from_code(code: u16) -> Self {
15        match code {
16            1 => Self::PixelIsArea,
17            2 => Self::PixelIsPoint,
18            other => Self::Unknown(other),
19        }
20    }
21}
22
23/// Extracted CRS information from GeoKeys.
24#[derive(Debug, Clone)]
25pub struct CrsInfo {
26    /// Model type: 1 = Projected, 2 = Geographic, 3 = Geocentric.
27    pub model_type: u16,
28    /// Raster type: 1 = PixelIsArea, 2 = PixelIsPoint.
29    pub raster_type: u16,
30    /// EPSG code for a projected CRS (from ProjectedCSTypeGeoKey).
31    pub projected_epsg: Option<u16>,
32    /// EPSG code for a geographic CRS (from GeographicTypeGeoKey).
33    pub geographic_epsg: Option<u16>,
34    /// Citation string for the projected CRS.
35    pub projection_citation: Option<String>,
36    /// Citation string for the geographic CRS.
37    pub geographic_citation: Option<String>,
38}
39
40impl CrsInfo {
41    /// Extract CRS information from a GeoKey directory.
42    pub fn from_geokeys(geokeys: &GeoKeyDirectory) -> Self {
43        Self {
44            model_type: geokeys.get_short(geokeys::GT_MODEL_TYPE).unwrap_or(0),
45            raster_type: geokeys.get_short(geokeys::GT_RASTER_TYPE).unwrap_or(1),
46            projected_epsg: geokeys.get_short(geokeys::PROJECTED_CS_TYPE),
47            geographic_epsg: geokeys.get_short(geokeys::GEOGRAPHIC_TYPE),
48            projection_citation: geokeys.get_ascii(geokeys::PROJ_CITATION).map(String::from),
49            geographic_citation: geokeys.get_ascii(geokeys::GEOG_CITATION).map(String::from),
50        }
51    }
52
53    /// Returns the most specific EPSG code available.
54    pub fn epsg(&self) -> Option<u32> {
55        self.projected_epsg
56            .or(self.geographic_epsg)
57            .map(|e| e as u32)
58    }
59
60    /// Returns the GeoTIFF raster-space interpretation.
61    pub fn raster_type_enum(&self) -> RasterType {
62        RasterType::from_code(self.raster_type)
63    }
64}