Skip to content

Commit

Permalink
Add LineSTring-Polygon intersection
Browse files Browse the repository at this point in the history
  • Loading branch information
urschrei committed Dec 27, 2021
1 parent 7dfc55c commit 853620f
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 2 deletions.
4 changes: 4 additions & 0 deletions geo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,7 @@ harness = false
[[bench]]
name = "frechet_distance"
harness = false

[[bench]]
name = "intersects"
harness = false
49 changes: 49 additions & 0 deletions geo/benches/intersects.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#[macro_use]
extern crate criterion;
extern crate geo;

use criterion::Criterion;
use geo::{intersects::Intersects, Coordinate, Line, LineString, Polygon};


fn criterion_benchmark(c: &mut Criterion) {
let big: Vec<[f64;2 ]> = include!("../src/algorithm/test_fixtures/big.rs");
let norway: Vec<[f64;2 ]> = include!("../src/algorithm/test_fixtures/norway_main.rs");
c.bench_function("Large Polygon-Line intersection", |bencher| {
let polygon = {
let exterior = LineString::<f64>::from(big.clone());
Polygon::new(exterior, vec![])
};
let line = Line::new(
Coordinate { x: 49.92187499999999, y: 70.95969716686398 },
Coordinate { x: 55.1953125, y: 62.59334083012024 }
);

bencher.iter(|| {
criterion::black_box(
criterion::black_box(&polygon).intersects(criterion::black_box(&line)),
);
});
});

c.bench_function("Polygon-Polygon intersection", |bencher| {

let polygon_big = {
let exterior = LineString::<f64>::from(big.clone());
Polygon::new(exterior, vec![])
};
let polygon_norway = {
let exterior = LineString::<f64>::from(norway.clone());
Polygon::new(exterior, vec![])
};

bencher.iter(|| {
criterion::black_box(
criterion::black_box(&polygon_big).intersects(criterion::black_box(&polygon_norway)),
);
});
});
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
32 changes: 30 additions & 2 deletions geo/src/algorithm/intersects/polygon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,36 @@ where
|| self.intersects(&line.end)
}
}

impl<T> Intersects<LineString<T>> for Polygon<T>
where
T: GeoNum,
geo_types::Line<T>: RTreeObject,
{
fn intersects(&self, linestring: &LineString<T>) -> bool {
if (self.exterior().0.len() + self.interiors().iter().map(|ls| ls.0.len()).sum::<usize>())
* linestring.0.len()
> MAX_NAIVE_SEGMENTS
{
let lines_a: Vec<_> = self
.exterior()
.lines()
.chain(self.interiors().iter().flat_map(|ls| ls.lines()))
.collect();
let tree_a = RTree::bulk_load(lines_a);
let lines_b: Vec<_> = linestring.lines().collect();
let tree_b = RTree::bulk_load(lines_b);
let mut candidates = tree_a.intersection_candidates_with_other_tree(&tree_b);
candidates.any(|line_pair| {
dbg!("{:?}", line_pair);
line_pair.0.intersects(line_pair.1)
})
} else {
linestring.lines().any(|line| self.intersects(&line))
}
}
}
symmetric_intersects_impl!(Line<T>, Polygon<T>);
symmetric_intersects_impl!(Polygon<T>, LineString<T>);
symmetric_intersects_impl!(Polygon<T>, MultiLineString<T>);

impl<T> Intersects<Rect<T>> for Polygon<T>
Expand Down Expand Up @@ -81,7 +109,7 @@ where
.collect();
let tree_b = RTree::bulk_load(lines_b);
let mut candidates = tree_a.intersection_candidates_with_other_tree(&tree_b);
candidates.any(|line_pairs| line_pairs.0.intersects(line_pairs.1))
candidates.any(|line_pair| line_pair.0.intersects(line_pair.1))
} else {
self.intersects(polygon.exterior()) ||
polygon.interiors().iter().any(|inner_line_string| self.intersects(inner_line_string)) ||
Expand Down

0 comments on commit 853620f

Please sign in to comment.