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
13trait Bounded {
14 fn min_value() -> Self;
15 fn max_value() -> Self;
16}
17macro_rules! impl_bounded {
18 ($($t:ty),*) => {
19 $(
20 impl Bounded for $t {
21 fn min_value() -> Self {
22 <$t>::MIN
23 }
24 fn max_value() -> Self {
25 <$t>::MAX
26 }
27 }
28 )*
29 };
30}
31
32impl_bounded!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, isize, usize, f32, f64);
34
35#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
41pub struct BBox<T = f64> {
42 pub left: T,
44 pub bottom: T,
46 pub right: T,
48 pub top: T,
50}
51impl<T> From<BBox<T>> for MValue
52where
53 T: Into<ValueType>,
54{
55 fn from(bbox: BBox<T>) -> MValue {
56 MValue::from([
57 ("left".into(), bbox.left.into()),
58 ("bottom".into(), bbox.bottom.into()),
59 ("right".into(), bbox.right.into()),
60 ("top".into(), bbox.top.into()),
61 ])
62 }
63}
64impl<T> From<&BBox<T>> for MValue
65where
66 T: Copy + Into<ValueType>,
67{
68 fn from(bbox: &BBox<T>) -> MValue {
69 MValue::from([
70 ("left".into(), bbox.left.into()),
71 ("bottom".into(), bbox.bottom.into()),
72 ("right".into(), bbox.right.into()),
73 ("top".into(), bbox.top.into()),
74 ])
75 }
76}
77impl<T> From<MValue> for BBox<T>
78where
79 T: From<ValueType>,
80{
81 fn from(mvalue: MValue) -> Self {
82 BBox {
83 left: mvalue.get("left").unwrap().clone().into(),
84 bottom: mvalue.get("bottom").unwrap().clone().into(),
85 right: mvalue.get("right").unwrap().clone().into(),
86 top: mvalue.get("top").unwrap().clone().into(),
87 }
88 }
89}
90impl<T> From<&MValue> for BBox<T>
91where
92 T: From<ValueType>,
93{
94 fn from(mvalue: &MValue) -> Self {
95 BBox {
96 left: mvalue.get("left").unwrap().clone().into(),
97 bottom: mvalue.get("bottom").unwrap().clone().into(),
98 right: mvalue.get("right").unwrap().clone().into(),
99 top: mvalue.get("top").unwrap().clone().into(),
100 }
101 }
102}
103impl<T> MValueCompatible for BBox<T>
104where
105 ValueType: From<T>,
106 T: From<ValueType> + Default + Bounded + Copy + Interpolate,
107{
108}
109impl<T> Default for BBox<T>
110where
111 T: Default + Bounded + Copy,
112{
113 fn default() -> Self {
114 BBox::new(T::max_value(), T::max_value(), T::min_value(), T::min_value())
115 }
116}
117impl<T> BBox<T> {
118 pub fn new(left: T, bottom: T, right: T, top: T) -> Self
120 where
121 T: Copy,
122 {
123 BBox { left, bottom, right, top }
124 }
125
126 pub fn point_overlap<P: GetXY>(&self, point: &P) -> bool
128 where
129 T: Into<f64> + Copy, {
131 point.x() >= self.left.into()
132 && point.x() <= self.right.into()
133 && point.y() >= self.bottom.into()
134 && point.y() <= self.top.into()
135 }
136
137 pub fn merge(&self, other: &Self) -> Self
139 where
140 T: PartialOrd + Copy,
141 {
142 let mut new_bbox = *self;
143 new_bbox.left = if new_bbox.left < other.left { new_bbox.left } else { other.left };
144 new_bbox.bottom =
145 if new_bbox.bottom < other.bottom { new_bbox.bottom } else { other.bottom };
146 new_bbox.right = if new_bbox.right > other.right { new_bbox.right } else { other.right };
147 new_bbox.top = if new_bbox.top > other.top { new_bbox.top } else { other.top };
148
149 new_bbox
150 }
151
152 pub fn merge_in_place(&mut self, other: &Self)
154 where
155 T: PartialOrd + Copy,
156 {
157 self.left = if self.left < other.left { self.left } else { other.left };
158 self.bottom = if self.bottom < other.bottom { self.bottom } else { other.bottom };
159 self.right = if self.right > other.right { self.right } else { other.right };
160 self.top = if self.top > other.top { self.top } else { other.top };
161 }
162
163 pub fn overlap(&self, other: &BBox<T>) -> Option<BBox<T>>
165 where
166 T: PartialOrd + Copy,
167 {
168 if self.left > other.right
169 || self.right < other.left
170 || self.bottom > other.top
171 || self.top < other.bottom
172 {
173 None
174 } else {
175 let left = if self.left > other.left { self.left } else { other.left };
176 let bottom = if self.bottom > other.bottom { self.bottom } else { other.bottom };
177 let right = if self.right < other.right { self.right } else { other.right };
178 let top = if self.top < other.top { self.top } else { other.top };
179
180 Some(BBox { left, bottom, right, top })
181 }
182 }
183
184 pub fn clip(&self, axis: Axis, k1: T, k2: T) -> BBox<T>
186 where
187 T: PartialOrd + Copy,
188 {
189 let mut new_bbox = *self;
190 if axis == Axis::X {
191 new_bbox.left = if new_bbox.left > k1 { new_bbox.left } else { k1 };
192 new_bbox.right = if new_bbox.right < k2 { new_bbox.right } else { k2 };
193 } else {
194 new_bbox.bottom = if new_bbox.bottom > k1 { new_bbox.bottom } else { k1 };
195 new_bbox.top = if new_bbox.top < k2 { new_bbox.top } else { k2 };
196 }
197
198 new_bbox
199 }
200
201 pub fn inside(&self, other: &BBox<T>) -> bool
203 where
204 T: PartialOrd + Copy,
205 {
206 self.left >= other.left
207 && self.right <= other.right
208 && self.bottom >= other.bottom
209 && self.top <= other.top
210 }
211
212 pub fn area(&self) -> T
214 where
215 T: Sub<Output = T> + Mul<Output = T> + Copy,
216 {
217 (self.right - self.left) * (self.top - self.bottom)
218 }
219}
220impl BBox<f64> {
221 pub fn from_point<P: GetXY>(point: &P) -> Self {
223 BBox::new(point.x(), point.y(), point.x(), point.y())
224 }
225
226 pub fn from_linestring<P: GetXY>(line: &[P]) -> Self {
228 let mut bbox = BBox::default();
229 for point in line {
230 bbox.extend_from_point(point);
231 }
232 bbox
233 }
234
235 pub fn from_multi_linestring<P: GetXY>(lines: &[Vec<P>]) -> Self {
237 let mut bbox = BBox::default();
238 for line in lines {
239 for point in line {
240 bbox.extend_from_point(point);
241 }
242 }
243 bbox
244 }
245
246 pub fn from_polygon<P: GetXY>(polygon: &[Vec<P>]) -> Self {
248 Self::from_multi_linestring(polygon)
249 }
250
251 pub fn from_multi_polygon<P: GetXY>(polygons: &[Vec<Vec<P>>]) -> Self {
253 let mut bbox = BBox::default();
254 for polygon in polygons {
255 for line in polygon {
256 for point in line {
257 bbox.extend_from_point(point);
258 }
259 }
260 }
261 bbox
262 }
263
264 pub fn extend_from_point<P: GetXY>(&mut self, point: &P) {
266 self.merge_in_place(&BBox::from_point(point));
267 }
268
269 pub fn from_uv_zoom(u: f64, v: f64, zoom: u8) -> Self {
271 let division_factor = 2. / (1 << zoom) as f64;
272
273 BBox {
274 left: division_factor * u - 1.0,
275 bottom: division_factor * v - 1.0,
276 right: division_factor * (u + 1.0) - 1.0,
277 top: division_factor * (v + 1.0) - 1.0,
278 }
279 }
280
281 pub fn from_st_zoom(s: f64, t: f64, zoom: u8) -> Self {
283 let division_factor = (2. / (1 << zoom) as f64) * 0.5;
284
285 BBox {
286 left: division_factor * s,
287 bottom: division_factor * t,
288 right: division_factor * (s + 1.),
289 top: division_factor * (t + 1.),
290 }
291 }
292}
293impl<T> Serialize for BBox<T>
294where
295 T: Serialize + Copy,
296{
297 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
298 where
299 S: Serializer,
300 {
301 let mut seq = serializer.serialize_tuple(4)?;
302 seq.serialize_element(&self.left)?;
303 seq.serialize_element(&self.bottom)?;
304 seq.serialize_element(&self.right)?;
305 seq.serialize_element(&self.top)?;
306 seq.end()
307 }
308}
309impl<T: Copy> From<BBox3D<T>> for BBox<T> {
310 fn from(bbox: BBox3D<T>) -> Self {
311 BBox::new(bbox.left, bbox.bottom, bbox.right, bbox.top)
312 }
313}
314impl<'de, T> Deserialize<'de> for BBox<T>
315where
316 T: Deserialize<'de> + Copy,
317{
318 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
319 where
320 D: Deserializer<'de>,
321 {
322 struct BBoxVisitor<T> {
323 marker: core::marker::PhantomData<T>,
324 }
325
326 impl<'de, T> Visitor<'de> for BBoxVisitor<T>
327 where
328 T: Deserialize<'de> + Copy,
329 {
330 type Value = BBox<T>;
331
332 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
333 formatter.write_str("a sequence of four numbers")
334 }
335
336 fn visit_seq<V>(self, mut seq: V) -> Result<BBox<T>, V::Error>
337 where
338 V: SeqAccess<'de>,
339 {
340 let left =
341 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(0, &self))?;
342 let bottom =
343 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(1, &self))?;
344 let right =
345 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(2, &self))?;
346 let top = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(3, &self))?;
347 Ok(BBox { left, bottom, right, top })
348 }
349 }
350
351 deserializer.deserialize_tuple(4, BBoxVisitor { marker: core::marker::PhantomData })
352 }
353}
354
355#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
358pub struct BBox3D<T = f64> {
359 pub left: T,
361 pub bottom: T,
363 pub right: T,
365 pub top: T,
367 pub near: T,
370 pub far: T,
373}
374impl<T> From<BBox3D<T>> for MValue
375where
376 T: Into<ValueType>,
377{
378 fn from(bbox: BBox3D<T>) -> MValue {
379 MValue::from([
380 ("left".into(), bbox.left.into()),
381 ("bottom".into(), bbox.bottom.into()),
382 ("right".into(), bbox.right.into()),
383 ("top".into(), bbox.top.into()),
384 ("near".into(), bbox.near.into()),
385 ("far".into(), bbox.far.into()),
386 ])
387 }
388}
389impl<T> From<&BBox3D<T>> for MValue
390where
391 T: Copy + Into<ValueType>,
392{
393 fn from(bbox: &BBox3D<T>) -> MValue {
394 MValue::from([
395 ("left".into(), bbox.left.into()),
396 ("bottom".into(), bbox.bottom.into()),
397 ("right".into(), bbox.right.into()),
398 ("top".into(), bbox.top.into()),
399 ("near".into(), bbox.near.into()),
400 ("far".into(), bbox.far.into()),
401 ])
402 }
403}
404impl<T> From<MValue> for BBox3D<T>
405where
406 T: From<ValueType>,
407{
408 fn from(mvalue: MValue) -> Self {
409 BBox3D {
410 left: mvalue.get("left").unwrap().clone().into(),
411 bottom: mvalue.get("bottom").unwrap().clone().into(),
412 right: mvalue.get("right").unwrap().clone().into(),
413 top: mvalue.get("top").unwrap().clone().into(),
414 near: mvalue.get("near").unwrap().clone().into(),
415 far: mvalue.get("far").unwrap().clone().into(),
416 }
417 }
418}
419impl<T> From<&MValue> for BBox3D<T>
420where
421 T: From<ValueType>,
422{
423 fn from(mvalue: &MValue) -> Self {
424 BBox3D {
425 left: mvalue.get("left").unwrap().clone().into(),
426 bottom: mvalue.get("bottom").unwrap().clone().into(),
427 right: mvalue.get("right").unwrap().clone().into(),
428 top: mvalue.get("top").unwrap().clone().into(),
429 near: mvalue.get("near").unwrap().clone().into(),
430 far: mvalue.get("far").unwrap().clone().into(),
431 }
432 }
433}
434impl<T> MValueCompatible for BBox3D<T>
435where
436 ValueType: From<T>,
437 T: From<ValueType> + Default + Bounded + Copy + Interpolate,
438{
439}
440impl<T> BBox3D<T> {
441 pub fn new(left: T, bottom: T, right: T, top: T, near: T, far: T) -> Self
443 where
444 T: Copy,
445 {
446 BBox3D { left, bottom, right, top, near, far }
447 }
448
449 pub fn point_overlap<P: GetXY + GetZ>(&self, point: &P) -> bool
451 where
452 T: Into<f64> + Copy, {
454 let z = point.z().unwrap_or_default();
455 point.x() >= self.left.into()
456 && point.x() <= self.right.into()
457 && point.y() >= self.bottom.into()
458 && point.y() <= self.top.into()
459 && z >= self.near.into()
460 && z <= self.far.into()
461 }
462
463 pub fn merge(&self, other: &BBox3D<T>) -> BBox3D<T>
465 where
466 T: PartialOrd + Copy,
467 {
468 let mut new_bbox = *self;
469 new_bbox.left = if new_bbox.left < other.left { new_bbox.left } else { other.left };
470 new_bbox.bottom =
471 if new_bbox.bottom < other.bottom { new_bbox.bottom } else { other.bottom };
472 new_bbox.right = if new_bbox.right > other.right { new_bbox.right } else { other.right };
473 new_bbox.top = if new_bbox.top > other.top { new_bbox.top } else { other.top };
474 new_bbox.near = if new_bbox.near < other.near { new_bbox.near } else { other.near };
475 new_bbox.far = if new_bbox.far > other.far { new_bbox.far } else { other.far };
476
477 new_bbox
478 }
479
480 pub fn merge_in_place(&mut self, other: &Self)
482 where
483 T: PartialOrd + Copy,
484 {
485 self.left = if self.left < other.left { self.left } else { other.left };
486 self.bottom = if self.bottom < other.bottom { self.bottom } else { other.bottom };
487 self.right = if self.right > other.right { self.right } else { other.right };
488 self.top = if self.top > other.top { self.top } else { other.top };
489 self.near = if self.near < other.near { self.near } else { other.near };
490 self.far = if self.far > other.far { self.far } else { other.far };
491 }
492
493 pub fn overlap(&self, other: &BBox3D<T>) -> Option<BBox3D<T>>
495 where
496 T: PartialOrd + Copy,
497 {
498 if self.left > other.right
499 || self.right < other.left
500 || self.bottom > other.top
501 || self.top < other.bottom
502 || self.near > other.far
503 || self.far < other.near
504 {
505 None
506 } else {
507 let left = if self.left > other.left { self.left } else { other.left };
508 let bottom = if self.bottom > other.bottom { self.bottom } else { other.bottom };
509 let right = if self.right < other.right { self.right } else { other.right };
510 let top = if self.top < other.top { self.top } else { other.top };
511
512 let near = if self.near > other.near { self.near } else { other.near };
513 let far = if self.far < other.far { self.far } else { other.far };
514
515 Some(BBox3D { left, bottom, right, top, near, far })
516 }
517 }
518
519 pub fn clip(&self, axis: Axis, k1: T, k2: T) -> BBox3D<T>
521 where
522 T: PartialOrd + Copy,
523 {
524 let mut new_bbox = *self;
525 if axis == Axis::X {
526 new_bbox.left = if new_bbox.left > k1 { new_bbox.left } else { k1 };
527 new_bbox.right = if new_bbox.right < k2 { new_bbox.right } else { k2 };
528 } else {
529 new_bbox.bottom = if new_bbox.bottom > k1 { new_bbox.bottom } else { k1 };
530 new_bbox.top = if new_bbox.top < k2 { new_bbox.top } else { k2 };
531 }
532
533 new_bbox
534 }
535
536 pub fn from_bbox(bbox: &BBox<T>) -> Self
538 where
539 T: Copy + Default,
540 {
541 BBox3D::new(bbox.left, bbox.bottom, bbox.right, bbox.top, T::default(), T::default())
542 }
543
544 pub fn inside(&self, other: &BBox3D<T>) -> bool
546 where
547 T: PartialOrd + Copy,
548 {
549 self.left >= other.left
550 && self.right <= other.right
551 && self.bottom >= other.bottom
552 && self.top <= other.top
553 && self.near >= other.near
554 && self.far <= other.far
555 }
556
557 pub fn area(&self) -> T
559 where
560 T: Sub<Output = T> + Mul<Output = T> + MulAssign + Into<f64> + Copy,
561 {
562 let mut res = (self.right - self.left) * (self.top - self.bottom);
563 if self.far.into() != 0. || self.near.into() != 0. {
564 res *= self.far - self.near
565 }
566
567 res
568 }
569}
570impl<T> Serialize for BBox3D<T>
571where
572 T: Serialize + Copy,
573{
574 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
575 where
576 S: Serializer,
577 {
578 let mut seq = serializer.serialize_tuple(6)?;
579 seq.serialize_element(&self.left)?;
580 seq.serialize_element(&self.bottom)?;
581 seq.serialize_element(&self.right)?;
582 seq.serialize_element(&self.top)?;
583 seq.serialize_element(&self.near)?;
584 seq.serialize_element(&self.far)?;
585 seq.end()
586 }
587}
588impl<T> Default for BBox3D<T>
589where
590 T: Default + Bounded + Copy,
591{
592 fn default() -> Self {
593 BBox3D::new(
594 T::max_value(),
595 T::max_value(),
596 T::min_value(),
597 T::min_value(),
598 T::max_value(),
599 T::min_value(),
600 )
601 }
602}
603impl BBox3D<f64> {
604 pub fn from_point<P: GetXY + GetZ>(point: &P) -> Self {
606 BBox3D::new(
607 point.x(),
608 point.y(),
609 point.x(),
610 point.y(),
611 point.z().unwrap_or(f64::MAX),
612 point.z().unwrap_or(f64::MIN),
613 )
614 }
615
616 pub fn from_linestring<P: GetXY + GetZ>(line: &[P]) -> Self {
618 let mut bbox = BBox3D::default();
619 for point in line {
620 bbox.extend_from_point(point);
621 }
622 bbox
623 }
624
625 pub fn from_multi_linestring<P: GetXY + GetZ>(lines: &[Vec<P>]) -> Self {
627 let mut bbox = BBox3D::default();
628 for line in lines {
629 for point in line {
630 bbox.extend_from_point(point);
631 }
632 }
633 bbox
634 }
635
636 pub fn from_polygon<P: GetXY + GetZ>(polygon: &[Vec<P>]) -> Self {
638 Self::from_multi_linestring(polygon)
639 }
640
641 pub fn from_multi_polygon<P: GetXY + GetZ>(polygons: &[Vec<Vec<P>>]) -> Self {
643 let mut bbox = BBox3D::default();
644 for polygon in polygons {
645 for line in polygon {
646 for point in line {
647 bbox.extend_from_point(point);
648 }
649 }
650 }
651 bbox
652 }
653
654 pub fn extend_from_point<P: GetXY + GetZ>(&mut self, point: &P) {
656 self.merge_in_place(&BBox3D::from_point(point));
657 }
658
659 pub fn from_uv_zoom(u: f64, v: f64, zoom: u8) -> Self {
661 let division_factor = 2. / (1 << zoom) as f64;
662
663 BBox3D {
664 left: division_factor * u - 1.0,
665 bottom: division_factor * v - 1.0,
666 right: division_factor * (u + 1.0) - 1.0,
667 top: division_factor * (v + 1.0) - 1.0,
668 near: f64::MAX,
669 far: f64::MIN,
670 }
671 }
672
673 pub fn from_st_zoom(s: f64, t: f64, zoom: u8) -> Self {
675 let division_factor = (2. / (1 << zoom) as f64) * 0.5;
676
677 BBox3D {
678 left: division_factor * s,
679 bottom: division_factor * t,
680 right: division_factor * (s + 1.),
681 top: division_factor * (t + 1.),
682 near: f64::MAX,
683 far: f64::MIN,
684 }
685 }
686}
687impl<T: Default + Copy> From<BBox<T>> for BBox3D<T> {
688 fn from(bbox: BBox<T>) -> Self {
689 BBox3D::from_bbox(&bbox)
690 }
691}
692impl<'de, T> Deserialize<'de> for BBox3D<T>
693where
694 T: Deserialize<'de> + Copy,
695{
696 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
697 where
698 D: Deserializer<'de>,
699 {
700 struct BBox3DVisitor<T> {
701 marker: core::marker::PhantomData<T>,
702 }
703
704 impl<'de, T> Visitor<'de> for BBox3DVisitor<T>
705 where
706 T: Deserialize<'de> + Copy,
707 {
708 type Value = BBox3D<T>;
709
710 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
711 formatter.write_str("a sequence of six numbers")
712 }
713
714 fn visit_seq<V>(self, mut seq: V) -> Result<BBox3D<T>, V::Error>
715 where
716 V: SeqAccess<'de>,
717 {
718 let left =
719 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(0, &self))?;
720 let bottom =
721 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(1, &self))?;
722 let right =
723 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(2, &self))?;
724 let top = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(3, &self))?;
725 let near =
726 seq.next_element()?.ok_or_else(|| de::Error::invalid_length(4, &self))?;
727 let far = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(5, &self))?;
728 Ok(BBox3D { left, bottom, right, top, near, far })
729 }
730 }
731
732 deserializer.deserialize_tuple(6, BBox3DVisitor { marker: core::marker::PhantomData })
733 }
734}
735
736#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq)]
738pub enum BBOX {
739 BBox(BBox),
741 BBox3D(BBox3D),
743}
744impl Default for BBOX {
745 fn default() -> Self {
746 BBOX::BBox(BBox::default())
747 }
748}
749impl From<BBox> for BBOX {
750 fn from(bbox: BBox) -> Self {
751 BBOX::BBox(bbox)
752 }
753}
754impl From<BBox3D> for BBOX {
755 fn from(bbox: BBox3D) -> Self {
756 BBOX::BBox3D(bbox)
757 }
758}
759impl Eq for BBOX {}
760impl PartialOrd for BBOX {
761 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
762 Some(self.cmp(other))
763 }
764}
765impl Ord for BBOX {
766 fn cmp(&self, other: &Self) -> Ordering {
767 match (self, other) {
768 (BBOX::BBox(a), BBOX::BBox(b)) => a.partial_cmp(b).unwrap_or(Ordering::Equal),
769 (BBOX::BBox3D(a), BBOX::BBox3D(b)) => a.partial_cmp(b).unwrap_or(Ordering::Equal),
770 (BBOX::BBox(_), BBOX::BBox3D(_)) => Ordering::Less,
772 (BBOX::BBox3D(_), BBOX::BBox(_)) => Ordering::Greater,
773 }
774 }
775}