Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

speed up Relate/Contains with an rstar backed edge set intersector #829

Merged
merged 5 commits into from
May 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions geo-test-fixtures/fixtures/east_baton_rouge.wkt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
POLYGON((-91.316488 30.590003,-91.315282 30.594288,-91.309914 30.601297,-91.301863 30.609497,-91.29465 30.625207,-91.293072 30.629882,-91.292821 30.631539,-91.293596 30.63919,-91.294211 30.641591,-91.296807 30.648037,-91.297658 30.649548,-91.293604 30.655036,-91.292644 30.658244,-91.292608 30.662034,-91.289693 30.667624,-91.288731 30.677904,-91.27046 30.680864,-91.267699 30.686118,-91.268221 30.689126,-91.267518 30.690108,-91.267133 30.693745,-91.267882 30.69442,-91.265734 30.696264,-91.264865 30.698514,-91.260461 30.70129,-91.257352 30.702703,-91.254419 30.705294,-91.250223 30.705131,-91.216658 30.706386,-91.21374 30.706187,-91.193932 30.706939,-91.17396 30.707768,-91.169445 30.707978,-91.145132 30.708785,-91.145008 30.708785,-91.10764 30.710296,-91.101421 30.710579,-91.097704 30.710583,-91.078958 30.711282,-91.053393 30.712184,-91.023218 30.713182,-90.97269 30.715084,-90.968038 30.71528,-90.849041 30.719311,-90.849327 30.717661,-90.8475 30.71629,-90.847859 30.713883,-90.847421 30.712922,-90.845068 30.71246,-90.845888 30.70969,-90.844181 30.708047,-90.848658 30.70447,-90.849922 30.705858,-90.851101 30.70557,-90.851857 30.702998,-90.8537 30.702048,-90.854054 30.700822,-90.852545 30.700603,-90.85147 30.70141,-90.850499 30.700267,-90.8527 30.699303,-90.852985 30.695681,-90.854366 30.69515,-90.857988 30.695477,-90.859058 30.696311,-90.860664 30.6955,-90.859909 30.692764,-90.862696 30.691928,-90.865774 30.693349,-90.869114 30.692353,-90.869982 30.693779,-90.870916 30.693329,-90.870826 30.690951,-90.869282 30.689224,-90.872294 30.68704,-90.874186 30.686451,-90.876457 30.686588,-90.877024 30.684365,-90.879099 30.682584,-90.877092 30.680332,-90.87818 30.679072,-90.879783 30.678886,-90.881 30.677585,-90.8856 30.676884,-90.885735 30.67494,-90.8884 30.673584,-90.890389 30.673779,-90.890602 30.672414,-90.888798 30.671685,-90.888798 30.670584,-90.891899 30.671085,-90.893517 30.670603,-90.896569 30.668153,-90.893901 30.666485,-90.894875 30.66411,-90.8971 30.663685,-90.900459 30.665352,-90.90142 30.664068,-90.899698 30.662373,-90.89979 30.661149,-90.903225 30.659716,-90.902999 30.658187,-90.900677 30.658835,-90.899867 30.658084,-90.901455 30.655313,-90.902346 30.654722,-90.904169 30.655655,-90.904459 30.654692,-90.907358 30.655592,-90.907901 30.657185,-90.908792 30.65532,-90.911962 30.652148,-90.91224 30.65087,-90.910701 30.649385,-90.9096 30.647385,-90.911304 30.645989,-90.913582 30.646772,-90.9154 30.646685,-90.917001 30.643885,-90.916941 30.639759,-90.918315 30.638055,-90.920903 30.636684,-90.922799 30.637221,-90.924601 30.638786,-90.927337 30.637186,-90.9279 30.635085,-90.931854 30.631002,-90.935003 30.628286,-90.935672 30.626387,-90.937738 30.624671,-90.937629 30.622967,-90.939825 30.621947,-90.940636 30.620456,-90.938518 30.618039,-90.934782 30.619782,-90.935031 30.621483,-90.933528 30.620642,-90.932214 30.618409,-90.933206 30.616932,-90.936027 30.616147,-90.936051 30.615005,-90.934182 30.613829,-90.935098 30.612851,-90.936166 30.613716,-90.938669 30.612396,-90.939837 30.608952,-90.941707 30.608455,-90.944376 30.608685,-90.945809 30.609605,-90.947686 30.609826,-90.948301 30.606986,-90.947672 30.605735,-90.949101 30.604085,-90.952921 30.605533,-90.954707 30.604613,-90.956629 30.604644,-90.958064 30.605756,-90.960201 30.605203,-90.960117 30.603245,-90.958339 30.601296,-90.956783 30.600911,-90.956859 30.599497,-90.958215 30.598641,-90.959084 30.598267,-90.961037 30.59902,-90.960534 30.600678,-90.961634 30.600981,-90.962748 30.600001,-90.962898 30.596731,-90.963803 30.593925,-90.965602 30.593685,-90.96622 30.59447,-90.965551 30.597404,-90.971102 30.597383,-90.972247 30.596887,-90.972208 30.59385,-90.97352 30.592471,-90.975823 30.593886,-90.977401 30.593485,-90.977979 30.592319,-90.977564 30.59078,-90.979533 30.590148,-90.980695 30.590779,-90.980497 30.589081,-90.979403 30.587586,-90.980489 30.584757,-90.982203 30.584408,-90.985103 30.585601,-90.985601 30.584686,-90.985515 30.581627,-90.983835 30.579256,-90.986101 30.575986,-90.986141 30.574711,-90.987906 30.572643,-90.986843 30.571579,-90.98211 30.571012,-90.980464 30.568821,-90.976555 30.568453,-90.975718 30.567385,-90.975505 30.565471,-90.97204 30.564175,-90.971431 30.562004,-90.973216 30.56012,-90.972407 30.557335,-90.973276 30.554538,-90.972628 30.552923,-90.972012 30.550828,-90.972958 30.549596,-90.97566 30.547689,-90.975924 30.545495,-90.972802 30.543188,-90.972952 30.540928,-90.974033 30.539505,-90.977519 30.538068,-90.980003 30.537738,-90.981512 30.536387,-90.980931 30.535555,-90.980266 30.534383,-90.981441 30.532891,-90.983745 30.531724,-90.984385 30.530637,-90.982326 30.529691,-90.980723 30.530385,-90.979274 30.529695,-90.97816 30.527677,-90.977473 30.525067,-90.979487 30.523423,-90.981486 30.523259,-90.982197 30.522114,-90.978328 30.521299,-90.978327 30.519752,-90.980463 30.51837,-90.977727 30.515117,-90.975258 30.513965,-90.974228 30.512707,-90.971469 30.511803,-90.971333 30.509198,-90.971001 30.507389,-90.968744 30.506094,-90.96789 30.504381,-90.970957 30.503431,-90.974452 30.501177,-90.975929 30.498349,-90.97374 30.497059,-90.972221 30.497844,-90.970319 30.497527,-90.970035 30.495571,-90.970097 30.492371,-90.971382 30.491452,-90.973126 30.491844,-90.971892 30.489895,-90.972898 30.487617,-90.971933 30.485544,-90.975451 30.483899,-90.974807 30.481763,-90.974857 30.481508,-90.976008 30.480015,-90.978266 30.479956,-90.978662 30.479098,-90.976877 30.476923,-90.975065 30.476003,-90.975122 30.473147,-90.974268 30.471019,-90.976516 30.467267,-90.979607 30.467421,-90.981062 30.466533,-90.984251 30.468332,-90.985709 30.467645,-90.986354 30.466202,-90.988174 30.466515,-90.98923 30.465831,-90.989892 30.46488,-90.98995 30.464738,-90.991475 30.461954,-90.991053 30.460404,-90.989008 30.45866,-90.989195 30.456173,-90.988558 30.455145,-90.98505 30.45327,-90.981157 30.452765,-90.9815 30.451013,-90.983841 30.450237,-90.986847 30.450277,-90.986932 30.448361,-90.985706 30.44761,-90.984245 30.445308,-90.982808 30.444307,-90.981307 30.441883,-90.979362 30.440882,-90.977349 30.43879,-90.976358 30.438531,-90.974558 30.440124,-90.972402 30.440302,-90.973444 30.437701,-90.978066 30.434069,-90.980239 30.433383,-90.981034 30.432144,-90.981048 30.43035,-90.978957 30.42855,-90.982536 30.425479,-90.982351 30.423465,-90.981158 30.422263,-90.977503 30.420899,-90.970717 30.420846,-90.969301 30.420472,-90.967425 30.418801,-90.966114 30.418385,-90.964151 30.418868,-90.963312 30.417981,-90.966053 30.415194,-90.965794 30.414713,-90.963243 30.413719,-90.961949 30.411219,-90.958539 30.407409,-90.957922 30.406076,-90.958435 30.405233,-90.96144 30.403074,-90.963283 30.402806,-90.969401 30.405138,-90.972067 30.402318,-90.972346 30.397519,-90.968888 30.393287,-90.967888 30.39134,-90.968264 30.389151,-90.967357 30.388702,-90.96421 30.390357,-90.96224 30.388391,-90.961391 30.388144,-90.957574 30.388612,-90.954095 30.389642,-90.951012 30.392011,-90.9501 30.394092,-90.949197 30.394445,-90.946648 30.393529,-90.943917 30.391733,-90.942849 30.389448,-90.94468 30.386335,-90.947213 30.384939,-90.9446 30.383792,-90.944817 30.381551,-90.9459 30.379892,-90.9436 30.377992,-90.9437 30.376492,-90.940273 30.374184,-90.937695 30.373883,-90.932906 30.372749,-90.931533 30.371282,-90.9325 30.369697,-90.935477 30.367401,-90.93723 30.366565,-90.937527 30.364746,-90.936957 30.363913,-90.935037 30.36384,-90.934133 30.365846,-90.933056 30.365912,-90.931229 30.364373,-90.930764 30.361974,-90.929417 30.361873,-90.927622 30.364148,-90.926345 30.363723,-90.923101 30.364613,-90.920296 30.365947,-90.91807 30.364954,-90.917549 30.362627,-90.915434 30.361214,-90.915586 30.359497,-90.913523 30.358673,-90.910967 30.359404,-90.909935 30.360531,-90.907063 30.361196,-90.905379 30.36105,-90.903385 30.359774,-90.903678 30.35775,-90.905148 30.357207,-90.907226 30.35772,-90.90805 30.356018,-90.90647 30.355179,-90.903354 30.35564,-90.902341 30.355314,-90.900434 30.352134,-90.900119 30.349623,-90.900596 30.347745,-90.899754 30.347442,-90.897515 30.347981,-90.895577 30.347851,-90.891728 30.345244,-90.894305 30.345859,-90.900194 30.34251,-90.902606 30.342794,-90.904555 30.340624,-90.907057 30.341907,-90.908935 30.340863,-90.910074 30.339713,-90.912256 30.340706,-90.917343 30.340885,-90.917349 30.343786,-90.918851 30.345509,-90.920685 30.345714,-90.923852 30.34413,-90.927625 30.34334,-90.928926 30.341574,-90.930109 30.341389,-90.930743 30.342591,-90.93187 30.342683,-90.933619 30.341476,-90.935656 30.341839,-90.939418 30.340313,-90.941341 30.341117,-90.943858 30.341101,-90.945635 30.343197,-90.948525 30.342826,-90.948581 30.344706,-90.949289 30.345356,-90.951115 30.344634,-90.95311 30.345887,-90.954946 30.345216,-90.956912 30.345644,-90.958892 30.345139,-90.962884 30.345529,-90.963742 30.346704,-90.965546 30.346769,-90.968094 30.345804,-90.969738 30.345891,-90.974123 30.346933,-90.975656 30.346437,-90.976249 30.344656,-90.977364 30.343951,-90.981803 30.344331,-90.983178 30.343893,-90.98463 30.344003,-90.986968 30.345729,-90.988917 30.343089,-90.992883 30.342749,-90.994999 30.341604,-90.997494 30.341511,-91.000818 30.336556,-91.001367 30.33634,-91.006339 30.337795,-91.00778 30.337867,-91.009281 30.336015,-91.012205 30.335654,-91.014157 30.334779,-91.013825 30.330184,-91.014065 30.330029,-91.015148 30.329257,-91.016298 30.328273,-91.017168 30.326419,-91.017986 30.324094,-91.021014 30.321489,-91.025665 30.318262,-91.028271 30.31597,-91.032435 30.314822,-91.036783 30.314746,-91.040452 30.315318,-91.04499 30.31533,-91.046917 30.316134,-91.050206 30.31576,-91.052127 30.316288,-91.053483 30.31532,-91.053546 30.317465,-91.056481 30.317531,-91.058636 30.317081,-91.062717 30.318884,-91.064422 30.318148,-91.067805 30.319381,-91.071102 30.31966,-91.07951 30.319537,-91.082603 30.319693,-91.08633 30.31925,-91.09065 30.319365,-91.093004 30.320592,-91.095639 30.319262,-91.098798 30.319537,-91.10011 30.318793,-91.105204 30.317493,-91.107441 30.316062,-91.108504 30.315393,-91.113004 30.314893,-91.115459 30.312693,-91.118429 30.312469,-91.12013 30.313219,-91.125283 30.313232,-91.128323 30.314226,-91.132672 30.31341,-91.136277 30.315112,-91.137906 30.317194,-91.141478 30.3192,-91.142305 30.319893,-91.142042 30.322718,-91.142105 30.323293,-91.142439 30.324835,-91.145005 30.331293,-91.150801 30.337424,-91.151521 30.337809,-91.154105 30.339193,-91.161971 30.341528,-91.170333 30.343558,-91.174419 30.344187,-91.180251 30.345084,-91.187286 30.34651,-91.194507 30.346993,-91.204422 30.345198,-91.214093 30.342324,-91.222607 30.340593,-91.230307 30.341093,-91.235808 30.344493,-91.239534 30.351584,-91.241508 30.357592,-91.240617 30.362756,-91.233908 30.375292,-91.219429 30.389616,-91.215256 30.39401,-91.212807 30.397091,-91.208107 30.403691,-91.205707 30.407991,-91.199807 30.419091,-91.199056 30.422279,-91.198247 30.425935,-91.196307 30.434691,-91.195906 30.43939,-91.195907 30.43959,-91.196007 30.44689,-91.196114 30.452699,-91.196207 30.45779,-91.196507 30.46389,-91.196407 30.46639,-91.19653 30.469365,-91.196749 30.478845,-91.197205 30.506864,-91.198508 30.513089,-91.200808 30.517689,-91.203708 30.519789,-91.208004 30.522244,-91.209308 30.522989,-91.236101 30.513973,-91.253767 30.508208,-91.257014 30.506857,-91.262734 30.505238,-91.268258 30.504726,-91.274406 30.504613,-91.276486 30.504688,-91.281478 30.506115,-91.28276 30.507317,-91.284161 30.509635,-91.284735 30.511598,-91.284359 30.515339,-91.282767 30.51719,-91.280878 30.518573,-91.275351 30.521081,-91.265989 30.52658,-91.249475 30.533764,-91.246058 30.535851,-91.243333 30.540609,-91.242457 30.544218,-91.242312 30.547994,-91.24309 30.55314,-91.244409 30.555888,-91.247909 30.560688,-91.250109 30.562988,-91.254439 30.566543,-91.261522 30.571071,-91.264954 30.572176,-91.267121 30.572522,-91.280928 30.57295,-91.291498 30.572546,-91.295639 30.572228,-91.302914 30.573119,-91.305854 30.573027,-91.308012 30.573599,-91.310477 30.574679,-91.311825 30.575809,-91.314406 30.578817,-91.314839 30.579791,-91.316547 30.585244,-91.316488 30.590003))
83 changes: 55 additions & 28 deletions geo-test-fixtures/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{fs, iter::FromIterator, path::PathBuf, str::FromStr};

