1use crate::bbox::WebBBox;
2use crate::{flipy, xyz2rmid, BBox, LngLat, Tile, TileZBox};
3
4#[cfg(feature = "pmtiles")]
5use crate::pmtiles;
6
7pub trait TileLike {
9 fn x(&self) -> u32;
11
12 fn y(&self) -> u32;
14
15 fn z(&self) -> u8;
17
18 #[must_use]
20 fn zoom(&self) -> u8 {
21 self.z()
22 }
23
24 fn yflip(&self) -> u32 {
26 flipy(self.y(), self.z())
27 }
28
29 fn flipy(&self) -> u32 {
31 flipy(self.y(), self.z())
32 }
33
34 fn yup(&self) -> u32 {
35 flipy(self.y(), self.z())
36 }
37
38 fn xyz_str_fslash(&self) -> String {
39 format!("{}/{}/{}", self.x(), self.y(), self.z())
40 }
41
42 fn zxy_str_fslash(&self) -> String {
43 format!("{}/{}/{}", self.z(), self.x(), self.y())
44 }
45
46 fn xyz_str_sep(&self, sep: &str) -> String {
47 format!("{}{}{}{}{}", self.x(), sep, self.y(), sep, self.z())
48 }
49
50 fn zxy_str_sep(&self, sep: &str) -> String {
51 format!("{}{}{}{}{}", self.z(), sep, self.x(), sep, self.y())
52 }
53
54 #[must_use]
56 fn tile(&self) -> Tile {
57 Tile::new(self.x(), self.y(), self.z())
58 }
59
60 #[must_use]
62 fn valid(&self) -> bool {
63 crate::valid(self.x(), self.y(), self.z())
64 }
65
66 #[must_use]
68 fn ul(&self) -> LngLat {
69 crate::ul(self.x(), self.y(), self.z())
70 }
71
72 #[must_use]
74 fn ur(&self) -> LngLat {
75 crate::ul(self.x() + 1, self.y(), self.z())
76 }
77
78 #[must_use]
80 fn lr(&self) -> LngLat {
81 crate::ul(self.x() + 1, self.y() + 1, self.z())
82 }
83
84 #[must_use]
86 fn ll(&self) -> LngLat {
87 crate::ul(self.x(), self.y() + 1, self.z())
88 }
89
90 #[must_use]
92 fn quadkey(&self) -> String {
93 crate::xyz2quadkey(self.x(), self.y(), self.z())
94 }
95
96 #[must_use]
98 fn qk(&self) -> String {
99 crate::xyz2quadkey(self.x(), self.y(), self.z())
100 }
101
102 #[cfg(feature = "pmtiles")]
104 #[must_use]
105 fn pmtileid(&self) -> u64 {
106 pmtiles::xyz2pmid(self.x(), self.y(), self.z())
107 }
108
109 #[cfg(feature = "pmtiles")]
111 #[must_use]
112 fn pmid(&self) -> u64 {
113 self.pmtileid()
114 }
115
116 #[must_use]
118 fn row_major_id(&self) -> u64 {
119 xyz2rmid(self.x(), self.y(), self.z())
120 }
121
122 #[must_use]
124 fn rmid(&self) -> u64 {
125 self.row_major_id()
126 }
127
128 #[must_use]
130 fn bbox(&self) -> (f64, f64, f64, f64) {
131 let ul = self.ul();
132 let lr = self.lr();
133 (ul.lng(), lr.lat(), lr.lng(), ul.lat())
134 }
135
136 #[must_use]
137 fn geobbox(&self) -> BBox {
138 let ul = self.ul();
139 let lr = self.lr();
140 BBox::new(ul.lng(), lr.lat(), lr.lng(), ul.lat())
141 }
142
143 #[must_use]
144 fn webbbox(&self) -> WebBBox {
145 self.geobbox().into()
146 }
147
148 #[must_use]
149 fn bbox_string(&self) -> String {
150 let (w, s, e, n) = self.bbox();
151 format!("[{w},{s},{e},{n}]")
152 }
153
154 #[must_use]
156 fn center(&self) -> LngLat {
157 let ul = self.ul();
158 let lr = self.lr();
159 LngLat::new((ul.lng() + lr.lng()) / 2.0, (ul.lat() + lr.lat()) / 2.0)
160 }
161
162 #[must_use]
164 fn json_arr(&self) -> String {
165 format!("[{}, {}, {}]", self.x(), self.y(), self.z())
166 }
167
168 #[must_use]
170 fn json_arr_min(&self) -> String {
171 format!("[{},{},{}]", self.x(), self.y(), self.z())
172 }
173
174 #[must_use]
176 fn json_obj(&self) -> String {
177 format!(
178 "{{\"x\":{}, \"y\":{}, \"z\":{}}}",
179 self.x(),
180 self.y(),
181 self.z()
182 )
183 }
184
185 #[must_use]
187 fn json(&self) -> String {
188 self.json_obj()
189 }
190
191 #[must_use]
193 fn tuple_string(&self) -> String {
194 format!("({}, {}, {})", self.x(), self.y(), self.z())
195 }
196
197 #[must_use]
199 fn mbtiles_sql_where(&self) -> String {
200 format!(
205 "(zoom_level = {} AND tile_column = {} AND tile_row = {})",
206 self.z(),
207 self.x(),
208 flipy(self.y(), self.z())
209 )
210 }
211
212 #[must_use]
214 fn zbox(&self) -> TileZBox {
215 TileZBox::from_tile(self)
216 }
217
218 #[must_use]
220 fn children_zbox(&self, depth: Option<u8>) -> TileZBox {
221 let d = depth.unwrap_or(1);
222 let target_zoom = self.z() + d;
223 let mut zbox = TileZBox::from_tile(self);
224 while zbox.z() < target_zoom {
225 zbox = zbox.zoom_in();
226 }
227 zbox
228 }
229}