Skip to main content

async_geotiff/style/
params.rs

1//! Immutable Raster Style input and render-plan access.
2use super::{raster::RasterPlan, TileFormat};
3use crate::error::AgResult;
4use crate::render::pipeline::CompiledTileStyle;
5use crate::warp::resampler::Resampling;
6use std::sync::{Arc, OnceLock};
7
8/// Supported square tile widths/heights in pixels.
9pub const ALLOWED_TILE_SIZES: [u32; 5] = [64, 128, 256, 512, 1024];
10
11/// Validated Raster Style 3.0. Change the JSON/Q3 document and parse again to edit.
12///
13/// ```compile_fail
14/// let mut style = async_geotiff::style::TileStyle::default();
15/// style.rescale = vec![(0.0, 100.0)];
16/// ```
17///
18/// ```compile_fail
19/// async_geotiff::style::TileStyle::from_query("stretch=stddev").unwrap();
20/// ```
21#[derive(Debug, Clone)]
22pub struct TileStyle {
23    pub(crate) raster: Arc<RasterPlan>,
24    pub(crate) nodata: Option<f64>,
25    pub(crate) resampling: Resampling,
26    pub(crate) reproject: Resampling,
27    pub(crate) tilesize: u32,
28    pub(crate) format: TileFormat,
29}
30
31impl Default for TileStyle {
32    /// Gray, source band 1, stretch none (0–255), PNG, 256 pixels.
33    fn default() -> Self {
34        Self::from_json(r#"{"version":"3.0","renderer":{"type":"gray","bidx":[1]}}"#)
35            .expect("built-in Raster Style is supported")
36    }
37}
38
39impl TileStyle {
40    /// Requested output encoding, PNG by default.
41    pub fn format(&self) -> TileFormat {
42        self.format
43    }
44    /// Square tile width/height in pixels, 256 by default.
45    pub fn tilesize(&self) -> u32 {
46        self.tilesize
47    }
48    /// Kernel for the read/resize stage; reprojection can use a separate kernel.
49    pub fn resampling(&self) -> Resampling {
50        self.resampling
51    }
52}
53
54/// Share a validated style's immutable plan with a standalone renderer.
55///
56/// Compilation performs no image reads or dataset statistics. The tile pipeline
57/// resolves dataset-dependent stretch settings when rendering through a Tiler.
58pub fn compile(style: &TileStyle) -> AgResult<CompiledTileStyle> {
59    Ok(CompiledTileStyle {
60        raster: style.raster.clone(),
61        nodata: style.nodata,
62        resampling: style.resampling,
63        format: style.format,
64    })
65}
66
67/// Cache immutable plans by their normalized Raster Style document.
68pub async fn compile_cached(style: &TileStyle) -> AgResult<Arc<CompiledTileStyle>> {
69    static CACHE: OnceLock<moka::future::Cache<String, Arc<CompiledTileStyle>>> = OnceLock::new();
70    let cache = CACHE.get_or_init(|| moka::future::Cache::new(256));
71    let key = style.raster.key.clone();
72    if let Some(hit) = cache.get(&key).await {
73        return Ok(hit);
74    }
75    let compiled = Arc::new(compile(style)?);
76    cache.insert(key, compiled.clone()).await;
77    Ok(compiled)
78}