shapefile_gbk/record/
bbox.rs1use super::traits::{GrowablePoint, HasM, HasXY, HasZ, ShrinkablePoint};
3use super::EsriShape;
4use super::PointZ;
5use crate::writer::{f64_max, f64_min};
6
7#[derive(Debug, Copy, Clone, PartialEq)]
26pub struct GenericBBox<PointType> {
27 pub max: PointType,
28 pub min: PointType,
29}
30
31impl<PointType> GenericBBox<PointType> {
32 pub(crate) fn from_points(points: &[PointType]) -> Self
33 where
34 PointType: Copy + ShrinkablePoint + GrowablePoint,
35 {
36 let mut min_point = points[0];
37 let mut max_point = points[0];
38
39 for point in &points[1..] {
40 min_point.shrink(point);
41 max_point.grow(point);
42 }
43
44 Self {
45 max: max_point,
46 min: min_point,
47 }
48 }
49
50 pub(crate) fn grow_from_points(&mut self, points: &[PointType])
51 where
52 PointType: ShrinkablePoint + GrowablePoint,
53 {
54 for point in points {
55 self.min.shrink(point);
56 self.max.grow(point);
57 }
58 }
59
60 pub(crate) fn from_parts(parts: &[Vec<PointType>]) -> Self
61 where
62 PointType: ShrinkablePoint + GrowablePoint + Copy,
63 {
64 let mut bbox = Self::from_points(&parts[0]);
65 for part in &parts[1..] {
66 bbox.grow_from_points(part);
67 }
68 bbox
69 }
70}
71
72impl<PointType: HasXY> GenericBBox<PointType> {
73 pub fn x_range(&self) -> [f64; 2] {
74 [self.min.x(), self.max.x()]
75 }
76
77 pub fn y_range(&self) -> [f64; 2] {
78 [self.min.y(), self.max.y()]
79 }
80}
81
82impl<PointType: HasZ> GenericBBox<PointType> {
83 pub fn z_range(&self) -> [f64; 2] {
84 [self.min.z(), self.max.z()]
85 }
86}
87
88impl<PointType: HasM> GenericBBox<PointType> {
89 pub fn m_range(&self) -> [f64; 2] {
90 [self.min.m(), self.max.m()]
91 }
92}
93
94impl<PointType: Default> Default for GenericBBox<PointType> {
95 fn default() -> Self {
96 Self {
97 max: PointType::default(),
98 min: PointType::default(),
99 }
100 }
101}
102
103pub type BBoxZ = GenericBBox<PointZ>;
104
105impl BBoxZ {
106 pub(crate) fn grow_from_shape<S: EsriShape>(&mut self, shape: &S) {
107 let x_range = shape.x_range();
108 let y_range = shape.y_range();
109 let z_range = shape.z_range();
110 let m_range = shape.m_range();
111
112 self.min.x = f64_min(x_range[0], self.min.x);
113 self.max.x = f64_max(x_range[1], self.max.x);
114 self.min.y = f64_min(y_range[0], self.min.y);
115 self.max.y = f64_max(y_range[1], self.max.y);
116
117 if S::shapetype().has_m() {
118 self.min.m = f64_min(m_range[0], self.min.m);
119 self.max.m = f64_max(m_range[1], self.max.m);
120 }
121
122 if S::shapetype().has_z() {
123 self.min.z = f64_min(z_range[0], self.min.z);
124 self.max.z = f64_max(z_range[1], self.max.z);
125 }
126 }
127}