From 3ec60bfb0010d12f2c7cef726aa581d75a142705 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Thu, 5 May 2022 10:55:43 -0700 Subject: [PATCH] scaffold rstar edge set intersector Copied the "SimpleEdgeSetIntersector" into a new struct. I'll add the actual RTree implementation in a follow up, and hopefully this way it'll be easier to compare the two implementations. --- .../relate/geomgraph/geometry_graph.rs | 11 +++- .../algorithm/relate/geomgraph/index/mod.rs | 2 + .../index/rstar_edge_set_intersector.rs | 59 +++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 geo/src/algorithm/relate/geomgraph/index/rstar_edge_set_intersector.rs diff --git a/geo/src/algorithm/relate/geomgraph/geometry_graph.rs b/geo/src/algorithm/relate/geomgraph/geometry_graph.rs index a699c06ea2..77efbc1da1 100644 --- a/geo/src/algorithm/relate/geomgraph/geometry_graph.rs +++ b/geo/src/algorithm/relate/geomgraph/geometry_graph.rs @@ -1,5 +1,7 @@ use super::{ - index::{EdgeSetIntersector, SegmentIntersector, SimpleEdgeSetIntersector}, + index::{ + EdgeSetIntersector, RstarEdgeSetIntersector, SegmentIntersector, SimpleEdgeSetIntersector, + }, CoordNode, CoordPos, Direction, Edge, Label, LineIntersector, PlanarGraph, TopologyPosition, }; @@ -97,7 +99,12 @@ where fn create_edge_set_intersector() -> Box> { // PERF: faster algorithms exist. This one was chosen for simplicity of implementation and // debugging - Box::new(SimpleEdgeSetIntersector::new()) + // Slow, but simple and good for debugging + // Box::new(SimpleEdgeSetIntersector::new()) + + // Should be much faster for sparse intersections, while not much slower than + // SimpleEdgeSetIntersector in the dense case + Box::new(RstarEdgeSetIntersector::new()) } fn boundary_nodes(&self) -> impl Iterator> { diff --git a/geo/src/algorithm/relate/geomgraph/index/mod.rs b/geo/src/algorithm/relate/geomgraph/index/mod.rs index 06c4b2c21c..ae48b3db93 100644 --- a/geo/src/algorithm/relate/geomgraph/index/mod.rs +++ b/geo/src/algorithm/relate/geomgraph/index/mod.rs @@ -1,7 +1,9 @@ mod edge_set_intersector; +mod rstar_edge_set_intersector; mod segment_intersector; mod simple_edge_set_intersector; pub(crate) use edge_set_intersector::EdgeSetIntersector; +pub(crate) use rstar_edge_set_intersector::RstarEdgeSetIntersector; pub(crate) use segment_intersector::SegmentIntersector; pub(crate) use simple_edge_set_intersector::SimpleEdgeSetIntersector; diff --git a/geo/src/algorithm/relate/geomgraph/index/rstar_edge_set_intersector.rs b/geo/src/algorithm/relate/geomgraph/index/rstar_edge_set_intersector.rs new file mode 100644 index 0000000000..91619f9197 --- /dev/null +++ b/geo/src/algorithm/relate/geomgraph/index/rstar_edge_set_intersector.rs @@ -0,0 +1,59 @@ +use super::super::Edge; +use super::{EdgeSetIntersector, SegmentIntersector}; +use crate::GeoFloat; + +use std::cell::RefCell; +use std::rc::Rc; + +pub(crate) struct RstarEdgeSetIntersector; + +impl RstarEdgeSetIntersector { + pub fn new() -> Self { + RstarEdgeSetIntersector + } + + fn compute_intersects( + &mut self, + edge0: &Rc>>, + edge1: &Rc>>, + segment_intersector: &mut SegmentIntersector, + ) { + let edge0_coords_len = edge0.borrow().coords().len() - 1; + let edge1_coords_len = edge1.borrow().coords().len() - 1; + for i0 in 0..edge0_coords_len { + for i1 in 0..edge1_coords_len { + segment_intersector.add_intersections(edge0, i0, edge1, i1); + } + } + } +} + +impl EdgeSetIntersector for RstarEdgeSetIntersector { + fn compute_intersections_within_set( + &mut self, + edges: &[Rc>>], + check_for_self_intersecting_edges: bool, + segment_intersector: &mut SegmentIntersector, + ) { + for edge0 in edges.iter() { + for edge1 in edges.iter() { + if check_for_self_intersecting_edges || edge0.as_ptr() != edge1.as_ptr() { + self.compute_intersects(edge0, edge1, segment_intersector); + } + } + } + } + + fn compute_intersections_between_sets( + &mut self, + edges0: &[Rc>>], + edges1: &[Rc>>], + segment_intersector: &mut SegmentIntersector, + ) { + for edge0 in edges0 { + for edge1 in edges1 { + self.compute_intersects(edge0, edge1, segment_intersector); + } + } + } +}