# rust-geo-validator A trait for MultiPolygon/Polygon geo-types to check for validity according to OGC standards. Validation currently conforms only partially to those rules. ## Validation Traits The current geo/geo-types packages contain no support for validation of Geometries other then succeeding/failing to create a Geometry. This package adds a trait to the MultiPolygon and Polygon type to check for validity according to the OGC specifications (currently a work in progress). The validation function provided here look for violations of the following rules: * A polygon may not have less than three points * A polygon may not have any unclosed rings * A polygon may not be a multi-polygon (all inner rings must be contained by the outer ring) * No ring in the polygon may intersect another ring * No ring in the polygon may intersect itself * No point on a ring may be touching a line in it or any other ring * No points may be repeated in a ring * All points must have valid floating point values ### validate() The `is_valid()` trait will return false at the first error and provides no debugging information. #### Examples ```rust use geo_types::polygon; use geo_validator::Validate; // Polygon self intersects and has intersecting inner/outer rings let poly = polygon!( exterior: [ (x: 0., y: 0.), (x: 0., y: 200.), (x: 200., y: 0.), (x: 200., y: 200.), ], interiors: [ [ (x: 10., y: 20.), (x: 50., y: 20.), (x: 20., y: 50.), (x: 50., y: 50.), ], ], ); let valid = poly.validate(); assert_eq!(valid, false); ``` ### validate_detailed The `validate_detailed()` function collects information about where the current MultiPolygon/Polygon is invalid, and returns that information to the caller. #### Examples ```rust use geo_types::polygon; use geo_validator::Validate; // Polygon self intersects and has intersecting inner/outer rings let poly = polygon!( exterior: [ (x: 0., y: 0.), (x: 0., y: 200.), (x: 200., y: 0.), (x: 200., y: 200.), ], interiors: [ [ (x: 10., y: 20.), (x: 50., y: 20.), (x: 20., y: 50.), (x: 50., y: 50.), ], ], ); let valid = poly.validate_detailed(); assert_eq!(valid.valid, false); assert_eq!(valid.ring_intersects_other_ring.len(), 3); assert_eq!(valid.self_intersections.len(), 2); assert_eq!(valid.point_touching_line.len(), 1); assert_eq!(valid.ring_intersects_other_ring[0].x, 20_f64); assert_eq!(valid.ring_intersects_other_ring[0].y, 20_f64); assert_eq!(valid.ring_intersects_other_ring[1].x, 35_f64); assert_eq!(valid.ring_intersects_other_ring[1].y, 35_f64); assert_eq!(valid.ring_intersects_other_ring[2].x, 50_f64); assert_eq!(valid.ring_intersects_other_ring[2].y, 50_f64); assert_eq!(valid.self_intersections[0].x, 100_f64); assert_eq!(valid.self_intersections[0].y, 100_f64); assert_eq!(valid.self_intersections[1].x, 32.857142857142854_f64); assert_eq!(valid.self_intersections[1].y, 37.142857142857146_f64); assert_eq!(valid.point_touching_line[0].x, 50_f64); assert_eq!(valid.point_touching_line[0].y, 50_f64); ```