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