martin_core/tiles/
source.rs1use std::collections::HashMap;
2use std::fmt::Debug;
3
4use async_trait::async_trait;
5use martin_tile_utils::{TileCoord, TileData, TileInfo};
6use tilejson::TileJSON;
7
8use crate::tiles::MartinCoreResult;
9use crate::tiles::catalog::CatalogSourceEntry;
10
11pub type UrlQuery = HashMap<String, String>;
13
14#[async_trait]
18pub trait Source: Send + Debug {
19 fn get_id(&self) -> &str;
21
22 fn get_tilejson(&self) -> &TileJSON;
24
25 fn get_tile_info(&self) -> TileInfo;
27
28 fn clone_source(&self) -> BoxedSource;
30
31 fn get_version(&self) -> Option<String> {
35 None
36 }
37
38 fn support_url_query(&self) -> bool {
40 false
41 }
42
43 fn benefits_from_concurrent_scraping(&self) -> bool {
45 false
46 }
47
48 async fn get_tile(
54 &self,
55 xyz: TileCoord,
56 url_query: Option<&UrlQuery>,
57 ) -> MartinCoreResult<TileData>;
58
59 fn is_valid_zoom(&self, zoom: u8) -> bool {
61 let tj = self.get_tilejson();
62 tj.minzoom.is_none_or(|minzoom| zoom >= minzoom)
63 && tj.maxzoom.is_none_or(|maxzoom| zoom <= maxzoom)
64 }
65
66 fn get_catalog_entry(&self) -> CatalogSourceEntry {
68 let id = self.get_id();
69 let tilejson = self.get_tilejson();
70 let info = self.get_tile_info();
71 CatalogSourceEntry {
72 content_type: info.format.content_type().to_string(),
73 content_encoding: info.encoding.content_encoding().map(ToString::to_string),
74 name: tilejson.name.as_ref().filter(|v| *v != id).cloned(),
75 description: tilejson.description.clone(),
76 attribution: tilejson.attribution.clone(),
77 }
78 }
79}
80
81pub type BoxedSource = Box<dyn Source>;
83
84impl Clone for BoxedSource {
85 fn clone(&self) -> Self {
86 self.clone_source()
87 }
88}