Skip to content

Commit

Permalink
Warn rather than debug_assert with invalid geometries
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelkirk committed Dec 10, 2024
1 parent 7055373 commit 9523da6
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 4 deletions.
16 changes: 12 additions & 4 deletions geo/src/algorithm/relate/geomgraph/edge_end_bundle_star.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ impl<F: GeoFloat> LabeledEdgeEndBundleStar<F> {

/// Compute a label for the star based on the labels of its EdgeEndBundles.
fn compute_labeling(&mut self, graph_a: &GeometryGraph<F>, graph_b: &GeometryGraph<F>) {
self.propagate_side_labels(0);
self.propagate_side_labels(1);
self.propagate_side_labels(0, graph_a);
self.propagate_side_labels(1, graph_b);
let mut has_dimensional_collapse_edge = [false, false];
for edge_end in self.edges.iter() {
let label = edge_end.label();
Expand Down Expand Up @@ -83,7 +83,7 @@ impl<F: GeoFloat> LabeledEdgeEndBundleStar<F> {
debug!("edge_end_bundle_star: {:?}", self);
}

fn propagate_side_labels(&mut self, geom_index: usize) {
fn propagate_side_labels(&mut self, geom_index: usize, geometry_graph: &GeometryGraph<F>) {
let mut start_position = None;

for edge_ends in self.edge_end_bundles_iter() {
Expand All @@ -109,7 +109,15 @@ impl<F: GeoFloat> LabeledEdgeEndBundleStar<F> {
let right_position = label.position(geom_index, Direction::Right);

if let Some(right_position) = right_position {
debug_assert!(right_position == current_position, "side_location conflict with coordinate: {:?}, right_location: {:?}, current_location: {:?}", edge_ends.coordinate(), right_position, current_position);
#[cfg(debug_assertions)]
if right_position != current_position {
use crate::algorithm::Validation;
if geometry_graph.geometry().is_valid() {
debug_assert!(false, "topology position conflict with coordinate — this can happen with invalid geometries. coordinate: {:?}, right_location: {:?}, current_location: {:?}", edge_ends.coordinate(), right_position, current_position);
} else {
warn!("topology position conflict with coordinate — this can happen with invalid geometries. coordinate: {:?}, right_location: {:?}, current_location: {:?}", edge_ends.coordinate(), right_position, current_position);
}
}
assert!(left_position.is_some(), "found single null side");
current_position = left_position.unwrap();
} else {
Expand Down
44 changes: 44 additions & 0 deletions geo/src/algorithm/validation/geometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use super::{
};
use crate::{GeoFloat, Geometry};

use crate::geometry_cow::GeometryCow;
use std::fmt;

/// A [`Geometry`] is valid if it's inner variant is valid.
Expand Down Expand Up @@ -83,3 +84,46 @@ impl<F: GeoFloat> Validation for Geometry<F> {
Ok(())
}
}

impl<F: GeoFloat> Validation for GeometryCow<'_, F> {
type Error = InvalidGeometry;

fn visit_validation<T>(
&self,
mut handle_validation_error: Box<dyn FnMut(Self::Error) -> Result<(), T> + '_>,
) -> Result<(), T> {
match self {
GeometryCow::Point(g) => g.visit_validation(Box::new(|err| {
handle_validation_error(InvalidGeometry::InvalidPoint(err))
}))?,
GeometryCow::Line(g) => g.visit_validation(Box::new(|err| {
handle_validation_error(InvalidGeometry::InvalidLine(err))
}))?,
GeometryCow::LineString(g) => g.visit_validation(Box::new(|err| {
handle_validation_error(InvalidGeometry::InvalidLineString(err))
}))?,
GeometryCow::Polygon(g) => g.visit_validation(Box::new(|err| {
handle_validation_error(InvalidGeometry::InvalidPolygon(err))
}))?,
GeometryCow::MultiPoint(g) => g.visit_validation(Box::new(|err| {
handle_validation_error(InvalidGeometry::InvalidMultiPoint(err))
}))?,
GeometryCow::MultiLineString(g) => g.visit_validation(Box::new(|err| {
handle_validation_error(InvalidGeometry::InvalidMultiLineString(err))
}))?,
GeometryCow::MultiPolygon(g) => g.visit_validation(Box::new(|err| {
handle_validation_error(InvalidGeometry::InvalidMultiPolygon(err))
}))?,
GeometryCow::GeometryCollection(g) => g.visit_validation(Box::new(|err| {
handle_validation_error(InvalidGeometry::InvalidGeometryCollection(err))
}))?,
GeometryCow::Rect(g) => g.visit_validation(Box::new(|err| {
handle_validation_error(InvalidGeometry::InvalidRect(err))
}))?,
GeometryCow::Triangle(g) => g.visit_validation(Box::new(|err| {
handle_validation_error(InvalidGeometry::InvalidTriangle(err))
}))?,
}
Ok(())
}
}

0 comments on commit 9523da6

Please sign in to comment.