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