use crate::context_handle::with_context;
use crate::functions::*;
use crate::traits::as_raw_impl;
use crate::{AsRaw, GResult, Geom};
use geos_sys::*;
use std::marker::PhantomData;
use std::ptr::NonNull;
pub struct PreparedGeometry<'a> {
ptr: NonNull<GEOSPreparedGeometry>,
phantom: PhantomData<&'a ()>,
}
impl<'a> PreparedGeometry<'a> {
pub fn new<G: Geom>(g: &'a G) -> GResult<Self> {
with_context(|ctx| unsafe {
let ptr = nullcheck!(GEOSPrepare_r(ctx.as_raw(), g.as_raw()))?;
Ok(PreparedGeometry {
ptr,
phantom: PhantomData,
})
})
}
pub fn contains<G: Geom>(&self, other: &G) -> GResult<bool> {
with_context(|ctx| unsafe {
predicate!(GEOSPreparedContains_r(
ctx.as_raw(),
self.as_raw(),
other.as_raw()
))
})
}
pub fn contains_properly<G: Geom>(&self, other: &G) -> GResult<bool> {
with_context(|ctx| unsafe {
predicate!(GEOSPreparedContainsProperly_r(
ctx.as_raw(),
self.as_raw(),
other.as_raw()
))
})
}
pub fn covered_by<G: Geom>(&self, other: &G) -> GResult<bool> {
with_context(|ctx| unsafe {
predicate!(GEOSPreparedCoveredBy_r(
ctx.as_raw(),
self.as_raw(),
other.as_raw()
))
})
}
pub fn covers<G: Geom>(&self, other: &G) -> GResult<bool> {
with_context(|ctx| unsafe {
predicate!(GEOSPreparedCovers_r(
ctx.as_raw(),
self.as_raw(),
other.as_raw()
))
})
}
pub fn crosses<G: Geom>(&self, other: &G) -> GResult<bool> {
with_context(|ctx| unsafe {
predicate!(GEOSPreparedCrosses_r(
ctx.as_raw(),
self.as_raw(),
other.as_raw()
))
})
}
pub fn disjoint<G: Geom>(&self, other: &G) -> GResult<bool> {
with_context(|ctx| unsafe {
predicate!(GEOSPreparedDisjoint_r(
ctx.as_raw(),
self.as_raw(),
other.as_raw()
))
})
}
pub fn intersects<G: Geom>(&self, other: &G) -> GResult<bool> {
with_context(|ctx| unsafe {
predicate!(GEOSPreparedIntersects_r(
ctx.as_raw(),
self.as_raw(),
other.as_raw()
))
})
}
pub fn overlaps<G: Geom>(&self, other: &G) -> GResult<bool> {
with_context(|ctx| unsafe {
predicate!(GEOSPreparedOverlaps_r(
ctx.as_raw(),
self.as_raw(),
other.as_raw()
))
})
}
pub fn touches<G: Geom>(&self, other: &G) -> GResult<bool> {
with_context(|ctx| unsafe {
predicate!(GEOSPreparedTouches_r(
ctx.as_raw(),
self.as_raw(),
other.as_raw()
))
})
}
pub fn within<G: Geom>(&self, other: &G) -> GResult<bool> {
with_context(|ctx| unsafe {
predicate!(GEOSPreparedWithin_r(
ctx.as_raw(),
self.as_raw(),
other.as_raw()
))
})
}
#[cfg(feature = "v3_10_0")]
pub fn dwithin<G: Geom>(&self, other: &G, distance: f64) -> GResult<bool> {
with_context(|ctx| unsafe {
predicate!(GEOSPreparedDistanceWithin_r(
ctx.as_raw(),
self.as_raw(),
other.as_raw(),
distance
))
})
}
#[cfg(feature = "v3_12_0")]
pub fn contains_xy(&self, x: f64, y: f64) -> GResult<bool> {
with_context(|ctx| unsafe {
predicate!(GEOSPreparedContainsXY_r(ctx.as_raw(), self.as_raw(), x, y))
})
}
#[cfg(feature = "v3_12_0")]
pub fn intersects_xy(&self, x: f64, y: f64) -> GResult<bool> {
with_context(|ctx| unsafe {
predicate!(GEOSPreparedIntersectsXY_r(
ctx.as_raw(),
self.as_raw(),
x,
y
))
})
}
#[cfg(feature = "v3_9_0")]
pub fn distance<G: Geom>(&self, other: &G) -> GResult<f64> {
with_context(|ctx| unsafe {
let mut distance = 0.0;
errcheck!(GEOSPreparedDistance_r(
ctx.as_raw(),
self.as_raw(),
other.as_raw(),
&mut distance
))?;
Ok(distance)
})
}
}
unsafe impl Send for PreparedGeometry<'_> {}
unsafe impl Sync for PreparedGeometry<'_> {}
impl Drop for PreparedGeometry<'_> {
fn drop(&mut self) {
with_context(|ctx| unsafe { GEOSPreparedGeom_destroy_r(ctx.as_raw(), self.as_raw()) });
}
}
as_raw_impl!(PreparedGeometry<'_>, GEOSPreparedGeometry);
#[cfg(doctest)]
pub mod lifetime_checks {}
#[cfg(doctest)]
mod lifetime_prepared_geom_sigsegv {}