Skip to content

Commit

Permalink
Merge #829
Browse files Browse the repository at this point in the history
829: speed up Relate/Contains with an rstar backed edge set intersector r=rmanoka a=michaelkirk

- [x] I agree to follow the project's [code of conduct](https://github.com/georust/geo/blob/main/CODE_OF_CONDUCT.md).
- [x] I added an entry to `CHANGES.md` if knowledge of this change could be valuable to users.
---
Fixes #649 (includes some good context too)

Please **note that I'm changing the bounds on `GeoFloat`** to be compatible with `RTreeNum`. I *think* it's unlikely that anyone is using unbounded or unsigned Floats, but let me know if you think otherwise.

Perf Highlights:

Larger overlapping geometries can hugely benefit over the naive O(n<sup>2</sup>)version — for example an ~80x speedup in these two:

![](https://user-images.githubusercontent.com/217057/167031437-9b90a919-ab34-4238-a74c-73c171a4cb9d.png)
```
large rotated polygons  time:   [8.0515 ms 8.0733 ms 8.0978 ms]
                        change: [-98.779% -98.776% -98.772%] (p = 0.00 < 0.05)
                        Performance has improved.
```

![](https://user-images.githubusercontent.com/217057/167031433-14b27845-2af1-48dc-9393-db24c884ebd5.png)
```
offset polygons         time:   [7.8104 ms 7.8154 ms 7.8218 ms]
                        change: [-98.818% -98.817% -98.816%] (p = 0.00 < 0.05)
                        Performance has improved.
```

But not everything is faster. In particular, small geometries don't benefit much from the lower `O(nlg(n))`, while still paying the tax of loading the RTree. 


The JTS test suite has a bunch of tests, but they're almost all comparing small geometries with other small geometries:
```
entire jts test suite   time:   [1.0457 ms 1.0502 ms 1.0549 ms]
                        change: [+24.311% +24.820% +25.351%] (p = 0.00 < 0.05)
```

Perhaps the worst case is comparing a big geometry to a small one. These used to be pretty fast due to a small `n`, but now, because we have to pay the tax of loading the big geometry into the RTree, but only perform a small number of queries against it, it results in a ~5x loss:
```                                                            
line across complex polygon                                                                                                             
                        time:   [415.72 us 417.35 us 419.23 us]                                                                         
                        change: [+487.88% +490.58% +494.00%] (p = 0.00 < 0.05)                                                          
                        Performance has regressed.    
```

Despite some of the regression with small geometries, I think this change is likely to be a big win for the kinds of operations people are likely to do in the real world. But I wanted to include these benched regressions to show some of the tradeoffs and opportunities for future work. 

<details>
<summary>Full bench output</summary>
<pre>
$ cargo bench --bench "*" -- --baseline rstar-edge-set-intersector-baseline
   Compiling geo v0.20.1 (/Users/mkirk/src/georust/geo/geo)
   Compiling jts-test-runner v0.1.0 (/Users/mkirk/src/georust/geo/jts-test-runner)
    Finished bench [optimized] target(s) in 13.22s
     Running unittests (target/release/deps/area-0b8c1a820085a672)
Gnuplot not found, using plotters backend
area                    time:   [8.5296 us 8.5386 us 8.5485 us]
                        change: [-0.1712% +0.0029% +0.1847%] (p = 0.98 > 0.05)
                        No change in performance detected.
Found 6 outliers among 100 measurements (6.00%)
  5 (5.00%) high mild
  1 (1.00%) high severe

     Running unittests (target/release/deps/concave_hull-2f7149869f3a316b)
Gnuplot not found, using plotters backend
concave hull f32        time:   [3.8781 ms 3.8865 ms 3.8957 ms]
                        change: [-0.1281% +0.1487% +0.4656%] (p = 0.34 > 0.05)
                        No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
  8 (8.00%) high mild

concave hull f64        time:   [4.4244 ms 4.4315 ms 4.4392 ms]
                        change: [-0.6194% -0.2200% +0.1702%] (p = 0.29 > 0.05)
                        No change in performance detected.
Found 3 outliers among 100 measurements (3.00%)
  3 (3.00%) high mild

     Running unittests (target/release/deps/contains-e4f5f16e04689e1f)
Gnuplot not found, using plotters backend
point in simple polygon time:   [31.625 ns 31.649 ns 31.675 ns]
                        change: [-0.1575% +0.0085% +0.1803%] (p = 0.92 > 0.05)
                        No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
  1 (1.00%) low mild
  5 (5.00%) high mild
  2 (2.00%) high severe

point outside simple polygon
                        time:   [5.9312 ns 5.9391 ns 5.9481 ns]
                        change: [-2.8268% -2.5942% -2.3294%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 13 outliers among 100 measurements (13.00%)
  1 (1.00%) low mild
  5 (5.00%) high mild
  7 (7.00%) high severe

point inside complex polygon
                        time:   [11.856 us 11.865 us 11.875 us]
                        change: [-0.2277% -0.0962% +0.0346%] (p = 0.15 > 0.05)
                        No change in performance detected.
Found 3 outliers among 100 measurements (3.00%)
  1 (1.00%) low mild
  2 (2.00%) high mild

point outside complex polygon
                        time:   [9.1280 us 9.1374 us 9.1468 us]
                        change: [+0.0772% +0.2399% +0.3912%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 4 outliers among 100 measurements (4.00%)
  1 (1.00%) low severe
  2 (2.00%) low mild
  1 (1.00%) high severe

line across complex polygon
                        time:   [415.72 us 417.35 us 419.23 us]
                        change: [+487.88% +490.58% +494.00%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 5 outliers among 100 measurements (5.00%)
  4 (4.00%) high mild
  1 (1.00%) high severe

complex polygon contains polygon
                        time:   [635.00 us 636.57 us 638.18 us]
                        change: [-90.360% -90.336% -90.307%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 1 outliers among 100 measurements (1.00%)
  1 (1.00%) high severe

     Running unittests (target/release/deps/convex_hull-8bbe3f1942adc5d6)
Gnuplot not found, using plotters backend
convex hull f32         time:   [249.90 us 254.40 us 261.37 us]
                        change: [+0.2974% +1.5514% +3.2978%] (p = 0.03 < 0.05)
                        Change within noise threshold.
Found 14 outliers among 100 measurements (14.00%)
  8 (8.00%) high mild
  6 (6.00%) high severe

convex hull f64         time:   [248.96 us 249.61 us 250.24 us]
                        change: [-0.8463% -0.4822% -0.1187%] (p = 0.01 < 0.05)
                        Change within noise threshold.

convex hull with collinear random i64
                        time:   [50.107 ms 50.178 ms 50.255 ms]
                        change: [-0.0373% +0.1351% +0.2966%] (p = 0.13 > 0.05)
                        No change in performance detected.
Found 4 outliers among 100 measurements (4.00%)
  2 (2.00%) high mild
  2 (2.00%) high severe

     Running unittests (target/release/deps/euclidean_distance-54438be5bae59208)
Gnuplot not found, using plotters backend
Polygon Euclidean distance RTree f64
                        time:   [7.7357 us 7.7431 us 7.7524 us]
                        change: [-0.3278% -0.2016% -0.0743%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 7 outliers among 100 measurements (7.00%)
  3 (3.00%) high mild
  4 (4.00%) high severe

Polygon Euclidean distance rotating calipers f64
                        time:   [4.0159 us 4.0252 us 4.0360 us]
                        change: [-1.0307% -0.7785% -0.5178%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 11 outliers among 100 measurements (11.00%)
  8 (8.00%) high mild
  3 (3.00%) high severe

     Running unittests (target/release/deps/extremes-8dffeefd89ec04f4)
Gnuplot not found, using plotters backend
extremes f32            time:   [17.528 us 17.539 us 17.551 us]
                        change: [-0.3366% -0.1541% +0.0197%] (p = 0.09 > 0.05)
                        No change in performance detected.
Found 6 outliers among 100 measurements (6.00%)
  4 (4.00%) high mild
  2 (2.00%) high severe

extremes f64            time:   [17.424 us 17.430 us 17.436 us]
                        change: [-0.6778% -0.5158% -0.3505%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 17 outliers among 100 measurements (17.00%)
  2 (2.00%) low mild
  11 (11.00%) high mild
  4 (4.00%) high severe

     Running unittests (target/release/deps/frechet_distance-9e7bcb0179a3b5ed)
Gnuplot not found, using plotters backend
Benchmarking frechet distance f32: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 8.5s, enable flat sampling, or reduce sample count to 50.
frechet distance f32    time:   [1.6973 ms 1.6988 ms 1.7006 ms]
                        change: [-1.3785% -1.0898% -0.7948%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 12 outliers among 100 measurements (12.00%)
  4 (4.00%) high mild
  8 (8.00%) high severe

Benchmarking frechet distance f64: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 8.8s, enable flat sampling, or reduce sample count to 50.
frechet distance f64    time:   [1.7609 ms 1.7647 ms 1.7685 ms]
                        change: [-0.0329% +0.1653% +0.3541%] (p = 0.09 > 0.05)
                        No change in performance detected.
Found 19 outliers among 100 measurements (19.00%)
  3 (3.00%) high mild
  16 (16.00%) high severe

     Running unittests (target/release/deps/geodesic_distance-1c6fe3c7253f5c46)
Gnuplot not found, using plotters backend
geodesic distance f64   time:   [526.69 ns 529.63 ns 533.96 ns]
                        change: [-0.7018% -0.3981% -0.0753%] (p = 0.02 < 0.05)
                        Change within noise threshold.
Found 6 outliers among 100 measurements (6.00%)
  5 (5.00%) high mild
  1 (1.00%) high severe

     Running unittests (target/release/deps/intersection-802c59c2adfd8419)
Gnuplot not found, using plotters backend
Benchmarking intersection: Warming up for 3.0000 s
Warning: Unable to complete 10 samples in 5.0s. You may wish to increase target time to 9.4s.
intersection            time:   [934.42 ms 935.71 ms 937.97 ms]
                        change: [-0.7515% -0.4668% -0.1439%] (p = 0.01 < 0.05)
                        Change within noise threshold.
Found 2 outliers among 10 measurements (20.00%)
  1 (10.00%) high mild
  1 (10.00%) high severe

     Running unittests (target/release/deps/relate-ceffe38ba496cd43)
Gnuplot not found, using plotters backend
relate overlapping 50-point polygons
                        time:   [28.875 us 28.904 us 28.936 us]
                        change: [-7.8495% -7.6973% -7.5476%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 3 outliers among 100 measurements (3.00%)
  3 (3.00%) high mild

Benchmarking entire jts test suite: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 5.3s, enable flat sampling, or reduce sample count to 60.
entire jts test suite   time:   [1.0457 ms 1.0502 ms 1.0549 ms]
                        change: [+24.311% +24.820% +25.351%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 11 outliers among 100 measurements (11.00%)
  6 (6.00%) high mild
  5 (5.00%) high severe

jts test suite matching *Relate*
                        time:   [554.63 us 556.97 us 559.57 us]
                        change: [+28.194% +28.932% +29.682%] (p = 0.00 < 0.05)
                        Performance has regressed.

disjoint polygons       time:   [103.25 us 103.38 us 103.50 us]
                        change: [-0.6161% -0.4141% -0.2065%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 4 outliers among 100 measurements (4.00%)
  2 (2.00%) low mild
  1 (1.00%) high mild
  1 (1.00%) high severe

large rotated polygons  time:   [8.0515 ms 8.0733 ms 8.0978 ms]
                        change: [-98.779% -98.776% -98.772%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 20 outliers among 100 measurements (20.00%)
  5 (5.00%) low severe
  3 (3.00%) high mild
  12 (12.00%) high severe

offset polygons         time:   [7.8104 ms 7.8154 ms 7.8218 ms]
                        change: [-98.818% -98.817% -98.816%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 12 outliers among 100 measurements (12.00%)
  5 (5.00%) low severe
  2 (2.00%) low mild
  3 (3.00%) high mild
  2 (2.00%) high severe

     Running unittests (target/release/deps/rotate-040ec92c58b8cab0)
Gnuplot not found, using plotters backend
rotate f32              time:   [43.596 us 43.599 us 43.603 us]
                        change: [-0.5593% -0.4650% -0.3753%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 8 outliers among 100 measurements (8.00%)
  2 (2.00%) low mild
  1 (1.00%) high mild
  5 (5.00%) high severe

rotate f64              time:   [50.061 us 50.075 us 50.090 us]
                        change: [+0.4022% +0.7342% +1.0530%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 7 outliers among 100 measurements (7.00%)
  3 (3.00%) high mild
  4 (4.00%) high severe

     Running unittests (target/release/deps/simplify-aeb9769932233ce2)
Gnuplot not found, using plotters backend
simplify simple f32     time:   [89.241 us 89.359 us 89.480 us]
                        change: [-0.5195% -0.4112% -0.2970%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 17 outliers among 100 measurements (17.00%)
  11 (11.00%) low severe
  3 (3.00%) high mild
  3 (3.00%) high severe

simplify simple f64     time:   [95.772 us 95.782 us 95.794 us]
                        change: [-0.5634% -0.4103% -0.2657%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 6 outliers among 100 measurements (6.00%)
  3 (3.00%) high mild
  3 (3.00%) high severe

     Running unittests (target/release/deps/simplifyvw-4faef7b96d25d158)
Gnuplot not found, using plotters backend
simplify vw simple f32  time:   [188.27 us 188.77 us 189.21 us]
                        change: [-0.3144% -0.0655% +0.1750%] (p = 0.60 > 0.05)
                        No change in performance detected.

simplify vw simple f64  time:   [203.72 us 203.84 us 203.97 us]
                        change: [-1.7891% -1.0598% -0.1814%] (p = 0.01 < 0.05)
                        Change within noise threshold.
Found 5 outliers among 100 measurements (5.00%)
  2 (2.00%) high mild
  3 (3.00%) high severe

Benchmarking simplify vwp f32: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 5.9s, enable flat sampling, or reduce sample count to 60.
simplify vwp f32        time:   [1.1728 ms 1.1732 ms 1.1738 ms]
                        change: [-1.1690% -0.9161% -0.6695%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 11 outliers among 100 measurements (11.00%)
  3 (3.00%) low severe
  4 (4.00%) low mild
  4 (4.00%) high severe

Benchmarking simplify vwp f64: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 5.9s, enable flat sampling, or reduce sample count to 60.
simplify vwp f64        time:   [1.1519 ms 1.1527 ms 1.1535 ms]
                        change: [-0.7080% -0.5331% -0.3648%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 8 outliers among 100 measurements (8.00%)
  2 (2.00%) low mild
  3 (3.00%) high mild
  3 (3.00%) high severe

     Running unittests (target/release/deps/vincenty_distance-c2705d043172c943)
Gnuplot not found, using plotters backend
vincenty distance f32   time:   [151.17 ns 151.17 ns 151.18 ns]
                        change: [-0.4311% -0.3368% -0.2455%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 18 outliers among 100 measurements (18.00%)
  2 (2.00%) low mild
  4 (4.00%) high mild
  12 (12.00%) high severe

vincenty distance f64   time:   [267.05 ns 267.05 ns 267.06 ns]
                        change: [-0.5073% -0.3750% -0.2535%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 16 outliers among 100 measurements (16.00%)
  1 (1.00%) low mild
  6 (6.00%) high mild
  9 (9.00%) high severe
</pre>
</details>


Co-authored-by: Michael Kirk <[email protected]>
  • Loading branch information
bors[bot] and michaelkirk authored May 27, 2022
2 parents c5c9ba8 + 3a8989f commit 8b701a1
Show file tree
Hide file tree
Showing 13 changed files with 313 additions and 58 deletions.
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

0 comments on commit 8b701a1

Please sign in to comment.