use geo_types::{LineString, MultiPolygon, Polygon};
use geo_types::{LineString, MultiPolygon, Point, Polygon};
use wkt::{Geometry, Wkt, WktFloat};

pub fn louisiana<T>() -> LineString<T>
Expand All @@ -10,6 +10,22 @@ where
line_string("louisiana.wkt")
}

pub fn baton_rouge<T>() -> Point<T>
where
T: WktFloat + Default + FromStr,
{
let x = T::from(-91.147385).unwrap();
let y = T::from(30.471165).unwrap();
Point::new(x, y)
}

pub fn east_baton_rouge<T>() -> Polygon<T>
where
T: WktFloat + Default + FromStr,
{
polygon("east_baton_rouge.wkt")
}

pub fn norway_main<T>() -> LineString<T>
where
T: WktFloat + Default + FromStr,
Expand Down Expand Up @@ -123,9 +139,18 @@ where
{
let wkt = Wkt::from_str(&file(name)).unwrap();
match wkt.item {
Geometry::LineString(line_string) => {
LineString::from_iter(line_string.0.into_iter().map(|coord| (coord.x, coord.y)))
}
Geometry::LineString(line_string) => wkt_line_string_to_geo(&line_string),
_ => unreachable!(),
}
}

fn polygon<T>(name: &str) -> Polygon<T>
where
T: WktFloat + Default + FromStr,
{
let wkt = Wkt::from_str(&file(name)).unwrap();
match wkt.item {
Geometry::Polygon(wkt_polygon) => wkt_polygon_to_geo(&wkt_polygon),
_ => unreachable!(),
}
}
Expand All @@ -136,34 +161,36 @@ where
{
let wkt = Wkt::from_str(&file(name)).unwrap();
match wkt.item {
Geometry::MultiPolygon(multi_polygon) => {
let polygons: Vec<Polygon<T>> = multi_polygon
.0
.into_iter()
.map(|wkt_polygon| {
let exterior: LineString<T> = LineString::from_iter(
wkt_polygon.0[0].0.iter().map(|coord| (coord.x, coord.y)),
);

let interiors: Vec<LineString<T>> = wkt_polygon.0[1..]
.iter()
.map(|wkt_line_string| {
LineString::from_iter(
wkt_line_string.0.iter().map(|coord| (coord.x, coord.y)),
)
})
.collect();

Polygon::new(exterior, interiors)
})
.collect();

MultiPolygon(polygons)
}
Geometry::MultiPolygon(multi_polygon) => wkt_multi_polygon_to_geo(&multi_polygon),
_ => unreachable!(),
}
}

