1use crate::*;
2use alloc::fmt;
3use core::cmp::Ordering;
4use serde::{
5 Deserialize, Deserializer, Serialize, Serializer,
6 de::{self, SeqAccess, Visitor},
7 ser::SerializeTuple,
8};
9
10trait Bounded {
11 fn min_value() -> Self;
12 fn max_value() -> Self;
13}
14macro_rules! impl_bounded {
15 ($($t:ty),*) => {
16 $(
17 impl Bounded for $t {
18 fn min_value() -> Self {
19 <$t>::MIN
20 }
21 fn max_value() -> Self {
22 <$t>::MAX
23 }
24 }
25 )*
26 };
27}
28
29impl_bounded!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, isize, usize, f32, f64);
31
32#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
38pub struct BBox<T = f64> {
39 pub left: T,
41 pub bottom: T,
43 pub right: T,
45 pub top: T,
47}
48impl<T> From<BBox<T>> for MValue
49where
50 T: Into<ValueType>,
51{
52 fn from(bbox: BBox<T>) -> MValue {
53 MValue::from([
54 ("left".into(), bbox.left.into()),
55 ("bottom".into(), bbox.bottom.into()),
56 ("right".into(), bbox.right.into()),
57 ("top".into(), bbox.top.into()),
58 ])
59 }
60}
61impl<T> From<&BBox<T>> for MValue
62where
63 T: Copy + Into<ValueType>,
64{
65 fn from(bbox: &BBox<T>) -> MValue {
66 MValue::from([
67 ("left".into(), bbox.left.into()),
68 ("bottom".into(), bbox.bottom.into()),
69 ("right".into(), bbox.right.into()),
70 ("top".into(), bbox.top.into()),
71 ])
72 }
73}
74impl<T> From<MValue> for BBox<T>
75where
76 T: From<ValueType>,
77{
78 fn from(mvalue: MValue) -> Self {
79 BBox {
80 left: mvalue.get("left").unwrap().clone().into(),
81 bottom: mvalue.get("bottom").unwrap().clone().into(),
82 right: mvalue.get("right").unwrap().clone().into(),
83 top: mvalue.get("top").unwrap().clone().into(),
84 }
85 }
86}
87impl<T> From<&MValue> for BBox<T>
88where
89 T: From<ValueType>,
90{
91 fn from(mvalue: &MValue) -> Self {
92 BBox {
93 left: mvalue.get("left").unwrap().clone().into(),
94 bottom: mvalue.get("bottom").unwrap().clone().into(),
95 right: mvalue.get("right").unwrap().clone().into(),
96 top: mvalue.get("top").unwrap().clone().into(),
97 }
98 }
99}
100impl<T> MValueCompatible for BBox<T>
101where
102 ValueType: From<T>,
103 T: From<ValueType> + Default + Bounded + Copy,
104{
105}
106impl<T> Default for BBox<T>
107where
108 T: Default + Bounded + Copy,
109{
110 fn default() -> Self {
111 BBox::new(T::max_value(), T::max_value(), T::min_value(), T::min_value())
112 }
113}
114impl<T> BBox<T> {
115 pub fn new(left: T, bottom: T, right: T, top: T) -> Self
117 where
118 T: Copy,
119 {
120 BBox { left, bottom, right, top }
121 }
122
123 pub fn point_overlap<P: GetXY>(&self, point: &P) -> bool
125 where
126 T: Into<f64> + Copy, {
128 point.x() >= self.left.into()
129 && point.x() <= self.right.into()
130 && point.y() >= self.bottom.into()
131 && point.y() <= self.top.into()
132 }
133
134 pub fn merge(&self, other: &Self) -> Self
136 where
137 T: PartialOrd + Copy,
138 {
139 let mut new_bbox = *self;
140 new_bbox.left = if new_bbox.left < other.left { new_bbox.left } else { other.left };
141 new_bbox.bottom =
142 if new_bbox.bottom < other.bottom { new_bbox.bottom } else { other.bottom };
143 new_bbox.right = if new_bbox.right > other.right { new_bbox.right } else { other.right };
144 new_bbox.top = if new_bbox.top > other.top { new_bbox.top } else { other.top };
145
146 new_bbox
147 }
148
149 pub fn merge_in_place(&mut self, other: &Self)
151 where
152 T: PartialOrd + Copy,
153 {
154 self.left = if self.left < other.left { self.left } else { other.left };
155 self.bottom = if self.bottom < other.bottom { self.bottom } else { other.bottom };
156 self.right = if self.right > other.right { self.right } else { other.right };
157 self.top = if self.top > other.top { self.top } else { other.top };
158 }
159
160 pub fn overlap(&self, other: &BBox<T>) -> Option<BBox<T>>
162 where
163 T: PartialOrd + Copy,
164 {
165 if self.left > other.right
166 || self.right < other.left
167 || self.bottom > other.top
168 || self.top < other.bottom
169 {
170 None
171 } else {
172 let left = if self.left > other.left { self.left } else { other.left };
173 let bottom = if self.bottom > other.bottom { self.bottom } else { other.bottom };
174 let right = if self.right < other.right { self.right } else { other.right };
175 let top = if self.top < other.top { self.top } else { other.top };
176
177 Some(BBox { left, bottom, right, top })
178 }
179 }
180
181 pub fn clip(&self, axis: Axis, k1: T, k2: T) -> BBox<T>
183 where
184 T: PartialOrd + Copy,
185 {
186 let mut new_bbox = *self;
187 if axis == Axis::X {
188 new_bbox.left = if new_bbox.left > k1 { new_bbox.left } else { k1 };
189 new_bbox.right = if new_bbox.right < k2 { new_bbox.right } else { k2 };
190 } else {
191 new_bbox.bottom = if new_bbox.bottom > k1 { new_bbox.bottom } else { k1 };
192 new_bbox.top = if new_bbox.top < k2 { new_bbox.top } else { k2 };
193 }
194
195 new_bbox
196 }
197
198 pub fn inside(&self, other: &BBox<T>) -> bool
200 where
201 T: PartialOrd + Copy,
202 {
203 self.left >= other.left
204 && self.right <= other.right
205 && self.bottom >= other.bottom
206 && self.top <= other.top
207 }
208}
209impl BBox<f64> {
210 pub fn from_point<P: GetXY>(point: &P) -> Self {
212 BBox::new(point.x(), point.y(), point.x(), point.y())
213 }
214
215 pub fn from_linestring<P: GetXY>(line: &[P]) -> Self {
217 let mut bbox = BBox::from_point(&line[0]);
218 for point in line {
219 bbox.extend_from_point(point);
220 }
221 bbox
222 }
223
224 pub fn from_multi_linestring<P: GetXY>(lines: &[Vec<P>]) -> Self {
226 let mut bbox = BBox::from_point(&lines[0][0]);
227 for line in lines {
228 for point in line {
229 bbox.extend_from_point(point);
230 }
231 }
232 bbox
233 }
234
235 pub fn from_polygon<P: GetXY>(polygon: &[Vec<P>]) -> Self {
237 BBox::<f64>::from_multi_linestring(polygon)
238 }
239
240 pub fn from_multi_polygon<P: GetXY>(polygons: &[Vec<Vec<P>>]) -> Self {
242 let mut bbox = BBox::from_point(&polygons[0][0][0]);
243 for polygon in polygons {
244 for line in polygon {
245 for point in line {
246 bbox.extend_from_point(point);
247 }
248 }
249 }
250 bbox
251 }
252
253 pub fn extend_from_point<P: GetXY>(&mut self, point: &P) {
255 self.merge_in_place(&BBox::from_point(point));
256 }
257
258 pub fn from_uv_zoom(u: f64, v: f64, zoom: u8) -> Self {
260 let division_factor = 2. / (1 << zoom) as f64;
261
262 BBox {
263 left: division_factor * u - 1.0,
264 bottom: division_factor * v - 1.0,
265 right: division_factor * (u + 1.0) - 1.0,
266 top: division_factor * (v + 1.0) - 1.0,
267 }
268 }
269
270 pub fn from_st_zoom(s: f64, t: f64, zoom: u8) -> Self {
272 let division_factor = (2. / (1 << zoom) as f64) * 0.5;
273
274 BBox {
275 left: division_factor * s,
276 bottom: division_factor * t,
277 right: division_factor * (s + 1.),
278 top: division_factor * (t + 1.),
279 }
280 }
281}
282impl<T> Serialize for BBox<T>
283where
284 T: Serialize + Copy,
285{
286 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
287 where
288 S: Serializer,
289 {
290 let mut seq = serializer.serialize_tuple(4)?;
291 seq.serialize_element(&self.left)?;
292 seq.serialize_element(&self.bottom)?;
293 seq.serialize_element(&self.right)?;
294 seq.serialize_element(&self.top)?;
295 seq.end()
296 }
297}
298impl<T: Copy> From<BBox3D<T>> for BBox<T> {
299 fn from(bbox: BBox3D<T>) -> Self {
300 BBox::new(bbox.left, bbox.bottom, bbox.right, bbox.top)
301 }
302}
303impl<'de, T> Deserialize<'de> for BBox<T>
304where
305 T: Deserialize<'de> + Copy,
306{
307 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
308 where
309 D: Deserializer<'de>,
310 {
311 struct BBoxVisitor<T> {
312 marker: core::marker::PhantomData<T>,
313 }
314
315 impl<'de, T> Visitor<'de> for BBoxVisitor<T>
316 where
317 T: Deserialize<'de> + Copy,
318 {
319 type Value = BBox<T>;
320
321 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
322 formatter.write_str("a sequence of four numbers")
323 }
324
325 fn visit_seq<V>(self, mut seq: V) -> Result<BBox<T>, V::Error>
326 where
327 V: SeqAccess<'de>,
328 {
329 let left =
330 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(0, &self))?;
331 let bottom =
332 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(1, &self))?;
333 let right =
334 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(2, &self))?;
335 let top = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(3, &self))?;
336 Ok(BBox { left, bottom, right, top })
337 }
338 }
339
340 deserializer.deserialize_tuple(4, BBoxVisitor { marker: core::marker::PhantomData })
341 }
342}
343
344#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
347pub struct BBox3D<T = f64> {
348 pub left: T,
350 pub bottom: T,
352 pub right: T,
354 pub top: T,
356 pub near: T,
359 pub far: T,
362}
363impl<T> BBox3D<T> {
364 pub fn new(left: T, bottom: T, right: T, top: T, near: T, far: T) -> Self
366 where
367 T: Copy,
368 {
369 BBox3D { left, bottom, right, top, near, far }
370 }
371
372 pub fn point_overlap<P: GetXY + GetZ>(&self, point: &P) -> bool
374 where
375 T: Into<f64> + Copy, {
377 let z = point.z().unwrap_or_default();
378 point.x() >= self.left.into()
379 && point.x() <= self.right.into()
380 && point.y() >= self.bottom.into()
381 && point.y() <= self.top.into()
382 && z >= self.near.into()
383 && z <= self.far.into()
384 }
385
386 pub fn merge(&self, other: &BBox3D<T>) -> BBox3D<T>
388 where
389 T: PartialOrd + Copy,
390 {
391 let mut new_bbox = *self;
392 new_bbox.left = if new_bbox.left < other.left { new_bbox.left } else { other.left };
393 new_bbox.bottom =
394 if new_bbox.bottom < other.bottom { new_bbox.bottom } else { other.bottom };
395 new_bbox.right = if new_bbox.right > other.right { new_bbox.right } else { other.right };
396 new_bbox.top = if new_bbox.top > other.top { new_bbox.top } else { other.top };
397 new_bbox.near = if new_bbox.near < other.near { new_bbox.near } else { other.near };
398 new_bbox.far = if new_bbox.far > other.far { new_bbox.far } else { other.far };
399
400 new_bbox
401 }
402
403 pub fn merge_in_place(&mut self, other: &Self)
405 where
406 T: PartialOrd + Copy,
407 {
408 self.left = if self.left < other.left { self.left } else { other.left };
409 self.bottom = if self.bottom < other.bottom { self.bottom } else { other.bottom };
410 self.right = if self.right > other.right { self.right } else { other.right };
411 self.top = if self.top > other.top { self.top } else { other.top };
412 self.near = if self.near < other.near { self.near } else { other.near };
413 self.far = if self.far > other.far { self.far } else { other.far };
414 }
415
416 pub fn overlap(&self, other: &BBox3D<T>) -> Option<BBox3D<T>>
418 where
419 T: PartialOrd + Copy,
420 {
421 if self.left > other.right
422 || self.right < other.left
423 || self.bottom > other.top
424 || self.top < other.bottom
425 || self.near > other.far
426 || self.far < other.near
427 {
428 None
429 } else {
430 let left = if self.left > other.left { self.left } else { other.left };
431 let bottom = if self.bottom > other.bottom { self.bottom } else { other.bottom };
432 let right = if self.right < other.right { self.right } else { other.right };
433 let top = if self.top < other.top { self.top } else { other.top };
434
435 let near = if self.near > other.near { self.near } else { other.near };
436 let far = if self.far < other.far { self.far } else { other.far };
437
438 Some(BBox3D { left, bottom, right, top, near, far })
439 }
440 }
441
442 pub fn clip(&self, axis: Axis, k1: T, k2: T) -> BBox3D<T>
444 where
445 T: PartialOrd + Copy,
446 {
447 let mut new_bbox = *self;
448 if axis == Axis::X {
449 new_bbox.left = if new_bbox.left > k1 { new_bbox.left } else { k1 };
450 new_bbox.right = if new_bbox.right < k2 { new_bbox.right } else { k2 };
451 } else {
452 new_bbox.bottom = if new_bbox.bottom > k1 { new_bbox.bottom } else { k1 };
453 new_bbox.top = if new_bbox.top < k2 { new_bbox.top } else { k2 };
454 }
455
456 new_bbox
457 }
458
459 pub fn from_bbox(bbox: &BBox<T>) -> Self
461 where
462 T: Copy + Default,
463 {
464 BBox3D::new(bbox.left, bbox.bottom, bbox.right, bbox.top, T::default(), T::default())
465 }
466
467 pub fn inside(&self, other: &BBox3D<T>) -> bool
469 where
470 T: PartialOrd + Copy,
471 {
472 self.left >= other.left
473 && self.right <= other.right
474 && self.bottom >= other.bottom
475 && self.top <= other.top
476 && self.near >= other.near
477 && self.far <= other.far
478 }
479}
480impl<T> Serialize for BBox3D<T>
481where
482 T: Serialize + Copy,
483{
484 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
485 where
486 S: Serializer,
487 {
488 let mut seq = serializer.serialize_tuple(6)?;
489 seq.serialize_element(&self.left)?;
490 seq.serialize_element(&self.bottom)?;
491 seq.serialize_element(&self.right)?;
492 seq.serialize_element(&self.top)?;
493 seq.serialize_element(&self.near)?;
494 seq.serialize_element(&self.far)?;
495 seq.end()
496 }
497}
498impl<T> Default for BBox3D<T>
499where
500 T: Default + Bounded + Copy,
501{
502 fn default() -> Self {
503 BBox3D::new(
504 T::max_value(),
505 T::max_value(),
506 T::min_value(),
507 T::min_value(),
508 T::max_value(),
509 T::min_value(),
510 )
511 }
512}
513impl BBox3D<f64> {
514 pub fn from_point<P: GetXY + GetZ>(point: &P) -> Self {
516 BBox3D::new(
517 point.x(),
518 point.y(),
519 point.x(),
520 point.y(),
521 point.z().unwrap_or(f64::MAX),
522 point.z().unwrap_or(f64::MIN),
523 )
524 }
525
526 pub fn from_linestring<P: GetXY + GetZ>(line: &[P]) -> Self {
528 let mut bbox = BBox3D::from_point(&line[0]);
529 for point in line {
530 bbox.extend_from_point(point);
531 }
532 bbox
533 }
534
535 pub fn from_multi_linestring<P: GetXY + GetZ>(lines: &[Vec<P>]) -> Self {
537 let mut bbox = BBox3D::from_point(&lines[0][0]);
538 for line in lines {
539 for point in line {
540 bbox.extend_from_point(point);
541 }
542 }
543 bbox
544 }
545
546 pub fn from_polygon<P: GetXY + GetZ>(polygon: &[Vec<P>]) -> Self {
548 BBox3D::<f64>::from_multi_linestring(polygon)
549 }
550
551 pub fn from_multi_polygon<P: GetXY + GetZ>(polygons: &[Vec<Vec<P>>]) -> Self {
553 let mut bbox = BBox3D::from_point(&polygons[0][0][0]);
554 for polygon in polygons {
555 for line in polygon {
556 for point in line {
557 bbox.extend_from_point(point);
558 }
559 }
560 }
561 bbox
562 }
563
564 pub fn extend_from_point<P: GetXY + GetZ>(&mut self, point: &P) {
566 self.merge_in_place(&BBox3D::from_point(point));
567 }
568
569 pub fn from_uv_zoom(u: f64, v: f64, zoom: u8) -> Self {
571 let division_factor = 2. / (1 << zoom) as f64;
572
573 BBox3D {
574 left: division_factor * u - 1.0,
575 bottom: division_factor * v - 1.0,
576 right: division_factor * (u + 1.0) - 1.0,
577 top: division_factor * (v + 1.0) - 1.0,
578 near: f64::MAX,
579 far: f64::MIN,
580 }
581 }
582
583 pub fn from_st_zoom(s: f64, t: f64, zoom: u8) -> Self {
585 let division_factor = (2. / (1 << zoom) as f64) * 0.5;
586
587 BBox3D {
588 left: division_factor * s,
589 bottom: division_factor * t,
590 right: division_factor * (s + 1.),
591 top: division_factor * (t + 1.),
592 near: f64::MAX,
593 far: f64::MIN,
594 }
595 }
596}
597impl<T: Default + Copy> From<BBox<T>> for BBox3D<T> {
598 fn from(bbox: BBox<T>) -> Self {
599 BBox3D::from_bbox(&bbox)
600 }
601}
602impl<'de, T> Deserialize<'de> for BBox3D<T>
603where
604 T: Deserialize<'de> + Copy,
605{
606 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
607 where
608 D: Deserializer<'de>,
609 {
610 struct BBox3DVisitor<T> {
611 marker: core::marker::PhantomData<T>,
612 }
613
614 impl<'de, T> Visitor<'de> for BBox3DVisitor<T>
615 where
616 T: Deserialize<'de> + Copy,
617 {
618 type Value = BBox3D<T>;
619
620 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
621 formatter.write_str("a sequence of six numbers")
622 }
623
624 fn visit_seq<V>(self, mut seq: V) -> Result<BBox3D<T>, V::Error>
625 where
626 V: SeqAccess<'de>,
627 {
628 let left =
629 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(0, &self))?;
630 let bottom =
631 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(1, &self))?;
632 let right =
633 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(2, &self))?;
634 let top = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(3, &self))?;
635 let near =
636 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(4, &self))?;
637 let far = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(5, &self))?;
638 Ok(BBox3D { left, bottom, right, top, near, far })
639 }
640 }
641
642 deserializer.deserialize_tuple(6, BBox3DVisitor { marker: core::marker::PhantomData })
643 }
644}
645
646#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq)]
648pub enum BBOX {
649 BBox(BBox),
651 BBox3D(BBox3D),
653}
654impl Default for BBOX {
655 fn default() -> Self {
656 BBOX::BBox(BBox::default())
657 }
658}
659impl Eq for BBOX {}
660impl PartialOrd for BBOX {
661 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
662 Some(self.cmp(other))
663 }
664}
665impl Ord for BBOX {
666 fn cmp(&self, other: &Self) -> Ordering {
667 match (self, other) {
668 (BBOX::BBox(a), BBOX::BBox(b)) => a.partial_cmp(b).unwrap_or(Ordering::Equal),
669 (BBOX::BBox3D(a), BBOX::BBox3D(b)) => a.partial_cmp(b).unwrap_or(Ordering::Equal),
670 (BBOX::BBox(_), BBOX::BBox3D(_)) => Ordering::Less,
672 (BBOX::BBox3D(_), BBOX::BBox(_)) => Ordering::Greater,
673 }
674 }
675}