Skip to main content

jismeshcode/types/
bounding_box.rs

1use crate::types::coordinate::Coordinate;
2
3#[derive(Debug, Clone, Copy, PartialEq)]
4pub struct BoundingBox {
5    south_west: Coordinate,
6    north_east: Coordinate,
7}
8
9impl BoundingBox {
10    pub fn new(south_west: Coordinate, north_east: Coordinate) -> Self {
11        BoundingBox {
12            south_west,
13            north_east,
14        }
15    }
16
17    pub fn south_west(&self) -> Coordinate {
18        self.south_west
19    }
20
21    pub fn north_east(&self) -> Coordinate {
22        self.north_east
23    }
24
25    pub fn min_lat(&self) -> f64 {
26        self.south_west.lat()
27    }
28
29    pub fn max_lat(&self) -> f64 {
30        self.north_east.lat()
31    }
32
33    pub fn min_lon(&self) -> f64 {
34        self.south_west.lon()
35    }
36
37    pub fn max_lon(&self) -> f64 {
38        self.north_east.lon()
39    }
40
41    pub fn contains(&self, coord: Coordinate) -> bool {
42        coord.lat() >= self.min_lat()
43            && coord.lat() <= self.max_lat()
44            && coord.lon() >= self.min_lon()
45            && coord.lon() <= self.max_lon()
46    }
47
48    pub fn center(&self) -> Coordinate {
49        let lat = (self.min_lat() + self.max_lat()) / 2.0;
50        let lon = (self.min_lon() + self.max_lon()) / 2.0;
51        Coordinate::new_unchecked(lat, lon)
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_bounding_box() {
61        let sw = Coordinate::new_unchecked(35.0, 139.0);
62        let ne = Coordinate::new_unchecked(36.0, 140.0);
63        let bbox = BoundingBox::new(sw, ne);
64
65        assert_eq!(bbox.min_lat(), 35.0);
66        assert_eq!(bbox.max_lat(), 36.0);
67        assert_eq!(bbox.min_lon(), 139.0);
68        assert_eq!(bbox.max_lon(), 140.0);
69    }
70
71    #[test]
72    fn test_contains() {
73        let sw = Coordinate::new_unchecked(35.0, 139.0);
74        let ne = Coordinate::new_unchecked(36.0, 140.0);
75        let bbox = BoundingBox::new(sw, ne);
76
77        let inside = Coordinate::new_unchecked(35.5, 139.5);
78        let outside = Coordinate::new_unchecked(37.0, 139.5);
79
80        assert!(bbox.contains(inside));
81        assert!(!bbox.contains(outside));
82    }
83
84    #[test]
85    fn test_center() {
86        let sw = Coordinate::new_unchecked(35.0, 139.0);
87        let ne = Coordinate::new_unchecked(36.0, 140.0);
88        let bbox = BoundingBox::new(sw, ne);
89
90        let center = bbox.center();
91        assert_eq!(center.lat(), 35.5);
92        assert_eq!(center.lon(), 139.5);
93    }
94}