fn wkt_line_string_to_geo<T>(line_string: &wkt::types::LineString<T>) -> LineString<T>
where
T: WktFloat + Default + FromStr,
{
LineString::from_iter(line_string.0.iter().map(|coord| (coord.x, coord.y)))
}

fn wkt_polygon_to_geo<T>(polygon: &wkt::types::Polygon<T>) -> Polygon<T>
where
T: WktFloat + Default + FromStr,
{
let exterior: LineString<T> = wkt_line_string_to_geo(&polygon.0[0]);
let interiors: Vec<LineString<T>> = polygon.0[1..].iter().map(wkt_line_string_to_geo).collect();

Polygon::new(exterior, interiors)
}

fn wkt_multi_polygon_to_geo<T>(multi_polygon: &wkt::types::MultiPolygon<T>) -> MultiPolygon<T>
where
T: WktFloat + Default + FromStr,
{
let polygons: Vec<Polygon<T>> = multi_polygon.0.iter().map(wkt_polygon_to_geo).collect();
MultiPolygon(polygons)
}

fn file(name: &str) -> String {
let mut res = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
res.push("fixtures");
Expand Down
4 changes: 4 additions & 0 deletions geo/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

## Unreleased

* POSSIBLY BREAKING: `GeoFloat` types must now implement `num_traits::Signed` and `num_traits::Bounded`. This shouldn't
affect you if you are using a standard `Geometry<f64>` or `Geometry<f32>` or `geo::GeoFloat` generically.
* Speed up `Relate` and `Contains` traits for large LineStrings and Polygons by using an RTree to more efficiently
inspect edges in our topology graph.
* Flatten algorithm namespace. For example:
```rust
# Before
Expand Down
63 changes: 50 additions & 13 deletions geo/benches/contains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,73 @@ extern crate criterion;
extern crate geo;

use geo::contains::Contains;
use geo::{polygon, Line, Point, Polygon};

use criterion::Criterion;

fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("point in polygon", |bencher| {
let polygon = geo::polygon![
(x: 0.0, y: 0.0),
c.bench_function("point in simple polygon", |bencher| {
let polygon = polygon![
(x: 0.0f64, y: 0.0),
(x: 1.0, y: 0.0),
(x: 1.0, y: 1.0),
(x: 0.0, y: 0.0),
];
let in_candidate = geo::Point::new(0.5, 0.1);
let point = Point::new(0.5, 0.1);
bencher.iter(|| {
criterion::black_box(
criterion::black_box(&polygon).contains(criterion::black_box(&in_candidate)),
);
assert!(criterion::black_box(&polygon).contains(criterion::black_box(&point)));
});
});

c.bench_function("point outside polygon", |bencher| {
let polygon = geo::polygon![
(x: 0.0, y: 0.0),
c.bench_function("point outside simple polygon", |bencher| {
let polygon = polygon![
(x: 0.0f64, y: 0.0),
(x: 1.0, y: 0.0),
(x: 1.0, y: 1.0),
(x: 0.0, y: 0.0),
];
let out_candidate = geo::Point::new(2.0, 2.0);
let point = Point::new(2.0, 2.0);
bencher.iter(|| {
assert!(!criterion::black_box(&polygon).contains(criterion::black_box(&point)));
});
});

c.bench_function("point inside complex polygon", |bencher| {
let polygon = Polygon::<f64>::new(geo_test_fixtures::louisiana(), vec![]);
let point = geo_test_fixtures::baton_rouge();
bencher.iter(|| {
assert!(criterion::black_box(&polygon).contains(criterion::black_box(&point)));
});
});

c.bench_function("point outside complex polygon", |bencher| {
let polygon = Polygon::<f64>::new(geo_test_fixtures::louisiana(), vec![]);
// lake borgne - near and mostly surrounded by, but not inside of, Louisiana
let point = point!(x: -89.641854, y: 30.026283);
bencher.iter(|| {
assert!(!criterion::black_box(&polygon).contains(criterion::black_box(&point)));
});
});

c.bench_function("line across complex polygon", |bencher| {
let polygon = Polygon::<f64>::new(geo_test_fixtures::louisiana(), vec![]);
// crossing part of, but not contained by Louisiana
let line = Line::new(
geo_test_fixtures::baton_rouge(),
point!(x: -89.641854, y: 30.026283),
);
bencher.iter(|| {
assert!(!criterion::black_box(&polygon).contains(criterion::black_box(&line)));
});
});

c.bench_function("complex polygon contains polygon", |bencher| {
let polygon = Polygon::<f64>::new(geo_test_fixtures::louisiana(), vec![]);
let contained_polygon = geo_test_fixtures::east_baton_rouge();

bencher.iter(|| {
criterion::black_box(
criterion::black_box(&polygon).contains(criterion::black_box(&out_candidate)),
assert!(
criterion::black_box(&polygon).contains(criterion::black_box(&contained_polygon))
);
});
});
Expand Down
Loading