geo
geo copied to clipboard
Implement RTreeObject for Geometry enum
Fixes https://github.com/georust/geo/issues/982
Still draft as I haven't written any tests yet.
- [x] I agree to follow the project's code of conduct.
- [ ] I added an entry to
CHANGES.md
if knowledge of this change could be valuable to users.
It makes me (only a little) itchy that we now have a separate, mostly equivalent, implementation of bounding_rect for geometry in geo and now in geo_types for the RTree integration.
I had a quick go at seeing what it'd look like to share a backing implementation here, based on your branch: https://github.com/georust/geo/tree/mkirk/rtreeobject
On the one hand, that approach is not a small endeavor. On the other hand, it's nice to dedupe the implementations and also, IMO solves at least the majority of the need for new tests since the existing bounding_rect has decent testing.
It's not clear to me which is better, so if you prefer to have the duplicated implementation, I'm on board.
Whoops, I left comments on the commit rather than in the PR.
Let me know if you want me to recreate them: https://github.com/georust/geo/commit/93dce717a63382c5bc673576bd483aaed5ac72cd
I vastly prefer the shared version, so that's incorporated now. In terms of tests, I want to make sure we're testing
-
GeometryCollection
s with empty envelopes, since I think that's the only real new logic we've added. - Adding and Querying a mixture of geometries as
Geometry
enum members
1 is probably a bit trickier.
I have just realised that we also need to impl PointDistance
which has really ruined my day.
Are you sure we need to implement PointDistance for everything?
I'm AFK so can't easily verify, but I seem to recall we could get some useful functionality with only the RTreeObject impl.
Like maybe we could get "intersection candidates", but not "nearest neighbor", which still seems like useful progress.
It certainly works, but everything other than the envelope-based queries require PointDistance
. So I don't know where to go from here. I'm happy to add some more tests, write the geo_rect_to_rstar_aabb
stuff (which I think will work), but I see no easy to way to implement PointDistance
using the current crate architecture. Even re-implementing just Point-[geom] distance wholesale isn't enough because individual impls require e.g. Intersects
.
Let me know if I can help contribute to this PR as it would be very helpful.
Given https://github.com/georust/geo/pull/1029 it can be quite simple to implement PointDistance
for all geometry type such as
impl PointDistance for Geometry {
fn distance_2(
&self,
point: &<Self::Envelope as rstar::Envelope>::Point,
) -> <<Self::Envelope as rstar::Envelope>::Point as rstar::Point>::Scalar {
let pnt = geo_types::point!(geo_types::coord!{x: point[0], y: point[1]});
let d = &self.geom.euclidean_distance(&pnt);
d.powi(2)
}
}
Given #1029 it can be quite simple to implement
PointDistance
for all geometry type such asimpl PointDistance for Geometry { fn distance_2( &self, point: &<Self::Envelope as rstar::Envelope>::Point, ) -> <<Self::Envelope as rstar::Envelope>::Point as rstar::Point>::Scalar { let pnt = geo_types::point!(geo_types::coord!{x: point[0], y: point[1]}); let d = &self.geom.euclidean_distance(&pnt); d.powi(2) } }
It's been a long time, but the problem with this approach is that RTreeObject
has to be implemented in geo-types
, not geo
. That means that none of the algorithms required to calculate distance_2
are available to us: they all reside in geo
.
@urschrei thanks for explaining! Perhaps, it could be feature gated in geo_types?
It's not a feature issue, it's a circular dependency issue: there are no algorithms in geo-types
(well, there are some secret ones for internal use only) and we can't pull in any from geo
, because geo
depends on geo-types
. We've kinda painted ourselves into a corner by separating types from algorithms, and nobody is really sure how we get out of it.
Let's merge geo and geo-types back together and have the --no-default-features build be types only.