everymap_providers_mapbox/domain/imaging/
mod.rs1use crate::client::MapBoxClient;
2use async_trait::async_trait;
3use everymap_core::domains::imaging::{ImageOptions, ImageResponse, MapImageProvider};
4use everymap_core::error::EveryMapResult;
5use everymap_core::types::Coordinate;
6use std::sync::Arc;
7
8const MAP_BASE_URL: &str = "https://api.mapbox.com";
9
10pub struct MapBoxMapImageProvider {
12 pub(crate) client: Arc<MapBoxClient>,
13 pub(crate) base_url: String,
14}
15
16impl MapBoxMapImageProvider {
17 pub fn new(client: Arc<MapBoxClient>) -> Self {
18 Self {
19 client,
20 base_url: MAP_BASE_URL.to_string(),
21 }
22 }
23
24 pub fn with_base_url(client: Arc<MapBoxClient>, base_url: String) -> Self {
25 Self { client, base_url }
26 }
27}
28
29#[async_trait]
30impl MapImageProvider for MapBoxMapImageProvider {
31 async fn get_image(
32 &self,
33 center: &Coordinate,
34 zoom: u32,
35 size: (u32, u32),
36 options: &ImageOptions,
37 ) -> EveryMapResult<ImageResponse> {
38 let style = options
39 .provider_extra
40 .as_ref()
41 .and_then(|e| e.get("style"))
42 .and_then(|v| v.as_str())
43 .unwrap_or("mapbox/streets-v12");
44
45 let url = format!(
47 "{}/styles/v1/{}/static/{},{},{}/{}x{}@2x",
48 self.base_url, style, center.lng, center.lat, zoom, size.0, size.1
49 );
50
51 let mut params: Vec<(&str, String)> = Vec::new();
52 if let Some(lang) = &options.language {
53 params.push(("language", lang.clone()));
54 }
55 if options.format.is_some() {
56 log::warn!(
57 "MapBox Static Images API does not support a format parameter; \
58 format will be ignored (MapBox always returns PNG)"
59 );
60 }
61
62 let builder = self
63 .client
64 .build_request(reqwest::Method::GET, &url)
65 .query(¶ms);
66
67 let response = self.client.request(builder).await?;
68
69 let content_type = response
70 .headers()
71 .get("content-type")
72 .and_then(|v| v.to_str().ok())
73 .map(|s| s.split(';').next().unwrap_or(s).trim().to_string());
74
75 let data = response.bytes().await?.to_vec();
76
77 Ok(ImageResponse { data, content_type })
78 }
79}