1use crate::*;
2use alloc::fmt;
3use core::{
4 cmp::Ordering,
5 ops::{Mul, MulAssign, Sub},
6};
7use serde::{
8 Deserialize, Deserializer, Serialize, Serializer,
9 de::{self, SeqAccess, Visitor},
10 ser::SerializeTuple,
11};
12
13pub trait Bounded {
15 fn min_value() -> Self;
17 fn max_value() -> Self;
19}
20macro_rules! impl_bounded {
21 ($($t:ty),*) => {
22 $(
23 impl Bounded for $t {
24 fn min_value() -> Self {
25 <$t>::MIN
26 }
27 fn max_value() -> Self {
28 <$t>::MAX
29 }
30 }
31 )*
32 };
33}
34
35impl_bounded!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, isize, usize, f32, f64);
37
38#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
79pub struct BBox<T = f64> {
80 pub left: T,
82 pub bottom: T,
84 pub right: T,
86 pub top: T,
88}
89impl<T> From<BBox<T>> for MValue
90where
91 T: Into<ValueType>,
92{
93 fn from(bbox: BBox<T>) -> MValue {
94 MValue::from([
95 ("left".into(), bbox.left.into()),
96 ("bottom".into(), bbox.bottom.into()),
97 ("right".into(), bbox.right.into()),
98 ("top".into(), bbox.top.into()),
99 ])
100 }
101}
102impl<T> From<&BBox<T>> for MValue
103where
104 T: Copy + Into<ValueType>,
105{
106 fn from(bbox: &BBox<T>) -> MValue {
107 MValue::from([
108 ("left".into(), bbox.left.into()),
109 ("bottom".into(), bbox.bottom.into()),
110 ("right".into(), bbox.right.into()),
111 ("top".into(), bbox.top.into()),
112 ])
113 }
114}
115impl<T> From<MValue> for BBox<T>
116where
117 T: From<ValueType>,
118{
119 fn from(mvalue: MValue) -> Self {
120 BBox {
121 left: mvalue.get("left").unwrap().clone().into(),
122 bottom: mvalue.get("bottom").unwrap().clone().into(),
123 right: mvalue.get("right").unwrap().clone().into(),
124 top: mvalue.get("top").unwrap().clone().into(),
125 }
126 }
127}
128impl<T> From<&MValue> for BBox<T>
129where
130 T: From<ValueType>,
131{
132 fn from(mvalue: &MValue) -> Self {
133 BBox {
134 left: mvalue.get("left").unwrap().clone().into(),
135 bottom: mvalue.get("bottom").unwrap().clone().into(),
136 right: mvalue.get("right").unwrap().clone().into(),
137 top: mvalue.get("top").unwrap().clone().into(),
138 }
139 }
140}
141impl<T> MValueCompatible for BBox<T>
142where
143 ValueType: From<T>,
144 T: From<ValueType> + Default + Bounded + Copy + Interpolate,
145{
146}
147impl<T> Default for BBox<T>
148where
149 T: Default + Bounded + Copy,
150{
151 fn default() -> Self {
152 BBox::new(T::max_value(), T::max_value(), T::min_value(), T::min_value())
153 }
154}
155impl<T> BBox<T> {
156 pub fn new(left: T, bottom: T, right: T, top: T) -> Self
158 where
159 T: Copy,
160 {
161 BBox { left, bottom, right, top }
162 }
163
164 pub fn point_overlap<P: GetXY>(&self, point: &P) -> bool
166 where
167 T: Into<f64> + Copy, {
169 point.x() >= self.left.into()
170 && point.x() <= self.right.into()
171 && point.y() >= self.bottom.into()
172 && point.y() <= self.top.into()
173 }
174
175 pub fn merge(&self, other: &Self) -> Self
177 where
178 T: PartialOrd + Copy,
179 {
180 let mut new_bbox = *self;
181 new_bbox.left = if new_bbox.left < other.left { new_bbox.left } else { other.left };
182 new_bbox.bottom =
183 if new_bbox.bottom < other.bottom { new_bbox.bottom } else { other.bottom };
184 new_bbox.right = if new_bbox.right > other.right { new_bbox.right } else { other.right };
185 new_bbox.top = if new_bbox.top > other.top { new_bbox.top } else { other.top };
186
187 new_bbox
188 }
189
190 pub fn merge_in_place(&mut self, other: &Self)
192 where
193 T: PartialOrd + Copy,
194 {
195 self.left = if self.left < other.left { self.left } else { other.left };
196 self.bottom = if self.bottom < other.bottom { self.bottom } else { other.bottom };
197 self.right = if self.right > other.right { self.right } else { other.right };
198 self.top = if self.top > other.top { self.top } else { other.top };
199 }
200
201 pub fn overlap(&self, other: &BBox<T>) -> Option<BBox<T>>
203 where
204 T: PartialOrd + Copy,
205 {
206 if self.left > other.right
207 || self.right < other.left
208 || self.bottom > other.top
209 || self.top < other.bottom
210 {
211 None
212 } else {
213 let left = if self.left > other.left { self.left } else { other.left };
214 let bottom = if self.bottom > other.bottom { self.bottom } else { other.bottom };
215 let right = if self.right < other.right { self.right } else { other.right };
216 let top = if self.top < other.top { self.top } else { other.top };
217
218 Some(BBox { left, bottom, right, top })
219 }
220 }
221
222 pub fn clip(&self, axis: Axis, k1: T, k2: T) -> BBox<T>
224 where
225 T: PartialOrd + Copy,
226 {
227 let mut new_bbox = *self;
228 if axis == Axis::X {
229 new_bbox.left = if new_bbox.left > k1 { new_bbox.left } else { k1 };
230 new_bbox.right = if new_bbox.right < k2 { new_bbox.right } else { k2 };
231 } else {
232 new_bbox.bottom = if new_bbox.bottom > k1 { new_bbox.bottom } else { k1 };
233 new_bbox.top = if new_bbox.top < k2 { new_bbox.top } else { k2 };
234 }
235
236 new_bbox
237 }
238
239 pub fn inside(&self, other: &BBox<T>) -> bool
241 where
242 T: PartialOrd + Copy,
243 {
244 self.left >= other.left
245 && self.right <= other.right
246 && self.bottom >= other.bottom
247 && self.top <= other.top
248 }
249
250 pub fn area(&self) -> T
252 where
253 T: Sub<Output = T> + Mul<Output = T> + Copy,
254 {
255 (self.right - self.left) * (self.top - self.bottom)
256 }
257}
258impl BBox<f64> {
259 pub fn from_point<P: GetXY>(point: &P) -> Self {
261 BBox::new(point.x(), point.y(), point.x(), point.y())
262 }
263
264 pub fn from_linestring<P: GetXY>(line: &[P]) -> Self {
266 let mut bbox = BBox::default();
267 for point in line {
268 bbox.extend_from_point(point);
269 }
270 bbox
271 }
272
273 pub fn from_multi_linestring<P: GetXY>(lines: &[Vec<P>]) -> Self {
275 let mut bbox = BBox::default();
276 for line in lines {
277 for point in line {
278 bbox.extend_from_point(point);
279 }
280 }
281 bbox
282 }
283
284 pub fn from_polygon<P: GetXY>(polygon: &[Vec<P>]) -> Self {
286 Self::from_multi_linestring(polygon)
287 }
288
289 pub fn from_multi_polygon<P: GetXY>(polygons: &[Vec<Vec<P>>]) -> Self {
291 let mut bbox = BBox::default();
292 for polygon in polygons {
293 for line in polygon {
294 for point in line {
295 bbox.extend_from_point(point);
296 }
297 }
298 }
299 bbox
300 }
301
302 pub fn extend_from_point<P: GetXY>(&mut self, point: &P) {
304 self.merge_in_place(&BBox::from_point(point));
305 }
306
307 pub fn from_uv_zoom(u: f64, v: f64, zoom: u8) -> Self {
309 let division_factor = 2. / (1 << zoom) as f64;
310
311 BBox {
312 left: division_factor * u - 1.0,
313 bottom: division_factor * v - 1.0,
314 right: division_factor * (u + 1.0) - 1.0,
315 top: division_factor * (v + 1.0) - 1.0,
316 }
317 }
318
319 pub fn from_st_zoom(s: f64, t: f64, zoom: u8) -> Self {
321 let division_factor = (2. / (1 << zoom) as f64) * 0.5;
322
323 BBox {
324 left: division_factor * s,
325 bottom: division_factor * t,
326 right: division_factor * (s + 1.),
327 top: division_factor * (t + 1.),
328 }
329 }
330}
331impl<T> Serialize for BBox<T>
332where
333 T: Serialize + Copy,
334{
335 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
336 where
337 S: Serializer,
338 {
339 let mut seq = serializer.serialize_tuple(4)?;
340 seq.serialize_element(&self.left)?;
341 seq.serialize_element(&self.bottom)?;
342 seq.serialize_element(&self.right)?;
343 seq.serialize_element(&self.top)?;
344 seq.end()
345 }
346}
347impl<T: Copy> From<BBox3D<T>> for BBox<T> {
348 fn from(bbox: BBox3D<T>) -> Self {
349 BBox::new(bbox.left, bbox.bottom, bbox.right, bbox.top)
350 }
351}
352impl<'de, T> Deserialize<'de> for BBox<T>
353where
354 T: Deserialize<'de> + Copy,
355{
356 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
357 where
358 D: Deserializer<'de>,
359 {
360 struct BBoxVisitor<T> {
361 marker: core::marker::PhantomData<T>,
362 }
363
364 impl<'de, T> Visitor<'de> for BBoxVisitor<T>
365 where
366 T: Deserialize<'de> + Copy,
367 {
368 type Value = BBox<T>;
369
370 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
371 formatter.write_str("a sequence of four numbers")
372 }
373
374 fn visit_seq<V>(self, mut seq: V) -> Result<BBox<T>, V::Error>
375 where
376 V: SeqAccess<'de>,
377 {
378 let left =
379 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(0, &self))?;
380 let bottom =
381 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(1, &self))?;
382 let right =
383 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(2, &self))?;
384 let top = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(3, &self))?;
385 Ok(BBox { left, bottom, right, top })
386 }
387 }
388
389 deserializer.deserialize_tuple(4, BBoxVisitor { marker: core::marker::PhantomData })
390 }
391}
392
393#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
435pub struct BBox3D<T = f64> {
436 pub left: T,
438 pub bottom: T,
440 pub right: T,
442 pub top: T,
444 pub near: T,
447 pub far: T,
450}
451impl<T> From<BBox3D<T>> for MValue
452where
453 T: Into<ValueType>,
454{
455 fn from(bbox: BBox3D<T>) -> MValue {
456 MValue::from([
457 ("left".into(), bbox.left.into()),
458 ("bottom".into(), bbox.bottom.into()),
459 ("right".into(), bbox.right.into()),
460 ("top".into(), bbox.top.into()),
461 ("near".into(), bbox.near.into()),
462 ("far".into(), bbox.far.into()),
463 ])
464 }
465}
466impl<T> From<&BBox3D<T>> for MValue
467where
468 T: Copy + Into<ValueType>,
469{
470 fn from(bbox: &BBox3D<T>) -> MValue {
471 MValue::from([
472 ("left".into(), bbox.left.into()),
473 ("bottom".into(), bbox.bottom.into()),
474 ("right".into(), bbox.right.into()),
475 ("top".into(), bbox.top.into()),
476 ("near".into(), bbox.near.into()),
477 ("far".into(), bbox.far.into()),
478 ])
479 }
480}
481impl<T> From<MValue> for BBox3D<T>
482where
483 T: From<ValueType>,
484{
485 fn from(mvalue: MValue) -> Self {
486 BBox3D {
487 left: mvalue.get("left").unwrap().clone().into(),
488 bottom: mvalue.get("bottom").unwrap().clone().into(),
489 right: mvalue.get("right").unwrap().clone().into(),
490 top: mvalue.get("top").unwrap().clone().into(),
491 near: mvalue.get("near").unwrap().clone().into(),
492 far: mvalue.get("far").unwrap().clone().into(),
493 }
494 }
495}
496impl<T> From<&MValue> for BBox3D<T>
497where
498 T: From<ValueType>,
499{
500 fn from(mvalue: &MValue) -> Self {
501 BBox3D {
502 left: mvalue.get("left").unwrap().clone().into(),
503 bottom: mvalue.get("bottom").unwrap().clone().into(),
504 right: mvalue.get("right").unwrap().clone().into(),
505 top: mvalue.get("top").unwrap().clone().into(),
506 near: mvalue.get("near").unwrap().clone().into(),
507 far: mvalue.get("far").unwrap().clone().into(),
508 }
509 }
510}
511impl<T> MValueCompatible for BBox3D<T>
512where
513 ValueType: From<T>,
514 T: From<ValueType> + Default + Bounded + Copy + Interpolate,
515{
516}
517impl<T> BBox3D<T> {
518 pub fn new(left: T, bottom: T, right: T, top: T, near: T, far: T) -> Self
520 where
521 T: Copy,
522 {
523 BBox3D { left, bottom, right, top, near, far }
524 }
525
526 pub fn point_overlap<P: GetXY + GetZ>(&self, point: &P) -> bool
528 where
529 T: Into<f64> + Copy, {
531 let z = point.z().unwrap_or_default();
532 point.x() >= self.left.into()
533 && point.x() <= self.right.into()
534 && point.y() >= self.bottom.into()
535 && point.y() <= self.top.into()
536 && z >= self.near.into()
537 && z <= self.far.into()
538 }
539
540 pub fn merge(&self, other: &BBox3D<T>) -> BBox3D<T>
542 where
543 T: PartialOrd + Copy,
544 {
545 let mut new_bbox = *self;
546 new_bbox.left = if new_bbox.left < other.left { new_bbox.left } else { other.left };
547 new_bbox.bottom =
548 if new_bbox.bottom < other.bottom { new_bbox.bottom } else { other.bottom };
549 new_bbox.right = if new_bbox.right > other.right { new_bbox.right } else { other.right };
550 new_bbox.top = if new_bbox.top > other.top { new_bbox.top } else { other.top };
551 new_bbox.near = if new_bbox.near < other.near { new_bbox.near } else { other.near };
552 new_bbox.far = if new_bbox.far > other.far { new_bbox.far } else { other.far };
553
554 new_bbox
555 }
556
557 pub fn merge_in_place(&mut self, other: &Self)
559 where
560 T: PartialOrd + Copy,
561 {
562 self.left = if self.left < other.left { self.left } else { other.left };
563 self.bottom = if self.bottom < other.bottom { self.bottom } else { other.bottom };
564 self.right = if self.right > other.right { self.right } else { other.right };
565 self.top = if self.top > other.top { self.top } else { other.top };
566 self.near = if self.near < other.near { self.near } else { other.near };
567 self.far = if self.far > other.far { self.far } else { other.far };
568 }
569
570 pub fn overlap(&self, other: &BBox3D<T>) -> Option<BBox3D<T>>
572 where
573 T: PartialOrd + Copy,
574 {
575 if self.left > other.right
576 || self.right < other.left
577 || self.bottom > other.top
578 || self.top < other.bottom
579 || self.near > other.far
580 || self.far < other.near
581 {
582 None
583 } else {
584 let left = if self.left > other.left { self.left } else { other.left };
585 let bottom = if self.bottom > other.bottom { self.bottom } else { other.bottom };
586 let right = if self.right < other.right { self.right } else { other.right };
587 let top = if self.top < other.top { self.top } else { other.top };
588
589 let near = if self.near > other.near { self.near } else { other.near };
590 let far = if self.far < other.far { self.far } else { other.far };
591
592 Some(BBox3D { left, bottom, right, top, near, far })
593 }
594 }
595
596 pub fn clip(&self, axis: Axis, k1: T, k2: T) -> BBox3D<T>
598 where
599 T: PartialOrd + Copy,
600 {
601 let mut new_bbox = *self;
602 if axis == Axis::X {
603 new_bbox.left = if new_bbox.left > k1 { new_bbox.left } else { k1 };
604 new_bbox.right = if new_bbox.right < k2 { new_bbox.right } else { k2 };
605 } else {
606 new_bbox.bottom = if new_bbox.bottom > k1 { new_bbox.bottom } else { k1 };
607 new_bbox.top = if new_bbox.top < k2 { new_bbox.top } else { k2 };
608 }
609
610 new_bbox
611 }
612
613 pub fn from_bbox(bbox: &BBox<T>) -> Self
615 where
616 T: Copy + Default,
617 {
618 BBox3D::new(bbox.left, bbox.bottom, bbox.right, bbox.top, T::default(), T::default())
619 }
620
621 pub fn inside(&self, other: &BBox3D<T>) -> bool
623 where
624 T: PartialOrd + Copy,
625 {
626 self.left >= other.left
627 && self.right <= other.right
628 && self.bottom >= other.bottom
629 && self.top <= other.top
630 && self.near >= other.near
631 && self.far <= other.far
632 }
633
634 pub fn area(&self) -> T
636 where
637 T: Sub<Output = T> + Mul<Output = T> + MulAssign + Into<f64> + Copy,
638 {
639 let mut res = (self.right - self.left) * (self.top - self.bottom);
640 if self.far.into() != 0. || self.near.into() != 0. {
641 res *= self.far - self.near
642 }
643
644 res
645 }
646}
647impl<T> Serialize for BBox3D<T>
648where
649 T: Serialize + Copy,
650{
651 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
652 where
653 S: Serializer,
654 {
655 let mut seq = serializer.serialize_tuple(6)?;
656 seq.serialize_element(&self.left)?;
657 seq.serialize_element(&self.bottom)?;
658 seq.serialize_element(&self.right)?;
659 seq.serialize_element(&self.top)?;
660 seq.serialize_element(&self.near)?;
661 seq.serialize_element(&self.far)?;
662 seq.end()
663 }
664}
665impl<T> Default for BBox3D<T>
666where
667 T: Default + Bounded + Copy,
668{
669 fn default() -> Self {
670 BBox3D::new(
671 T::max_value(),
672 T::max_value(),
673 T::min_value(),
674 T::min_value(),
675 T::max_value(),
676 T::min_value(),
677 )
678 }
679}
680impl BBox3D<f64> {
681 pub fn from_point<P: GetXY + GetZ>(point: &P) -> Self {
683 BBox3D::new(
684 point.x(),
685 point.y(),
686 point.x(),
687 point.y(),
688 point.z().unwrap_or(f64::MAX),
689 point.z().unwrap_or(f64::MIN),
690 )
691 }
692
693 pub fn from_linestring<P: GetXY + GetZ>(line: &[P]) -> Self {
695 let mut bbox = BBox3D::default();
696 for point in line {
697 bbox.extend_from_point(point);
698 }
699 bbox
700 }
701
702 pub fn from_multi_linestring<P: GetXY + GetZ>(lines: &[Vec<P>]) -> Self {
704 let mut bbox = BBox3D::default();
705 for line in lines {
706 for point in line {
707 bbox.extend_from_point(point);
708 }
709 }
710 bbox
711 }
712
713 pub fn from_polygon<P: GetXY + GetZ>(polygon: &[Vec<P>]) -> Self {
715 Self::from_multi_linestring(polygon)
716 }
717
718 pub fn from_multi_polygon<P: GetXY + GetZ>(polygons: &[Vec<Vec<P>>]) -> Self {
720 let mut bbox = BBox3D::default();
721 for polygon in polygons {
722 for line in polygon {
723 for point in line {
724 bbox.extend_from_point(point);
725 }
726 }
727 }
728 bbox
729 }
730
731 pub fn extend_from_point<P: GetXY + GetZ>(&mut self, point: &P) {
733 self.merge_in_place(&BBox3D::from_point(point));
734 }
735
736 pub fn from_uv_zoom(u: f64, v: f64, zoom: u8) -> Self {
738 let division_factor = 2. / (1 << zoom) as f64;
739
740 BBox3D {
741 left: division_factor * u - 1.0,
742 bottom: division_factor * v - 1.0,
743 right: division_factor * (u + 1.0) - 1.0,
744 top: division_factor * (v + 1.0) - 1.0,
745 near: f64::MAX,
746 far: f64::MIN,
747 }
748 }
749
750 pub fn from_st_zoom(s: f64, t: f64, zoom: u8) -> Self {
752 let division_factor = (2. / (1 << zoom) as f64) * 0.5;
753
754 BBox3D {
755 left: division_factor * s,
756 bottom: division_factor * t,
757 right: division_factor * (s + 1.),
758 top: division_factor * (t + 1.),
759 near: f64::MAX,
760 far: f64::MIN,
761 }
762 }
763}
764impl<T: Default + Copy> From<BBox<T>> for BBox3D<T> {
765 fn from(bbox: BBox<T>) -> Self {
766 BBox3D::from_bbox(&bbox)
767 }
768}
769impl<'de, T> Deserialize<'de> for BBox3D<T>
770where
771 T: Deserialize<'de> + Copy,
772{
773 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
774 where
775 D: Deserializer<'de>,
776 {
777 struct BBox3DVisitor<T> {
778 marker: core::marker::PhantomData<T>,
779 }
780
781 impl<'de, T> Visitor<'de> for BBox3DVisitor<T>
782 where
783 T: Deserialize<'de> + Copy,
784 {
785 type Value = BBox3D<T>;
786
787 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
788 formatter.write_str("a sequence of six numbers")
789 }
790
791 fn visit_seq<V>(self, mut seq: V) -> Result<BBox3D<T>, V::Error>
792 where
793 V: SeqAccess<'de>,
794 {
795 let left =
796 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(0, &self))?;
797 let bottom =
798 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(1, &self))?;
799 let right =
800 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(2, &self))?;
801 let top = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(3, &self))?;
802 let near =
803 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(4, &self))?;
804 let far = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(5, &self))?;
805 Ok(BBox3D { left, bottom, right, top, near, far })
806 }
807 }
808
809 deserializer.deserialize_tuple(6, BBox3DVisitor { marker: core::marker::PhantomData })
810 }
811}
812
813#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq)]
815pub enum BBOX {
816 BBox(BBox),
818 BBox3D(BBox3D),
820}
821impl Default for BBOX {
822 fn default() -> Self {
823 BBOX::BBox(BBox::default())
824 }
825}
826impl From<BBox> for BBOX {
827 fn from(bbox: BBox) -> Self {
828 BBOX::BBox(bbox)
829 }
830}
831impl From<BBox3D> for BBOX {
832 fn from(bbox: BBox3D) -> Self {
833 BBOX::BBox3D(bbox)
834 }
835}
836impl Eq for BBOX {}
837impl PartialOrd for BBOX {
838 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
839 Some(self.cmp(other))
840 }
841}
842impl Ord for BBOX {
843 fn cmp(&self, other: &Self) -> Ordering {
844 match (self, other) {
845 (BBOX::BBox(a), BBOX::BBox(b)) => a.partial_cmp(b).unwrap_or(Ordering::Equal),
846 (BBOX::BBox3D(a), BBOX::BBox3D(b)) => a.partial_cmp(b).unwrap_or(Ordering::Equal),
847 (BBOX::BBox(_), BBOX::BBox3D(_)) => Ordering::Less,
849 (BBOX::BBox3D(_), BBOX::BBox(_)) => Ordering::Greater,
850 }
851 }
852}