-
Notifications
You must be signed in to change notification settings - Fork 198
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
performance for multipolygon contains much worse than for geos #1184
Comments
No, but you can decompose the multipolygon into polygons and add them to an rstar spatial index: https://docs.rs/rstar/latest/rstar/struct.RTree.html. The rtree is serializable, re-exported by geo (so it should "just work" for bulk loading the multipolygon Vec), and you can associate extra data with each polygon by using https://docs.rs/rstar/latest/rstar/primitives/struct.GeomWithData.html |
Thanks, for the tip. Do you know if that is how geos is doing it? |
A geos prepared geometry is an rtree behind the scenes, yes. So things like point in multipolygon query the tree transparently. |
I'm trying to add all my Polygons to an RTree, and then check if a point is contained by any of the polygons. But I'm getting this error:
gauteh/roaring-landmask@b8e3a21 How can I search through the Polygons and check if the point is contained? |
I think |
I wrapped the polygons and implemented contains (gauteh/roaring-landmask@60bc592) The performance is better, but still roughly 1000x worse than geos :/
|
Can you post a link to your benchmark? I just want to make sure I'm understanding everything here. |
Hi, the benchmark is here: https://github.com/gauteh/roaring-landmask/blob/685ed6f43e944a604545c452273ded4ab901ce42/src/shapes.rs#L201 You run it with: cargo bench shapes --features nightly, requires python at least 3.10. main branch is with geos, the linked PR is with geo. Thanks |
FWIW I believe a GEOS prepared geometry indexes every coordinate pair ( I think that geo will automatically build in-effect a prepared geometry before doing the intersection, but there's currently no API to allow the user to persist this. So if you're doing repeated intersections I'd expect bad performance compared to GEOS |
Thanks, that seems like something that needs to be done on geo level. It appears to have got some work, but still require some effort? |
Would it be enough to persist/cache this intermediate step? Any way to do a quick test if that makes any difference? |
You can enable serialise / deserialise support for trees by enabling the serde feature on the rstar dependency. I haven't done it myself, but it should be pretty straightforward using something like https://docs.rs/bincode/latest/bincode/ |
It's not the rstar, but what is mentioned here: #1184 (comment) . Rstar didn't help enough. |
As discussed in #803, https://github.com/georust/geo/compare/mkirk/prepared-geom?expand=1 could be a good starting point. |
Now testing out prepared geometries through #1198, is it better if I create an RTree with prepared polygons, or should I just create one prepared multipolygon? I am testing many points against all the polygons. |
Using a RTree of prepared geometries (gauteh/roaring-landmask@e413778), slightly worse:
|
I've worked on NTS, the C# port of JTS (whereas GEOS is the C++ port of JTS). Since it looks like part of this discussion focuses SPECIFICALLY on the "contains point" case, while it's true that JTS / NTS / GEOS use an R-tree for this, there's some nuance that I don't see being discussed here (it's somewhat addressed here, but it's the details of that index that make a huge difference). If I've scanned too quickly and missed it, please ignore me... For single-point tests specifically, it's NOT a typical 2-dimensional R-tree holding all the line segments. Rather, it uses a 1-dimensional "interval R-tree" of those segments. Mathematically, calculating "where is The math doesn't care which direction we choose, but there are four interesting ones: positive / negative, parallel to the x / y axis. GEOS happens to pick positive X, so I'll talk about that specifically, but it can work with any of the four. Once you commit to choosing choosing that direction, you can index all of the line segments of the (multi/)polygon using a variant of the R-tree that only looks at their min/max Y values. With that index, a query for point I hope this helps. |
Hi,
I'm trying to convert some code for roaring-landmask (https://github.com/gauteh/roaring-landmask) from geos to geo (gauteh/roaring-landmask#27). However, checking if a point is contained by a large multipolygon (with all countries from GSHHG) is far slower with geo than with geos. With geos I used
PreparedGeometry
, does something similar exist?geos:
geo:
The text was updated successfully, but these errors were encountered: