gistools/readers/tile/
mod.rs

1/// Raster based tools
2pub mod raster;
3
4use crate::{data_structures::HasLayer, parsers::RGBA};
5use alloc::string::String;
6pub use raster::*;
7use s2_tilejson::{Metadata, Scheme};
8use s2json::{Face, MValueCompatible, VectorFeature};
9use serde::{Deserialize, Serialize};
10use std::path::{Path, PathBuf};
11
12/// S2 Tile's metadata
13#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
14pub struct S2TileMetadata {
15    /// S2 Face
16    pub face: Face,
17    /// S2 Zoom
18    pub zoom: u8,
19    /// S2 X Tile Coordinate
20    pub x: u32,
21    /// S2 Y Tile Coordinate
22    pub y: u32,
23}
24
25/// Tile's metadata
26#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
27pub struct WMTileMetadata {
28    /// Zoom level
29    pub zoom: u8,
30    /// X tile coordinate
31    pub x: u32,
32    /// Y tile coordinate
33    pub y: u32,
34}
35
36/// Tile's metadata
37#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
38pub enum TileMetadata {
39    /// Web Mercator metadata
40    WM(WMTileMetadata),
41    /// S2 Mercator metadata
42    S2(S2TileMetadata),
43}
44impl Default for TileMetadata {
45    fn default() -> Self {
46        Self::WM(WMTileMetadata::default())
47    }
48}
49impl HasLayer for TileMetadata {
50    fn get_layer(&self) -> Option<String> {
51        None
52    }
53}
54
55/// Tile Fetching Mechanism
56pub trait TileFetcher<
57    // Properties
58    P: Clone + Default,
59    // M-Value
60    D: Clone + Default,
61    // Tile Reader
62    T: TileReader<P, D>,
63>
64{
65    /// Creates a new file reader from a file path
66    fn new<R: AsRef<Path>>(path: R, threshold: Option<u8>) -> Self;
67    /// Get the Tile Store's Metadata
68    fn get_metadata(&self) -> &Metadata;
69    /// Check if a WebMercator tile exists
70    fn has_tile_wm(&self, zoom: u8, x: u32, y: u32) -> bool;
71    /// Check if an S2 Geometry tile exists
72    fn has_tile_s2(&self, face: Face, zoom: u8, x: u32, y: u32) -> bool;
73    /// Get a WebMercator tile
74    fn get_tile_wm(&self, zoom: u8, x: u32, y: u32) -> T;
75    /// Get an S2 Geometry tile
76    fn get_tile_s2(&self, face: Face, zoom: u8, x: u32, y: u32) -> T;
77    /// Check if it is S2 tile
78    fn is_s2(&self) -> bool {
79        let Metadata { scheme, .. } = self.get_metadata();
80        *scheme == Scheme::Fzxy || *scheme == Scheme::Tfzxy
81    }
82}
83
84/// Tile Reading Mechanism
85pub trait TileReader<P: Clone + Default, D: Clone + Default> {
86    /// Create a new Web Mercator Raster Tile Reader
87    fn new(
88        path: PathBuf,
89        metadata: &Metadata,
90        face: Face,
91        zoom: u8,
92        x: u32,
93        y: u32,
94        is_s2: bool,
95    ) -> Self;
96    /// Build a vector feature from the tile
97    fn build_feature(&self) -> VectorFeature<TileMetadata, P, D>;
98}
99
100/// Elevation converter
101pub type ElevationConverter = fn(r: u8, g: u8, b: u8, a: Option<u8>) -> f64;
102
103/// Conver a Terrarium tile encoded elevation data into a float precision elevation
104pub fn convert_terrarium_elevation_data(r: u8, g: u8, b: u8) -> f64 {
105    (r as f64) * 256.0 + (g as f64) + (b as f64) / 256.0 - 32768.0
106}
107
108/// Conver a Mapbox tile encoded elevation data into a float precision elevation
109pub fn convert_mapbox_elevation_data(r: u8, g: u8, b: u8) -> f64 {
110    -10000. + ((r as f64) * 256. * 256. + (g as f64) * 256. + (b as f64)) * 0.1
111}
112
113/// Trait mechanic to parse a raster tile. Could be elevation or RGB(A)
114pub trait GetRasterTileValue {
115    /// Get the value of a raster tile pixel
116    fn get_raster_tile_value(r: u8, g: u8, b: u8, a: Option<u8>) -> Self;
117}
118
119/// Elevation point used by terrarium readers
120#[derive(Debug, Default, Clone, MValueCompatible, Serialize, Deserialize)]
121pub struct TerrariumElevation {
122    /// Elevation of a point
123    pub elev: f64,
124}
125impl GetRasterTileValue for TerrariumElevation {
126    fn get_raster_tile_value(r: u8, g: u8, b: u8, _a: Option<u8>) -> Self {
127        TerrariumElevation { elev: convert_terrarium_elevation_data(r, g, b) }
128    }
129}
130
131/// Elevation point used by terrarium readers
132#[derive(Debug, Default, Clone, MValueCompatible, Serialize, Deserialize)]
133pub struct MapboxElevation {
134    /// Elevation of a point
135    pub elev: f64,
136}
137impl GetRasterTileValue for MapboxElevation {
138    fn get_raster_tile_value(r: u8, g: u8, b: u8, _a: Option<u8>) -> Self {
139        MapboxElevation { elev: convert_mapbox_elevation_data(r, g, b) }
140    }
141}
142
143impl GetRasterTileValue for RGBA {
144    fn get_raster_tile_value(r: u8, g: u8, b: u8, a: Option<u8>) -> Self {
145        RGBA::from_u8s(r, g, b, a.unwrap_or(255))
146    }
147}