Skip to content

Commit

Permalink
apply GeoNum
Browse files Browse the repository at this point in the history
I think this will be clearer than "HasKernel".

We still often use CoordNum (things which *don't* implement HasKernel).

Do we actually care to make that distinction? Seems like it complicates
things a bit for a usecase I'm not sure exists in the wild.
  • Loading branch information
michaelkirk committed Jan 11, 2021
1 parent e58bf76 commit 48e9fae
Show file tree
Hide file tree
Showing 14 changed files with 77 additions and 87 deletions.
9 changes: 4 additions & 5 deletions geo/src/algorithm/contains/geometry.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::Contains;
use crate::kernels::*;
use crate::*;

// ┌──────────────────────────────┐
Expand All @@ -8,7 +7,7 @@ use crate::*;

impl<T> Contains<Coordinate<T>> for Geometry<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, coord: &Coordinate<T>) -> bool {
match self {
Expand All @@ -28,7 +27,7 @@ where

impl<T> Contains<Point<T>> for Geometry<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, point: &Point<T>) -> bool {
self.contains(&point.0)
Expand All @@ -41,7 +40,7 @@ where

impl<T> Contains<Coordinate<T>> for GeometryCollection<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, coord: &Coordinate<T>) -> bool {
self.iter().any(|geometry| geometry.contains(coord))
Expand All @@ -50,7 +49,7 @@ where

impl<T> Contains<Point<T>> for GeometryCollection<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, point: &Point<T>) -> bool {
self.contains(&point.0)
Expand Down
11 changes: 5 additions & 6 deletions geo/src/algorithm/contains/line.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use super::Contains;
use crate::intersects::Intersects;
use crate::kernels::*;
use crate::*;
use crate::{Coordinate, GeoNum, Line, LineString, Point};

// ┌──────────────────────────┐
// │ Implementations for Line │
// └──────────────────────────┘

impl<T> Contains<Coordinate<T>> for Line<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, coord: &Coordinate<T>) -> bool {
if self.start == self.end {
Expand All @@ -22,7 +21,7 @@ where

impl<T> Contains<Point<T>> for Line<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, p: &Point<T>) -> bool {
self.contains(&p.0)
Expand All @@ -31,7 +30,7 @@ where

impl<T> Contains<Line<T>> for Line<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, line: &Line<T>) -> bool {
if line.start == line.end {
Expand All @@ -44,7 +43,7 @@ where

impl<T> Contains<LineString<T>> for Line<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, linestring: &LineString<T>) -> bool {
// Empty linestring has no interior, and not
Expand Down
13 changes: 6 additions & 7 deletions geo/src/algorithm/contains/line_string.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use super::Contains;
use crate::kernels::*;
use crate::*;
use intersects::Intersects;
use crate::intersects::Intersects;
use crate::{CoordNum, Coordinate, GeoNum, Line, LineString, MultiLineString, Point};

// ┌────────────────────────────────┐
// │ Implementations for LineString │
// └────────────────────────────────┘

impl<T> Contains<Coordinate<T>> for LineString<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, coord: &Coordinate<T>) -> bool {
if self.0.is_empty() {
Expand All @@ -28,7 +27,7 @@ where

impl<T> Contains<Point<T>> for LineString<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, p: &Point<T>) -> bool {
self.contains(&p.0)
Expand All @@ -37,7 +36,7 @@ where

impl<T> Contains<Line<T>> for LineString<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, line: &Line<T>) -> bool {
if line.start == line.end {
Expand Down Expand Up @@ -107,7 +106,7 @@ where

impl<T> Contains<LineString<T>> for LineString<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, rhs: &LineString<T>) -> bool {
rhs.lines().all(|l| self.contains(&l))
Expand Down
13 changes: 6 additions & 7 deletions geo/src/algorithm/contains/polygon.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use super::Contains;
use crate::intersects::Intersects;
use crate::kernels::HasKernel;
use crate::{CoordNum, Coordinate, Line, LineString, MultiPolygon, Point, Polygon};
use crate::{CoordNum, Coordinate, GeoNum, Line, LineString, MultiPolygon, Point, Polygon};

// ┌─────────────────────────────┐
// │ Implementations for Polygon │
// └─────────────────────────────┘

impl<T> Contains<Coordinate<T>> for Polygon<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, coord: &Coordinate<T>) -> bool {
use crate::algorithm::coordinate_position::{CoordPos, CoordinatePosition};
Expand All @@ -20,7 +19,7 @@ where

impl<T> Contains<Point<T>> for Polygon<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, p: &Point<T>) -> bool {
self.contains(&p.0)
Expand All @@ -31,7 +30,7 @@ where
// line.start and line.end is on the boundaries
impl<T> Contains<Line<T>> for Polygon<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, line: &Line<T>) -> bool {
// both endpoints are contained in the polygon and the line
Expand All @@ -46,7 +45,7 @@ where
// TODO: also check interiors
impl<T> Contains<Polygon<T>> for Polygon<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, poly: &Polygon<T>) -> bool {
// decompose poly's exterior ring into Lines, and check each for containment
Expand All @@ -57,7 +56,7 @@ where
// TODO: ensure DE-9IM compliance
impl<T> Contains<LineString<T>> for Polygon<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, linestring: &LineString<T>) -> bool {
// All LineString points must be inside the Polygon
Expand Down
9 changes: 4 additions & 5 deletions geo/src/algorithm/contains/triangle.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
use super::Contains;
use crate::kernels::*;
use crate::*;
use crate::{Coordinate, GeoNum, LineString, Point, Triangle};

// ┌──────────────────────────────┐
// │ Implementations for Triangle │
// └──────────────────────────────┘

impl<T> Contains<Coordinate<T>> for Triangle<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, coord: &Coordinate<T>) -> bool {
let ls = LineString(vec![self.0, self.1, self.2, self.0]);
use utils::*;
use crate::utils::{coord_pos_relative_to_ring, CoordPos};
coord_pos_relative_to_ring(*coord, &ls) == CoordPos::Inside
}
}

impl<T> Contains<Point<T>> for Triangle<T>
where
T: HasKernel,
T: GeoNum,
{
fn contains(&self, point: &Point<T>) -> bool {
self.contains(&point.0)
Expand Down
7 changes: 3 additions & 4 deletions geo/src/algorithm/convex_hull/graham.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{swap_remove_to_first, trivial_hull};
use crate::algorithm::kernels::*;
use crate::{Coordinate, LineString};
use crate::{Coordinate, GeoNum, LineString};

/// The [Graham's scan] algorithm to compute the convex hull
/// of a collection of points. This algorithm is less
Expand All @@ -20,7 +20,7 @@ use crate::{Coordinate, LineString};
/// [Graham's scan]: //en.wikipedia.org/wiki/Graham_scan
pub fn graham_hull<T>(mut points: &mut [Coordinate<T>], include_on_hull: bool) -> LineString<T>
where
T: HasKernel,
T: GeoNum,
{
if points.len() < 4 {
// Nothing to build with fewer than four points.
Expand Down Expand Up @@ -89,8 +89,7 @@ where
mod test {
use super::*;
use crate::algorithm::is_convex::IsConvex;
use std::fmt::Debug;
fn test_convexity<T: HasKernel + Debug>(initial: &[(T, T)]) {
fn test_convexity<T: GeoNum>(initial: &[(T, T)]) {
let mut v: Vec<_> = initial
.iter()
.map(|e| Coordinate::from((e.0, e.1)))
Expand Down
17 changes: 8 additions & 9 deletions geo/src/algorithm/convex_hull/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::kernels::*;
use crate::*;
use crate::{Coordinate, GeoNum, LineString, MultiLineString, MultiPoint, MultiPolygon, Polygon};

/// Returns the convex hull of a Polygon. The hull is always oriented counter-clockwise.
///
Expand Down Expand Up @@ -38,13 +37,13 @@ use crate::*;
/// assert_eq!(res.exterior(), &correct_hull);
/// ```
pub trait ConvexHull {
type Scalar: CoordNum;
type Scalar: GeoNum;
fn convex_hull(&self) -> Polygon<Self::Scalar>;
}

impl<T> ConvexHull for Polygon<T>
where
T: HasKernel,
T: GeoNum,
{
type Scalar = T;
fn convex_hull(&self) -> Polygon<T> {
Expand All @@ -54,7 +53,7 @@ where

impl<T> ConvexHull for MultiPolygon<T>
where
T: HasKernel,
T: GeoNum,
{
type Scalar = T;
fn convex_hull(&self) -> Polygon<T> {
Expand All @@ -69,7 +68,7 @@ where

impl<T> ConvexHull for LineString<T>
where
T: HasKernel,
T: GeoNum,
{
type Scalar = T;
fn convex_hull(&self) -> Polygon<T> {
Expand All @@ -79,7 +78,7 @@ where

impl<T> ConvexHull for MultiLineString<T>
where
T: HasKernel,
T: GeoNum,
{
type Scalar = T;
fn convex_hull(&self) -> Polygon<T> {
Expand All @@ -90,7 +89,7 @@ where

impl<T> ConvexHull for MultiPoint<T>
where
T: HasKernel,
T: GeoNum,
{
type Scalar = T;
fn convex_hull(&self) -> Polygon<T> {
Expand All @@ -111,7 +110,7 @@ pub use graham::graham_hull;
// required.
fn trivial_hull<T>(points: &mut [Coordinate<T>], include_on_hull: bool) -> LineString<T>
where
T: HasKernel,
T: GeoNum,
{
assert!(points.len() < 4);

Expand Down
12 changes: 6 additions & 6 deletions geo/src/algorithm/convex_hull/qhull.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::{swap_remove_to_first, trivial_hull};
use crate::algorithm::kernels::*;
use crate::kernels::{HasKernel, Kernel, Orientation};
use crate::utils::partition_slice;
use crate::{Coordinate, LineString};
use crate::{Coordinate, GeoNum, LineString};

// Determines if `p_c` lies on the positive side of the
// segment `p_a` to `p_b`. In other words, whether segment
Expand All @@ -11,16 +11,16 @@ use crate::{Coordinate, LineString};
#[inline]
fn is_ccw<T>(p_a: Coordinate<T>, p_b: Coordinate<T>, p_c: Coordinate<T>) -> bool
where
T: HasKernel,
T: GeoNum,
{
let o = T::Ker::orient2d(p_a, p_b, p_c);
let o = <T as HasKernel>::Ker::orient2d(p_a, p_b, p_c);
o == Orientation::CounterClockwise
}

// Adapted from https://web.archive.org/web/20180409175413/http://www.ahristov.com/tutorial/geometry-games/convex-hull.html
pub fn quick_hull<T>(mut points: &mut [Coordinate<T>]) -> LineString<T>
where
T: HasKernel,
T: GeoNum,
{
// can't build a hull from fewer than four points
if points.len() < 4 {
Expand Down Expand Up @@ -70,7 +70,7 @@ fn hull_set<T>(
mut set: &mut [Coordinate<T>],
hull: &mut Vec<Coordinate<T>>,
) where
T: HasKernel,
T: GeoNum,
{
if set.is_empty() {
return;
Expand Down
Loading

0 comments on commit 48e9fae

Please sign in to comment.