1use crate::tile_matrix_set::TileMatrixSetOps;
2use crate::tms::Tms;
3use ogcapi_types::tiles::TileMatrixSet;
4use once_cell::sync::OnceCell;
5use std::collections::HashMap;
6
7#[derive(Clone)]
9pub struct TileMatrixSets {
10 coll: HashMap<String, TileMatrixSet>,
13}
14
15#[derive(thiserror::Error, Debug)]
16pub enum RegistryError {
17 #[error("Tile Matrix set not found: `{0}`")]
18 TmsNotFound(String),
19 #[error("`{0}` is already a registered TMS")]
20 TmsAlreadyRegistered(String),
21 #[error(transparent)]
22 TmsError(#[from] crate::tms::TmsError),
23}
24
25impl Default for TileMatrixSets {
26 fn default() -> Self {
27 Self::new()
28 }
29}
30
31impl TileMatrixSets {
32 pub fn new() -> Self {
33 Self {
34 coll: HashMap::new(),
35 }
36 }
37
38 pub fn get(&self, id: &str) -> Result<&TileMatrixSet, RegistryError> {
39 self.coll
40 .get(id)
41 .ok_or(RegistryError::TmsNotFound(id.to_string()))
42 }
43
44 pub fn lookup(&self, id: &str) -> Result<Tms, RegistryError> {
45 self.get(id)?.try_into().map_err(Into::into)
46 }
47
48 pub fn list(&self) -> impl Iterator<Item = &String> {
49 self.coll.keys()
50 }
51
52 pub fn register(
53 &mut self,
54 custom_tms: Vec<TileMatrixSet>,
55 overwrite: bool,
56 ) -> Result<(), RegistryError> {
57 for tms in custom_tms {
58 if self.coll.contains_key(&tms.id) {
59 if overwrite {
60 self.coll.insert(tms.id.clone(), tms);
61 } else {
62 return Err(RegistryError::TmsAlreadyRegistered(tms.id));
63 }
64 } else {
65 self.coll.insert(tms.id.clone(), tms);
66 }
67 }
68 Ok(())
69 }
70}
71
72pub fn tms() -> &'static TileMatrixSets {
74 static TMS: OnceCell<TileMatrixSets> = OnceCell::new();
75 TMS.get_or_init(|| {
76 let mut sets = TileMatrixSets::new();
77 let tms = vec![
78 #[cfg(feature = "projtransform")]
79 include_str!("../data/CanadianNAD83_LCC.json"),
80 #[cfg(feature = "projtransform")]
82 include_str!("../data/EuropeanETRS89_LAEAQuad.json"),
83 #[cfg(feature = "projtransform")]
85 include_str!("../data/UPSAntarcticWGS84Quad.json"),
86 #[cfg(feature = "projtransform")]
87 include_str!("../data/UPSArcticWGS84Quad.json"),
88 #[cfg(feature = "projtransform")]
89 include_str!("../data/UTM31WGS84Quad.json"),
90 include_str!("../data/WebMercatorQuad.json"),
91 include_str!("../data/WGS1984Quad.json"),
92 include_str!("../data/WorldMercatorWGS84Quad.json"),
94 ]
95 .into_iter()
96 .map(|data| TileMatrixSet::from_json(data).unwrap())
97 .collect::<Vec<_>>();
98 sets.register(tms, false).unwrap();
99 sets
103 })
104}