Skip to content

Commit

Permalink
Add ObjectRef combinator to build tree referencing objects elsewhere. (
Browse files Browse the repository at this point in the history
…#178)

- [x] I agree to follow the project's [code of
conduct](https://github.com/georust/geo/blob/master/CODE_OF_CONDUCT.md).
- [x] I added an entry to `rstar/CHANGELOG.md` if knowledge of this
change could be valuable to users.
---

As discussed in
georust/geo#1246 (comment)
  • Loading branch information
adamreichold authored Nov 3, 2024
1 parent 7634435 commit f81b9a0
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 1 deletion.
2 changes: 2 additions & 0 deletions rstar/src/primitives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
mod cached_envelope;
mod geom_with_data;
mod line;
mod object_ref;
mod point_with_data;
mod rectangle;

pub use self::cached_envelope::CachedEnvelope;
pub use self::geom_with_data::GeomWithData;
pub use self::line::Line;
pub use self::object_ref::ObjectRef;
pub use self::point_with_data::PointWithData;
pub use self::rectangle::Rectangle;
62 changes: 62 additions & 0 deletions rstar/src/primitives/object_ref.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use crate::envelope::Envelope;
use crate::object::PointDistance;
use crate::{object::RTreeObject, point::Point};
use core::ops::Deref;

/// An [RTreeObject] that is a possibly short-lived reference to another object.
///
/// Sometimes it can be useful to build an [RTree] that does not own its constituent
/// objects but references them from elsewhere. Wrapping the bare references with this
/// combinator makes this possible.
///
/// **Note:** the wrapper implements [RTreeObject] and referenced object `T` can be
/// accessed via an implementation of `Deref<Target=T>`.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ObjectRef<'a, T: RTreeObject> {
inner: &'a T,
}

impl<'a, T: RTreeObject> RTreeObject for ObjectRef<'a, T> {
type Envelope = T::Envelope;

fn envelope(&self) -> Self::Envelope {
self.inner.envelope()
}
}

impl<'a, T: PointDistance> PointDistance for ObjectRef<'a, T> {
fn distance_2(
&self,
point: &<Self::Envelope as Envelope>::Point,
) -> <<Self::Envelope as Envelope>::Point as Point>::Scalar {
self.inner.distance_2(point)
}

fn contains_point(&self, p: &<Self::Envelope as Envelope>::Point) -> bool {
self.inner.contains_point(p)
}

fn distance_2_if_less_or_equal(
&self,
point: &<Self::Envelope as Envelope>::Point,
max_distance_2: <<Self::Envelope as Envelope>::Point as Point>::Scalar,
) -> Option<<<Self::Envelope as Envelope>::Point as Point>::Scalar> {
self.inner
.distance_2_if_less_or_equal(point, max_distance_2)
}
}

impl<'a, T: RTreeObject> ObjectRef<'a, T> {
/// Create a new [ObjectRef] struct using the object.
pub fn new(inner: &'a T) -> Self {
Self { inner }
}
}

impl<'a, T: RTreeObject> Deref for ObjectRef<'a, T> {
type Target = T;

fn deref(&self) -> &Self::Target {
self.inner
}
}
2 changes: 1 addition & 1 deletion rstar/src/rtree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ where
pub fn intersection_candidates_with_other_tree<'a, U>(
&'a self,
other: &'a RTree<U>,
) -> IntersectionIterator<T, U>
) -> IntersectionIterator<'a, T, U>
where
U: RTreeObject<Envelope = T::Envelope>,
{
Expand Down

0 comments on commit f81b9a0

Please sign in to comment.