geospatial_types/
bounding_box.rs1use crate::coordinate::GeographicCoordinate;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
11pub struct BoundingBox {
12 pub south_west: GeographicCoordinate,
14 pub north_east: GeographicCoordinate,
16}
17
18impl BoundingBox {
19 pub fn from_corners(
22 south_west: GeographicCoordinate,
23 north_east: GeographicCoordinate,
24 ) -> Result<Self, crate::SDKError> {
25 let _ = GeographicCoordinate::from_degrees(south_west.latitude, south_west.longitude)?;
26 let _ = GeographicCoordinate::from_degrees(north_east.latitude, north_east.longitude)?;
27 if south_west.latitude > north_east.latitude || south_west.longitude > north_east.longitude
28 {
29 return Err(crate::SDKError::InvalidCoordinateInput(
30 "bounding box corners are inverted".to_string(),
31 ));
32 }
33 Ok(Self {
34 south_west,
35 north_east,
36 })
37 }
38
39 pub fn contains_coordinate(&self, coordinate: &GeographicCoordinate) -> bool {
41 coordinate.latitude >= self.south_west.latitude
42 && coordinate.latitude <= self.north_east.latitude
43 && coordinate.longitude >= self.south_west.longitude
44 && coordinate.longitude <= self.north_east.longitude
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::BoundingBox;
51 use crate::coordinate::GeographicCoordinate;
52
53 fn coordinate(latitude: f64, longitude: f64) -> GeographicCoordinate {
54 GeographicCoordinate::from_degrees(latitude, longitude).unwrap()
55 }
56
57 #[test]
58 fn contains_points_inside_and_on_edges() {
59 let bounding_box =
60 BoundingBox::from_corners(coordinate(45.0, 5.0), coordinate(49.0, 11.0)).unwrap();
61 assert!(bounding_box.contains_coordinate(&coordinate(47.0, 8.0)));
62 assert!(bounding_box.contains_coordinate(&coordinate(45.0, 5.0)));
63 assert!(bounding_box.contains_coordinate(&coordinate(49.0, 11.0)));
64 assert!(!bounding_box.contains_coordinate(&coordinate(44.9, 8.0)));
65 assert!(!bounding_box.contains_coordinate(&coordinate(47.0, 11.1)));
66 }
67
68 #[test]
69 fn rejects_inverted_corners() {
70 assert!(BoundingBox::from_corners(coordinate(49.0, 11.0), coordinate(45.0, 5.0)).is_err());
71 }
72}