geo/algorithm/validation/
geometry_collection.rs1use super::{GeometryIndex, InvalidGeometry, Validation};
2use crate::{GeoFloat, GeometryCollection};
3
4use std::fmt;
5
6#[derive(Debug, Clone, PartialEq)]
8pub enum InvalidGeometryCollection {
9 InvalidGeometry(GeometryIndex, Box<InvalidGeometry>),
11}
12
13impl std::error::Error for InvalidGeometryCollection {}
14
15impl fmt::Display for InvalidGeometryCollection {
16 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
17 match self {
18 InvalidGeometryCollection::InvalidGeometry(idx, err) => {
19 write!(f, "geometry at index {} is invalid: {}", idx.0, err)
20 }
21 }
22 }
23}
24
25impl<F: GeoFloat> Validation for GeometryCollection<F> {
26 type Error = InvalidGeometryCollection;
27
28 fn visit_validation<T>(
29 &self,
30 mut handle_validation_error: Box<dyn FnMut(Self::Error) -> Result<(), T> + '_>,
31 ) -> Result<(), T> {
32 for (i, geometry) in self.0.iter().enumerate() {
35 geometry.visit_validation(Box::new(&mut |geometry_err| {
36 let err = InvalidGeometryCollection::InvalidGeometry(
37 GeometryIndex(i),
38 Box::new(geometry_err),
39 );
40 handle_validation_error(err)
41 }))?;
42 }
43 Ok(())
44 }
45}
46#[cfg(test)]
47mod tests {
48 use super::*;
49 use crate::algorithm::validation::{assert_validation_errors, InvalidLineString};
50 use crate::wkt;
51
52 #[test]
53 fn test_geometrycollection_contain_invalid_element() {
54 let gc = wkt!(
55 GEOMETRYCOLLECTION(
56 POINT(0. 0.),
57 LINESTRING(0. 0.,1. 1.),
58 LINESTRING(0. 0.,0. 0.)
59 )
60 );
61 assert_validation_errors!(
62 gc,
63 vec![InvalidGeometryCollection::InvalidGeometry(
64 GeometryIndex(2),
65 Box::new(InvalidGeometry::InvalidLineString(
66 InvalidLineString::TooFewPoints
67 )),
68 )]
69 );
70 }
71
72 #[test]
73 fn test_display() {
74 let gc = wkt!(
75 GEOMETRYCOLLECTION(
76 POINT(0. 0.),
77 LINESTRING(0. 0.,1. 1.),
78 LINESTRING(0. 0.,0. 0.),
79 POLYGON(
80 (0. 0., 1. 1., 1. 0., 0. 0.),
81 (0. 0., 1. 1., 1. 0., 0. 0.)
82 )
83 )
84 );
85 let errors = gc.validation_errors();
86 assert_eq!(
87 errors[0].to_string(),
88 "geometry at index 2 is invalid: line string must have at least 2 distinct points"
89 );
90
91 assert_eq!(
92 errors[1].to_string(),
93 "geometry at index 3 is invalid: interior ring at index 0 is not contained within the polygon's exterior"
94 );
95
96 assert_eq!(
97 errors[2].to_string(),
98 "geometry at index 3 is invalid: exterior ring and interior ring at index 0 intersect on a line"
99 );
100 }
101}