1use crate::*;
2use alloc::fmt;
3use serde::{
4 de::{self, SeqAccess, Visitor},
5 ser::SerializeTuple,
6 Deserialize, Deserializer, Serialize, Serializer,
7};
8
9#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
15pub struct BBox<T = f64> {
16 pub left: T,
18 pub bottom: T,
20 pub right: T,
22 pub top: T,
24}
25impl<T> BBox<T> {
26 pub fn new(left: T, bottom: T, right: T, top: T) -> Self
28 where
29 T: Copy,
30 {
31 BBox { left, bottom, right, top }
32 }
33
34 pub fn point_overlap<M: MValueCompatible>(&self, point: VectorPoint<M>) -> bool
36 where
37 T: Into<f64> + Copy, {
39 point.x >= self.left.into()
40 && point.x <= self.right.into()
41 && point.y >= self.bottom.into()
42 && point.y <= self.top.into()
43 }
44
45 pub fn merge(&self, other: &Self) -> Self
47 where
48 T: PartialOrd + Copy,
49 {
50 let mut new_bbox = *self;
51 new_bbox.left = if new_bbox.left < other.left { new_bbox.left } else { other.left };
52 new_bbox.bottom =
53 if new_bbox.bottom < other.bottom { new_bbox.bottom } else { other.bottom };
54 new_bbox.right = if new_bbox.right > other.right { new_bbox.right } else { other.right };
55 new_bbox.top = if new_bbox.top > other.top { new_bbox.top } else { other.top };
56
57 new_bbox
58 }
59
60 pub fn merge_in_place(&mut self, other: &Self)
62 where
63 T: PartialOrd + Copy,
64 {
65 self.left = if self.left < other.left { self.left } else { other.left };
66 self.bottom = if self.bottom < other.bottom { self.bottom } else { other.bottom };
67 self.right = if self.right > other.right { self.right } else { other.right };
68 self.top = if self.top > other.top { self.top } else { other.top };
69 }
70
71 pub fn overlap(&self, other: &BBox<T>) -> Option<BBox<T>>
73 where
74 T: PartialOrd + Copy,
75 {
76 if self.left > other.right
77 || self.right < other.left
78 || self.bottom > other.top
79 || self.top < other.bottom
80 {
81 None
82 } else {
83 let left = if self.left > other.left { self.left } else { other.left };
84 let bottom = if self.bottom > other.bottom { self.bottom } else { other.bottom };
85 let right = if self.right < other.right { self.right } else { other.right };
86 let top = if self.top < other.top { self.top } else { other.top };
87
88 Some(BBox { left, bottom, right, top })
89 }
90 }
91
92 pub fn clip(&self, axis: Axis, k1: T, k2: T) -> BBox<T>
94 where
95 T: PartialOrd + Copy,
96 {
97 let mut new_bbox = *self;
98 if axis == Axis::X {
99 new_bbox.left = if new_bbox.left > k1 { new_bbox.left } else { k1 };
100 new_bbox.right = if new_bbox.right < k2 { new_bbox.right } else { k2 };
101 } else {
102 new_bbox.bottom = if new_bbox.bottom > k1 { new_bbox.bottom } else { k1 };
103 new_bbox.top = if new_bbox.top < k2 { new_bbox.top } else { k2 };
104 }
105
106 new_bbox
107 }
108}
109impl Default for BBox<f64> {
110 fn default() -> Self {
111 BBox::new(f64::INFINITY, f64::INFINITY, -f64::INFINITY, -f64::INFINITY)
112 }
113}
114impl BBox<f64> {
115 pub fn from_point<M: MValueCompatible>(point: &VectorPoint<M>) -> Self {
117 BBox::new(point.x, point.y, point.x, point.y)
118 }
119
120 pub fn from_linestring<M: MValueCompatible>(line: &VectorLineString<M>) -> Self {
122 let mut bbox = BBox::from_point(&line[0]);
123 for point in line {
124 bbox.extend_from_point(point);
125 }
126 bbox
127 }
128
129 pub fn from_multi_linestring<M: MValueCompatible>(lines: &VectorMultiLineString<M>) -> Self {
131 let mut bbox = BBox::from_point(&lines[0][0]);
132 for line in lines {
133 for point in line {
134 bbox.extend_from_point(point);
135 }
136 }
137 bbox
138 }
139
140 pub fn from_polygon<M: MValueCompatible>(polygon: &VectorPolygon<M>) -> Self {
142 BBox::<f64>::from_multi_linestring(polygon)
143 }
144
145 pub fn from_multi_polygon<M: MValueCompatible>(polygons: &VectorMultiPolygon<M>) -> Self {
147 let mut bbox = BBox::from_point(&polygons[0][0][0]);
148 for polygon in polygons {
149 for line in polygon {
150 for point in line {
151 bbox.extend_from_point(point);
152 }
153 }
154 }
155 bbox
156 }
157
158 pub fn extend_from_point<M: MValueCompatible>(&mut self, point: &VectorPoint<M>) {
160 self.merge_in_place(&BBox::from_point(point));
161 }
162
163 pub fn from_uv_zoom(u: f64, v: f64, zoom: u8) -> Self {
165 let division_factor = 2. / (1 << zoom) as f64;
166
167 BBox {
168 left: division_factor * u - 1.0,
169 bottom: division_factor * v - 1.0,
170 right: division_factor * (u + 1.0) - 1.0,
171 top: division_factor * (v + 1.0) - 1.0,
172 }
173 }
174
175 pub fn from_st_zoom(s: f64, t: f64, zoom: u8) -> Self {
177 let division_factor = (2. / (1 << zoom) as f64) * 0.5;
178
179 BBox {
180 left: division_factor * s,
181 bottom: division_factor * t,
182 right: division_factor * (s + 1.),
183 top: division_factor * (t + 1.),
184 }
185 }
186}
187impl<T> Serialize for BBox<T>
188where
189 T: Serialize + Copy,
190{
191 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
192 where
193 S: Serializer,
194 {
195 let mut seq = serializer.serialize_tuple(4)?;
196 seq.serialize_element(&self.left)?;
197 seq.serialize_element(&self.bottom)?;
198 seq.serialize_element(&self.right)?;
199 seq.serialize_element(&self.top)?;
200 seq.end()
201 }
202}
203impl<'de, T> Deserialize<'de> for BBox<T>
204where
205 T: Deserialize<'de> + Copy,
206{
207 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
208 where
209 D: Deserializer<'de>,
210 {
211 struct BBoxVisitor<T> {
212 marker: core::marker::PhantomData<T>,
213 }
214
215 impl<'de, T> Visitor<'de> for BBoxVisitor<T>
216 where
217 T: Deserialize<'de> + Copy,
218 {
219 type Value = BBox<T>;
220
221 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
222 formatter.write_str("a sequence of four numbers")
223 }
224
225 fn visit_seq<V>(self, mut seq: V) -> Result<BBox<T>, V::Error>
226 where
227 V: SeqAccess<'de>,
228 {
229 let left =
230 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(0, &self))?;
231 let bottom =
232 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(1, &self))?;
233 let right =
234 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(2, &self))?;
235 let top = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(3, &self))?;
236 Ok(BBox { left, bottom, right, top })
237 }
238 }
239
240 deserializer.deserialize_tuple(4, BBoxVisitor { marker: core::marker::PhantomData })
241 }
242}
243
244#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
247pub struct BBox3D<T = f64> {
248 pub left: T,
250 pub bottom: T,
252 pub right: T,
254 pub top: T,
256 pub near: T,
259 pub far: T,
262}
263impl<T> BBox3D<T> {
264 pub fn new(left: T, bottom: T, right: T, top: T, near: T, far: T) -> Self
266 where
267 T: Copy,
268 {
269 BBox3D { left, bottom, right, top, near, far }
270 }
271
272 pub fn point_overlap<M: MValueCompatible>(&self, point: VectorPoint<M>) -> bool
274 where
275 T: Into<f64> + Copy, {
277 let z = point.z.unwrap_or_default();
278 point.x >= self.left.into()
279 && point.x <= self.right.into()
280 && point.y >= self.bottom.into()
281 && point.y <= self.top.into()
282 && z >= self.near.into()
283 && z <= self.far.into()
284 }
285
286 pub fn merge(&self, other: &BBox3D<T>) -> BBox3D<T>
288 where
289 T: PartialOrd + Copy,
290 {
291 let mut new_bbox = *self;
292 new_bbox.left = if new_bbox.left < other.left { new_bbox.left } else { other.left };
293 new_bbox.bottom =
294 if new_bbox.bottom < other.bottom { new_bbox.bottom } else { other.bottom };
295 new_bbox.right = if new_bbox.right > other.right { new_bbox.right } else { other.right };
296 new_bbox.top = if new_bbox.top > other.top { new_bbox.top } else { other.top };
297 new_bbox.near = if new_bbox.near < other.near { new_bbox.near } else { other.near };
298 new_bbox.far = if new_bbox.far > other.far { new_bbox.far } else { other.far };
299
300 new_bbox
301 }
302
303 pub fn merge_in_place(&mut self, other: &Self)
305 where
306 T: PartialOrd + Copy,
307 {
308 self.left = if self.left < other.left { self.left } else { other.left };
309 self.bottom = if self.bottom < other.bottom { self.bottom } else { other.bottom };
310 self.right = if self.right > other.right { self.right } else { other.right };
311 self.top = if self.top > other.top { self.top } else { other.top };
312 self.near = if self.near < other.near { self.near } else { other.near };
313 self.far = if self.far > other.far { self.far } else { other.far };
314 }
315
316 pub fn overlap(&self, other: &BBox3D<T>) -> Option<BBox3D<T>>
318 where
319 T: PartialOrd + Copy,
320 {
321 if self.left > other.right
322 || self.right < other.left
323 || self.bottom > other.top
324 || self.top < other.bottom
325 || self.near > other.far
326 || self.far < other.near
327 {
328 None
329 } else {
330 let left = if self.left > other.left { self.left } else { other.left };
331 let bottom = if self.bottom > other.bottom { self.bottom } else { other.bottom };
332 let right = if self.right < other.right { self.right } else { other.right };
333 let top = if self.top < other.top { self.top } else { other.top };
334
335 let near = if self.near > other.near { self.near } else { other.near };
336 let far = if self.far < other.far { self.far } else { other.far };
337
338 Some(BBox3D { left, bottom, right, top, near, far })
339 }
340 }
341
342 pub fn clip(&self, axis: Axis, k1: T, k2: T) -> BBox3D<T>
344 where
345 T: PartialOrd + Copy,
346 {
347 let mut new_bbox = *self;
348 if axis == Axis::X {
349 new_bbox.left = if new_bbox.left > k1 { new_bbox.left } else { k1 };
350 new_bbox.right = if new_bbox.right < k2 { new_bbox.right } else { k2 };
351 } else {
352 new_bbox.bottom = if new_bbox.bottom > k1 { new_bbox.bottom } else { k1 };
353 new_bbox.top = if new_bbox.top < k2 { new_bbox.top } else { k2 };
354 }
355
356 new_bbox
357 }
358}
359impl<T> Serialize for BBox3D<T>
360where
361 T: Serialize + Copy,
362{
363 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
364 where
365 S: Serializer,
366 {
367 let mut seq = serializer.serialize_tuple(6)?;
368 seq.serialize_element(&self.left)?;
369 seq.serialize_element(&self.bottom)?;
370 seq.serialize_element(&self.right)?;
371 seq.serialize_element(&self.top)?;
372 seq.serialize_element(&self.near)?;
373 seq.serialize_element(&self.far)?;
374 seq.end()
375 }
376}
377impl Default for BBox3D<f64> {
378 fn default() -> Self {
379 BBox3D::new(
380 f64::INFINITY,
381 f64::INFINITY,
382 -f64::INFINITY,
383 -f64::INFINITY,
384 f64::INFINITY,
385 -f64::INFINITY,
386 )
387 }
388}
389impl BBox3D<f64> {
390 pub fn from_point<M: MValueCompatible>(point: &VectorPoint<M>) -> Self {
392 BBox3D::new(
393 point.x,
394 point.y,
395 point.x,
396 point.y,
397 point.z.unwrap_or(f64::INFINITY),
398 point.z.unwrap_or(-f64::INFINITY),
399 )
400 }
401
402 pub fn from_linestring<M: MValueCompatible>(line: &VectorLineString<M>) -> Self {
404 let mut bbox = BBox3D::from_point(&line[0]);
405 for point in line {
406 bbox.extend_from_point(point);
407 }
408 bbox
409 }
410
411 pub fn from_multi_linestring<M: MValueCompatible>(lines: &VectorMultiLineString<M>) -> Self {
413 let mut bbox = BBox3D::from_point(&lines[0][0]);
414 for line in lines {
415 for point in line {
416 bbox.extend_from_point(point);
417 }
418 }
419 bbox
420 }
421
422 pub fn from_polygon<M: MValueCompatible>(polygon: &VectorPolygon<M>) -> Self {
424 BBox3D::<f64>::from_multi_linestring(polygon)
425 }
426
427 pub fn from_multi_polygon<M: MValueCompatible>(polygons: &VectorMultiPolygon<M>) -> Self {
429 let mut bbox = BBox3D::from_point(&polygons[0][0][0]);
430 for polygon in polygons {
431 for line in polygon {
432 for point in line {
433 bbox.extend_from_point(point);
434 }
435 }
436 }
437 bbox
438 }
439
440 pub fn from_bbox(bbox: &BBox) -> Self {
442 BBox3D::new(bbox.left, bbox.bottom, bbox.right, bbox.top, 0., 0.)
443 }
444
445 pub fn extend_from_point<M: MValueCompatible>(&mut self, point: &VectorPoint<M>) {
447 self.merge_in_place(&BBox3D::from_point(point));
448 }
449
450 pub fn from_uv_zoom(u: f64, v: f64, zoom: u8) -> Self {
452 let division_factor = 2. / (1 << zoom) as f64;
453
454 BBox3D {
455 left: division_factor * u - 1.0,
456 bottom: division_factor * v - 1.0,
457 right: division_factor * (u + 1.0) - 1.0,
458 top: division_factor * (v + 1.0) - 1.0,
459 near: f64::INFINITY,
460 far: -f64::INFINITY,
461 }
462 }
463
464 pub fn from_st_zoom(s: f64, t: f64, zoom: u8) -> Self {
466 let division_factor = (2. / (1 << zoom) as f64) * 0.5;
467
468 BBox3D {
469 left: division_factor * s,
470 bottom: division_factor * t,
471 right: division_factor * (s + 1.),
472 top: division_factor * (t + 1.),
473 near: f64::INFINITY,
474 far: -f64::INFINITY,
475 }
476 }
477}
478impl From<BBox> for BBox3D<f64> {
479 fn from(bbox: BBox) -> Self {
480 BBox3D::from_bbox(&bbox)
481 }
482}
483impl<'de, T> Deserialize<'de> for BBox3D<T>
484where
485 T: Deserialize<'de> + Copy,
486{
487 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
488 where
489 D: Deserializer<'de>,
490 {
491 struct BBox3DVisitor<T> {
492 marker: core::marker::PhantomData<T>,
493 }
494
495 impl<'de, T> Visitor<'de> for BBox3DVisitor<T>
496 where
497 T: Deserialize<'de> + Copy,
498 {
499 type Value = BBox3D<T>;
500
501 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
502 formatter.write_str("a sequence of six numbers")
503 }
504
505 fn visit_seq<V>(self, mut seq: V) -> Result<BBox3D<T>, V::Error>
506 where
507 V: SeqAccess<'de>,
508 {
509 let left =
510 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(0, &self))?;
511 let bottom =
512 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(1, &self))?;
513 let right =
514 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(2, &self))?;
515 let top = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(3, &self))?;
516 let near =
517 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(4, &self))?;
518 let far = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(5, &self))?;
519 Ok(BBox3D { left, bottom, right, top, near, far })
520 }
521 }
522
523 deserializer.deserialize_tuple(6, BBox3DVisitor { marker: core::marker::PhantomData })
524 }
525}
526
527#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq)]
529pub enum BBOX {
530 BBox(BBox),
532 BBox3D(BBox3D),
534}
535impl Default for BBOX {
536 fn default() -> Self {
537 BBOX::BBox(BBox::default())
538 }
539}