utiles/mbt/
tiles_filter.rs

1use utiles_core::{tile_ranges, BBox, ZoomOrZooms, ZoomSet};
2
3use crate::errors::UtilesResult;
4
5#[derive(Debug, Clone)]
6pub struct TilesFilter {
7    pub bboxes: Option<Vec<BBox>>,
8    pub zooms: Option<Vec<u8>>,
9}
10
11impl TilesFilter {
12    #[must_use]
13    pub fn new(bboxes: Option<Vec<BBox>>, zooms: Option<Vec<u8>>) -> Self {
14        Self { bboxes, zooms }
15    }
16
17    pub fn mbtiles_sql_where(&self, prefix: Option<&str>) -> UtilesResult<String> {
18        self.where_clause(prefix)
19    }
20
21    pub fn where_clause(&self, prefix: Option<&str>) -> UtilesResult<String> {
22        let pred = match (&self.bboxes, &self.zooms) {
23            (Some(bbox), Some(zooms)) => {
24                let zboxes = bbox
25                    .iter()
26                    .flat_map(|b| {
27                        tile_ranges(b.tuple(), ZoomOrZooms::Zooms(zooms.clone()))
28                    })
29                    .collect::<Vec<_>>();
30                let pred = zboxes
31                    .iter()
32                    .map(|a| a.mbtiles_sql_where(prefix))
33                    .collect::<Vec<_>>()
34                    .join(" OR ");
35                format!("({pred})")
36            }
37            (Some(bbox), None) => {
38                let zboxes = bbox
39                    .iter()
40                    .flat_map(|b| {
41                        tile_ranges(
42                            b.tuple(),
43                            ZoomOrZooms::Zooms(ZoomSet::all().into()),
44                        )
45                    })
46                    .collect::<Vec<_>>();
47                let pred = zboxes
48                    .iter()
49                    .map(|a| a.mbtiles_sql_where(prefix))
50                    .collect::<Vec<_>>()
51                    .join(" OR ");
52                format!("({pred})")
53            }
54            (None, Some(zooms)) => {
55                format!(
56                    "zoom_level IN ({zooms})",
57                    zooms = zooms
58                        .iter()
59                        .map(ToString::to_string)
60                        .collect::<Vec<String>>()
61                        .join(",")
62                )
63            }
64            (None, None) => String::new(),
65        };
66        // attach 'WHERE'
67        if pred.is_empty() {
68            Ok(pred)
69        } else {
70            Ok(format!("WHERE {pred}"))
71        }
72    }
73}