From 6280fc2a821e335a5024fec60a89c08345f90395 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 13 Apr 2024 12:47:16 -0400 Subject: [PATCH 1/8] - --- geo-types/src/geometry/coord.rs | 18 +++++-- geo-types/src/geometry/line_string.rs | 11 ++-- geo-types/src/geometry/point.rs | 75 +++++++++++++++------------ geo-types/src/lib.rs | 13 +++++ 4 files changed, 76 insertions(+), 41 deletions(-) diff --git a/geo-types/src/geometry/coord.rs b/geo-types/src/geometry/coord.rs index 08ef00bb8..c5b89b75b 100644 --- a/geo-types/src/geometry/coord.rs +++ b/geo-types/src/geometry/coord.rs @@ -1,4 +1,4 @@ -use crate::{coord, CoordNum, Point}; +use crate::{coord, geo_traits, CoordNum, Point}; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq, UlpsEq}; @@ -33,6 +33,18 @@ pub struct Coord { #[deprecated(note = "Renamed to `geo_types::Coord` (or `geo::Coord`)")] pub type Coordinate = Coord; +impl geo_traits::Coord for Coord { + type Scalar = T; + + fn x(&self) -> Self::Scalar { + self.x + } + + fn y(&self) -> Self::Scalar { + self.y + } +} + impl From<(T, T)> for Coord { #[inline] fn from(coords: (T, T)) -> Self { @@ -53,9 +65,9 @@ impl From<[T; 2]> for Coord { } } -impl From> for Coord { +impl From> for Coord { #[inline] - fn from(point: Point) -> Self { + fn from(point: Point) -> Self { coord! { x: point.x(), y: point.y(), diff --git a/geo-types/src/geometry/line_string.rs b/geo-types/src/geometry/line_string.rs index 4512b4ccc..9f1c3f992 100644 --- a/geo-types/src/geometry/line_string.rs +++ b/geo-types/src/geometry/line_string.rs @@ -6,6 +6,7 @@ use alloc::vec; use alloc::vec::Vec; use core::iter::FromIterator; use core::ops::{Index, IndexMut}; +use crate::geo_traits; /// An ordered collection of two or more [`Coord`]s, representing a /// path between locations. @@ -134,7 +135,7 @@ use core::ops::{Index, IndexMut}; #[derive(Eq, PartialEq, Clone, Debug, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct LineString(pub Vec>); +pub struct LineString>(pub Vec); /// A [`Point`] iterator returned by the `points` method #[derive(Debug)] @@ -192,20 +193,20 @@ impl<'a, T: CoordNum> DoubleEndedIterator for CoordinatesIter<'a, T> { } } -impl LineString { +impl LineString { /// Instantiate Self from the raw content value - pub fn new(value: Vec>) -> Self { + pub fn new(value: Vec) -> Self { Self(value) } /// Return an iterator yielding the coordinates of a [`LineString`] as [`Point`]s #[deprecated(note = "Use points() instead")] - pub fn points_iter(&self) -> PointsIter { + pub fn points_iter(&self) -> PointsIter { PointsIter(self.0.iter()) } /// Return an iterator yielding the coordinates of a [`LineString`] as [`Point`]s - pub fn points(&self) -> PointsIter { + pub fn points(&self) -> PointsIter { PointsIter(self.0.iter()) } diff --git a/geo-types/src/geometry/point.rs b/geo-types/src/geometry/point.rs index 7b7c7f9fd..51b7f7925 100644 --- a/geo-types/src/geometry/point.rs +++ b/geo-types/src/geometry/point.rs @@ -3,6 +3,7 @@ use crate::{point, Coord, CoordFloat, CoordNum}; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; +use crate::geo_traits; use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; /// A single point in 2D space. @@ -28,39 +29,51 @@ use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAss /// ``` #[derive(Eq, PartialEq, Clone, Copy, Debug, Hash, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct Point(pub Coord); +pub struct Point>(pub C); -impl From> for Point { - fn from(x: Coord) -> Self { +impl geo_traits::Coord for Point { + type Scalar = C::Scalar; + + fn x(&self) -> Self::Scalar { + self.0.x() + } + + fn y(&self) -> Self::Scalar { + self.0.y() + } +} + +impl From for Point { + fn from(x: C) -> Self { Point(x) } } -impl From<(T, T)> for Point { - fn from(coords: (T, T)) -> Self { +impl From<(C::Scalar, C::Scalar)> for Point { + fn from(coords: (C::Scalar, C::Scalar)) -> Self { Point::new(coords.0, coords.1) } } -impl From<[T; 2]> for Point { - fn from(coords: [T; 2]) -> Self { +impl From<[C::Scalar; 2]> for Point { + fn from(coords: [C::Scalar; 2]) -> Self { Point::new(coords[0], coords[1]) } } -impl From> for (T, T) { - fn from(point: Point) -> Self { - point.0.into() +impl From> for (C::Scalar, C::Scalar) { + fn from(point: Point) -> Self { + (point.0.x(), point.0.y()) } } -impl From> for [T; 2] { - fn from(point: Point) -> Self { - point.0.into() +impl From> for [C::Scalar; 2] { + fn from(point: Point) -> Self { + [point.0.x(), point.0.y()] } } -impl Point { +impl Point { /// Creates a new point. /// /// # Examples @@ -73,7 +86,7 @@ impl Point { /// assert_eq!(p.x(), 1.234); /// assert_eq!(p.y(), 2.345); /// ``` - pub fn new(x: T, y: T) -> Self { + pub fn new(x: C::Scalar, y: C::Scalar) -> Self { point! { x: x, y: y } } @@ -88,8 +101,8 @@ impl Point { /// /// assert_eq!(p.x(), 1.234); /// ``` - pub fn x(self) -> T { - self.0.x + pub fn x(self) -> C::Scalar { + self.0.x() } /// Sets the x/horizontal component of the point. @@ -104,7 +117,7 @@ impl Point { /// /// assert_eq!(p.x(), 9.876); /// ``` - pub fn set_x(&mut self, x: T) -> &mut Self { + pub fn set_x(&mut self, x: C::Scalar) -> &mut Self { self.0.x = x; self } @@ -121,7 +134,7 @@ impl Point { /// *p_x += 1.0; /// assert_relative_eq!(p.x(), 2.234); /// ``` - pub fn x_mut(&mut self) -> &mut T { + pub fn x_mut(&mut self) -> &mut C::Scalar { &mut self.0.x } /// Returns the y/vertical component of the point. @@ -135,7 +148,7 @@ impl Point { /// /// assert_eq!(p.y(), 2.345); /// ``` - pub fn y(self) -> T { + pub fn y(self) -> C::Scalar { self.0.y } @@ -151,7 +164,7 @@ impl Point { /// /// assert_eq!(p.y(), 9.876); /// ``` - pub fn set_y(&mut self, y: T) -> &mut Self { + pub fn set_y(&mut self, y: C::Scalar) -> &mut Self { self.0.y = y; self } @@ -168,7 +181,7 @@ impl Point { /// *p_y += 1.0; /// assert_relative_eq!(p.y(), 3.345); /// ``` - pub fn y_mut(&mut self) -> &mut T { + pub fn y_mut(&mut self) -> &mut C::Scalar { &mut self.0.y } @@ -185,7 +198,7 @@ impl Point { /// assert_eq!(y, 2.345); /// assert_eq!(x, 1.234); /// ``` - pub fn x_y(self) -> (T, T) { + pub fn x_y(self) -> (C::Scalar, C::Scalar) { (self.0.x, self.0.y) } /// Returns the longitude/horizontal component of the point. @@ -200,7 +213,7 @@ impl Point { /// assert_eq!(p.x(), 1.234); /// ``` #[deprecated = "use `Point::x` instead, it's less ambiguous"] - pub fn lng(self) -> T { + pub fn lng(self) -> C::Scalar { self.x() } @@ -218,7 +231,7 @@ impl Point { /// assert_eq!(p.x(), 9.876); /// ``` #[deprecated = "use `Point::set_x` instead, it's less ambiguous"] - pub fn set_lng(&mut self, lng: T) -> &mut Self { + pub fn set_lng(&mut self, lng: C::Scalar) -> &mut Self { self.set_x(lng) } @@ -234,7 +247,7 @@ impl Point { /// assert_eq!(p.y(), 2.345); /// ``` #[deprecated = "use `Point::y` instead, it's less ambiguous"] - pub fn lat(self) -> T { + pub fn lat(self) -> C::Scalar { self.y() } /// Sets the latitude/vertical component of the point. @@ -251,12 +264,10 @@ impl Point { /// assert_eq!(p.y(), 9.876); /// ``` #[deprecated = "use `Point::set_y` instead, it's less ambiguous"] - pub fn set_lat(&mut self, lat: T) -> &mut Self { + pub fn set_lat(&mut self, lat: C::Scalar) -> &mut Self { self.set_y(lat) } -} -impl Point { /// Returns the dot product of the two points: /// `dot = x1 * x2 + y1 * y2` /// @@ -270,7 +281,7 @@ impl Point { /// /// assert_eq!(dot, 5.25); /// ``` - pub fn dot(self, other: Self) -> T { + pub fn dot(self, other: Self) -> C::Scalar { self.x() * other.x() + self.y() * other.y() } @@ -299,13 +310,11 @@ impl Point { /// /// assert_eq!(cross, 2.0) /// ``` - pub fn cross_prod(self, point_b: Self, point_c: Self) -> T { + pub fn cross_prod(self, point_b: Self, point_c: Self) -> C::Scalar { (point_b.x() - self.x()) * (point_c.y() - self.y()) - (point_b.y() - self.y()) * (point_c.x() - self.x()) } -} -impl Point { /// Converts the (x,y) components of Point to degrees /// /// # Example diff --git a/geo-types/src/lib.rs b/geo-types/src/lib.rs index 00e4a6ecc..14e77366d 100644 --- a/geo-types/src/lib.rs +++ b/geo-types/src/lib.rs @@ -137,6 +137,19 @@ mod wkt_macro; #[cfg(feature = "arbitrary")] mod arbitrary; +pub mod geo_traits { + pub trait Coord { + type Scalar: crate::CoordNum; + + fn x(&self) -> Self::Scalar; + fn y(&self) -> Self::Scalar; + + fn x_y(&self) -> (Self::Scalar, Self::Scalar) { + (self.x(), self.y()) + } + } +} + #[cfg(any( feature = "rstar_0_8", feature = "rstar_0_9", From ff68acbe60c51c1c3688b9c5aed918bcba018c8e Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sun, 21 Apr 2024 20:45:09 -0400 Subject: [PATCH 2/8] - --- geo-types/src/geometry/line.rs | 39 +++++++-------- geo-types/src/geometry/line_string.rs | 36 ++++++++------ geo-types/src/geometry/point.rs | 68 ++++++++++++++------------- geo-types/src/geometry/triangle.rs | 19 ++++---- geo-types/src/lib.rs | 4 +- 5 files changed, 90 insertions(+), 76 deletions(-) diff --git a/geo-types/src/geometry/line.rs b/geo-types/src/geometry/line.rs index d9435ee34..f3f397f93 100644 --- a/geo-types/src/geometry/line.rs +++ b/geo-types/src/geometry/line.rs @@ -1,3 +1,4 @@ +use crate::geo_traits; use crate::{Coord, CoordNum, Point}; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; @@ -11,12 +12,12 @@ use approx::{AbsDiffEq, RelativeEq}; /// `LineString` with the two end points. #[derive(Eq, PartialEq, Clone, Copy, Debug, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct Line { - pub start: Coord, - pub end: Coord, +pub struct Line> { + pub start: C, + pub end: C, } -impl Line { +impl Line { /// Creates a new line segment. /// /// # Examples @@ -29,9 +30,9 @@ impl Line { /// assert_eq!(line.start, coord! { x: 0., y: 0. }); /// assert_eq!(line.end, coord! { x: 1., y: 2. }); /// ``` - pub fn new(start: C, end: C) -> Self + pub fn new(start: I, end: I) -> Self where - C: Into>, + I: Into, { Self { start: start.into(), @@ -40,7 +41,7 @@ impl Line { } /// Calculate the difference in coordinates (Δx, Δy). - pub fn delta(&self) -> Coord { + pub fn delta(&self) -> C { self.end - self.start } @@ -59,8 +60,8 @@ impl Line { /// line.end.x - line.start.x /// # ); /// ``` - pub fn dx(&self) -> T { - self.delta().x + pub fn dx(&self) -> C::Scalar { + self.delta().x() } /// Calculate the difference in ‘y’ components (Δy). @@ -78,8 +79,8 @@ impl Line { /// line.end.y - line.start.y /// # ); /// ``` - pub fn dy(&self) -> T { - self.delta().y + pub fn dy(&self) -> C::Scalar { + self.delta().y() } /// Calculate the slope (Δy/Δx). @@ -108,7 +109,7 @@ impl Line { /// Line::new(a, b).slope() == Line::new(b, a).slope() /// # ); /// ``` - pub fn slope(&self) -> T { + pub fn slope(&self) -> C::Scalar { self.dy() / self.dx() } @@ -138,25 +139,25 @@ impl Line { /// Line::new(a, b).determinant() == -Line::new(b, a).determinant() /// # ); /// ``` - pub fn determinant(&self) -> T { - self.start.x * self.end.y - self.start.y * self.end.x + pub fn determinant(&self) -> C::Scalar { + self.start.x() * self.end.y() - self.start.y() * self.end.x() } - pub fn start_point(&self) -> Point { + pub fn start_point(&self) -> Point { Point::from(self.start) } - pub fn end_point(&self) -> Point { + pub fn end_point(&self) -> Point { Point::from(self.end) } - pub fn points(&self) -> (Point, Point) { + pub fn points(&self) -> (Point, Point) { (self.start_point(), self.end_point()) } } -impl From<[(T, T); 2]> for Line { - fn from(coord: [(T, T); 2]) -> Self { +impl From<[(C::Scalar, C::Scalar); 2]> for Line { + fn from(coord: [(C::Scalar, C::Scalar); 2]) -> Self { Line::new(coord[0], coord[1]) } } diff --git a/geo-types/src/geometry/line_string.rs b/geo-types/src/geometry/line_string.rs index 9f1c3f992..cdf5d4c85 100644 --- a/geo-types/src/geometry/line_string.rs +++ b/geo-types/src/geometry/line_string.rs @@ -2,11 +2,12 @@ use approx::{AbsDiffEq, RelativeEq}; use crate::{Coord, CoordNum, Line, Point, Triangle}; +use crate::geo_traits; use alloc::vec; use alloc::vec::Vec; use core::iter::FromIterator; use core::ops::{Index, IndexMut}; -use crate::geo_traits; +use std::fmt; /// An ordered collection of two or more [`Coord`]s, representing a /// path between locations. @@ -138,14 +139,19 @@ use crate::geo_traits; pub struct LineString>(pub Vec); /// A [`Point`] iterator returned by the `points` method -#[derive(Debug)] -pub struct PointsIter<'a, T: CoordNum + 'a>(::core::slice::Iter<'a, Coord>); +pub struct PointsIter<'a, C: geo_traits::Coord + 'a>(::core::slice::Iter<'a, C>); + +impl<'a, C: fmt::Debug + geo_traits::Coord + 'a> fmt::Debug for PointsIter<'a, C> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("PointsIter").field(&self.0.fmt(f)).finish() + } +} -impl<'a, T: CoordNum> Iterator for PointsIter<'a, T> { - type Item = Point; +impl<'a, C: geo_traits::Coord + 'a> Iterator for PointsIter<'a, C> { + type Item = C; fn next(&mut self) -> Option { - self.0.next().map(|c| Point::from(*c)) + self.0.next().map(|c| C::from(c.clone())) } fn size_hint(&self) -> (usize, Option) { @@ -153,15 +159,15 @@ impl<'a, T: CoordNum> Iterator for PointsIter<'a, T> { } } -impl<'a, T: CoordNum> ExactSizeIterator for PointsIter<'a, T> { +impl<'a, C: geo_traits::Coord + 'a> ExactSizeIterator for PointsIter<'a, C> { fn len(&self) -> usize { self.0.len() } } -impl<'a, T: CoordNum> DoubleEndedIterator for PointsIter<'a, T> { +impl<'a, C: geo_traits::Coord + 'a> DoubleEndedIterator for PointsIter<'a, C> { fn next_back(&mut self) -> Option { - self.0.next_back().map(|c| Point::from(*c)) + self.0.next_back().map(|c| c.clone()) } } @@ -211,22 +217,22 @@ impl LineString { } /// Return an iterator yielding the members of a [`LineString`] as [`Coord`]s - pub fn coords(&self) -> impl DoubleEndedIterator> { + pub fn coords(&self) -> impl DoubleEndedIterator { self.0.iter() } /// Return an iterator yielding the coordinates of a [`LineString`] as mutable [`Coord`]s - pub fn coords_mut(&mut self) -> impl DoubleEndedIterator> { + pub fn coords_mut(&mut self) -> impl DoubleEndedIterator { self.0.iter_mut() } /// Return the coordinates of a [`LineString`] as a [`Vec`] of [`Point`]s - pub fn into_points(self) -> Vec> { + pub fn into_points(self) -> Vec> { self.0.into_iter().map(Point::from).collect() } /// Return the coordinates of a [`LineString`] as a [`Vec`] of [`Coord`]s - pub fn into_inner(self) -> Vec> { + pub fn into_inner(self) -> Vec { self.0 } @@ -258,7 +264,7 @@ impl LineString { /// ); /// assert!(lines.next().is_none()); /// ``` - pub fn lines(&'_ self) -> impl ExactSizeIterator> + '_ { + pub fn lines(&'_ self) -> impl ExactSizeIterator> + '_ { self.0.windows(2).map(|w| { // slice::windows(N) is guaranteed to yield a slice with exactly N elements unsafe { Line::new(*w.get_unchecked(0), *w.get_unchecked(1)) } @@ -266,7 +272,7 @@ impl LineString { } /// An iterator which yields the coordinates of a [`LineString`] as [Triangle]s - pub fn triangles(&'_ self) -> impl ExactSizeIterator> + '_ { + pub fn triangles(&'_ self) -> impl ExactSizeIterator> + '_ { self.0.windows(3).map(|w| { // slice::windows(N) is guaranteed to yield a slice with exactly N elements unsafe { diff --git a/geo-types/src/geometry/point.rs b/geo-types/src/geometry/point.rs index 51b7f7925..28a389ef0 100644 --- a/geo-types/src/geometry/point.rs +++ b/geo-types/src/geometry/point.rs @@ -1,9 +1,9 @@ use crate::{point, Coord, CoordFloat, CoordNum}; +use crate::geo_traits; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; -use crate::geo_traits; use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; /// A single point in 2D space. @@ -29,10 +29,10 @@ use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAss /// ``` #[derive(Eq, PartialEq, Clone, Copy, Debug, Hash, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct Point>(pub C); +pub struct Point(pub Coord); -impl geo_traits::Coord for Point { - type Scalar = C::Scalar; +impl geo_traits::Coord for Point { + type Scalar = T; fn x(&self) -> Self::Scalar { self.0.x() @@ -43,37 +43,37 @@ impl geo_traits::Coord for Point { } } -impl From for Point { - fn from(x: C) -> Self { +impl From> for Point { + fn from(x: Coord) -> Self { Point(x) } } -impl From<(C::Scalar, C::Scalar)> for Point { - fn from(coords: (C::Scalar, C::Scalar)) -> Self { +impl From<(T, T)> for Point { + fn from(coords: (T, T)) -> Self { Point::new(coords.0, coords.1) } } -impl From<[C::Scalar; 2]> for Point { - fn from(coords: [C::Scalar; 2]) -> Self { +impl From<[T; 2]> for Point { + fn from(coords: [T; 2]) -> Self { Point::new(coords[0], coords[1]) } } -impl From> for (C::Scalar, C::Scalar) { - fn from(point: Point) -> Self { - (point.0.x(), point.0.y()) +impl From> for (T, T) { + fn from(point: Point) -> Self { + point.0.into() } } -impl From> for [C::Scalar; 2] { - fn from(point: Point) -> Self { - [point.0.x(), point.0.y()] +impl From> for [T; 2] { + fn from(point: Point) -> Self { + point.0.into() } } -impl Point { +impl Point { /// Creates a new point. /// /// # Examples @@ -86,7 +86,7 @@ impl Point { /// assert_eq!(p.x(), 1.234); /// assert_eq!(p.y(), 2.345); /// ``` - pub fn new(x: C::Scalar, y: C::Scalar) -> Self { + pub fn new(x: T, y: T) -> Self { point! { x: x, y: y } } @@ -101,8 +101,8 @@ impl Point { /// /// assert_eq!(p.x(), 1.234); /// ``` - pub fn x(self) -> C::Scalar { - self.0.x() + pub fn x(self) -> T { + self.0.x } /// Sets the x/horizontal component of the point. @@ -117,7 +117,7 @@ impl Point { /// /// assert_eq!(p.x(), 9.876); /// ``` - pub fn set_x(&mut self, x: C::Scalar) -> &mut Self { + pub fn set_x(&mut self, x: T) -> &mut Self { self.0.x = x; self } @@ -134,7 +134,7 @@ impl Point { /// *p_x += 1.0; /// assert_relative_eq!(p.x(), 2.234); /// ``` - pub fn x_mut(&mut self) -> &mut C::Scalar { + pub fn x_mut(&mut self) -> &mut T { &mut self.0.x } /// Returns the y/vertical component of the point. @@ -148,7 +148,7 @@ impl Point { /// /// assert_eq!(p.y(), 2.345); /// ``` - pub fn y(self) -> C::Scalar { + pub fn y(self) -> T { self.0.y } @@ -164,7 +164,7 @@ impl Point { /// /// assert_eq!(p.y(), 9.876); /// ``` - pub fn set_y(&mut self, y: C::Scalar) -> &mut Self { + pub fn set_y(&mut self, y: T) -> &mut Self { self.0.y = y; self } @@ -181,7 +181,7 @@ impl Point { /// *p_y += 1.0; /// assert_relative_eq!(p.y(), 3.345); /// ``` - pub fn y_mut(&mut self) -> &mut C::Scalar { + pub fn y_mut(&mut self) -> &mut T { &mut self.0.y } @@ -198,7 +198,7 @@ impl Point { /// assert_eq!(y, 2.345); /// assert_eq!(x, 1.234); /// ``` - pub fn x_y(self) -> (C::Scalar, C::Scalar) { + pub fn x_y(self) -> (T, T) { (self.0.x, self.0.y) } /// Returns the longitude/horizontal component of the point. @@ -213,7 +213,7 @@ impl Point { /// assert_eq!(p.x(), 1.234); /// ``` #[deprecated = "use `Point::x` instead, it's less ambiguous"] - pub fn lng(self) -> C::Scalar { + pub fn lng(self) -> T { self.x() } @@ -231,7 +231,7 @@ impl Point { /// assert_eq!(p.x(), 9.876); /// ``` #[deprecated = "use `Point::set_x` instead, it's less ambiguous"] - pub fn set_lng(&mut self, lng: C::Scalar) -> &mut Self { + pub fn set_lng(&mut self, lng: T) -> &mut Self { self.set_x(lng) } @@ -247,7 +247,7 @@ impl Point { /// assert_eq!(p.y(), 2.345); /// ``` #[deprecated = "use `Point::y` instead, it's less ambiguous"] - pub fn lat(self) -> C::Scalar { + pub fn lat(self) -> T { self.y() } /// Sets the latitude/vertical component of the point. @@ -264,10 +264,12 @@ impl Point { /// assert_eq!(p.y(), 9.876); /// ``` #[deprecated = "use `Point::set_y` instead, it's less ambiguous"] - pub fn set_lat(&mut self, lat: C::Scalar) -> &mut Self { + pub fn set_lat(&mut self, lat: T) -> &mut Self { self.set_y(lat) } +} +impl Point { /// Returns the dot product of the two points: /// `dot = x1 * x2 + y1 * y2` /// @@ -281,7 +283,7 @@ impl Point { /// /// assert_eq!(dot, 5.25); /// ``` - pub fn dot(self, other: Self) -> C::Scalar { + pub fn dot(self, other: Self) -> T { self.x() * other.x() + self.y() * other.y() } @@ -310,11 +312,13 @@ impl Point { /// /// assert_eq!(cross, 2.0) /// ``` - pub fn cross_prod(self, point_b: Self, point_c: Self) -> C::Scalar { + pub fn cross_prod(self, point_b: Self, point_c: Self) -> T { (point_b.x() - self.x()) * (point_c.y() - self.y()) - (point_b.y() - self.y()) * (point_c.x() - self.x()) } +} +impl Point { /// Converts the (x,y) components of Point to degrees /// /// # Example diff --git a/geo-types/src/geometry/triangle.rs b/geo-types/src/geometry/triangle.rs index 831e57cb1..2883e0163 100644 --- a/geo-types/src/geometry/triangle.rs +++ b/geo-types/src/geometry/triangle.rs @@ -1,4 +1,5 @@ use crate::{polygon, Coord, CoordNum, Line, Polygon}; +use crate::geo_traits; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; @@ -9,19 +10,19 @@ use approx::{AbsDiffEq, RelativeEq}; /// vertices must not be collinear and they must be distinct. #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct Triangle(pub Coord, pub Coord, pub Coord); +pub struct Triangle>(pub C, pub C, pub C); -impl Triangle { +impl Triangle { /// Instantiate Self from the raw content value - pub fn new(v1: Coord, v2: Coord, v3: Coord) -> Self { + pub fn new(v1: C, v2: C, v3: C) -> Self { Self(v1, v2, v3) } - pub fn to_array(&self) -> [Coord; 3] { + pub fn to_array(&self) -> [C; 3] { [self.0, self.1, self.2] } - pub fn to_lines(&self) -> [Line; 3] { + pub fn to_lines(&self) -> [Line; 3] { [ Line::new(self.0, self.1), Line::new(self.1, self.2), @@ -57,20 +58,20 @@ impl Triangle { } } -impl> + Copy, T: CoordNum> From<[IC; 3]> for Triangle { +impl + Copy> From<[IC; 3]> for Triangle { fn from(array: [IC; 3]) -> Self { Self(array[0].into(), array[1].into(), array[2].into()) } } #[cfg(any(feature = "approx", test))] -impl RelativeEq for Triangle +impl RelativeEq for Triangle where - T: AbsDiffEq + CoordNum + RelativeEq, + C::Scalar: AbsDiffEq + CoordNum + RelativeEq, { #[inline] fn default_max_relative() -> Self::Epsilon { - T::default_max_relative() + C::default_max_relative() } /// Equality assertion within a relative limit. diff --git a/geo-types/src/lib.rs b/geo-types/src/lib.rs index 14e77366d..f4e402e10 100644 --- a/geo-types/src/lib.rs +++ b/geo-types/src/lib.rs @@ -138,7 +138,9 @@ mod wkt_macro; mod arbitrary; pub mod geo_traits { - pub trait Coord { + use std::fmt; + + pub trait Coord: Clone + Copy + fmt::Debug { type Scalar: crate::CoordNum; fn x(&self) -> Self::Scalar; From 4052bc927b5bc76716be84362f694c83892096c1 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 22 Apr 2024 00:40:24 -0400 Subject: [PATCH 3/8] - --- geo-types/src/geometry/line.rs | 5 +- geo-types/src/geometry/line_string.rs | 85 +++++++++--------- geo-types/src/geometry/rect.rs | 123 ++++++++++++-------------- geo-types/src/lib.rs | 6 +- geo-types/src/private_utils.rs | 64 ++++++++------ 5 files changed, 141 insertions(+), 142 deletions(-) diff --git a/geo-types/src/geometry/line.rs b/geo-types/src/geometry/line.rs index f3f397f93..331ee733d 100644 --- a/geo-types/src/geometry/line.rs +++ b/geo-types/src/geometry/line.rs @@ -30,10 +30,7 @@ impl Line { /// assert_eq!(line.start, coord! { x: 0., y: 0. }); /// assert_eq!(line.end, coord! { x: 1., y: 2. }); /// ``` - pub fn new(start: I, end: I) -> Self - where - I: Into, - { + pub fn new(start: impl Into, end: impl Into) -> Self { Self { start: start.into(), end: end.into(), diff --git a/geo-types/src/geometry/line_string.rs b/geo-types/src/geometry/line_string.rs index cdf5d4c85..1d02d89b0 100644 --- a/geo-types/src/geometry/line_string.rs +++ b/geo-types/src/geometry/line_string.rs @@ -1,8 +1,8 @@ #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; -use crate::{Coord, CoordNum, Line, Point, Triangle}; use crate::geo_traits; +use crate::{Coord, CoordNum, Line, Point, Triangle}; use alloc::vec; use alloc::vec::Vec; use core::iter::FromIterator; @@ -143,7 +143,8 @@ pub struct PointsIter<'a, C: geo_traits::Coord + 'a>(::core::slice::Iter<'a, C>) impl<'a, C: fmt::Debug + geo_traits::Coord + 'a> fmt::Debug for PointsIter<'a, C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_tuple("PointsIter").field(&self.0.fmt(f)).finish() + let formatted = self.0.fmt(f); + f.debug_tuple("PointsIter").field(&formatted).finish() } } @@ -173,10 +174,10 @@ impl<'a, C: geo_traits::Coord + 'a> DoubleEndedIterator for PointsIter<'a, C> { /// A [`Coord`] iterator used by the `into_iter` method on a [`LineString`] #[derive(Debug)] -pub struct CoordinatesIter<'a, T: CoordNum + 'a>(::core::slice::Iter<'a, Coord>); +pub struct CoordinatesIter<'a, C: geo_traits::Coord + 'a>(::core::slice::Iter<'a, C>); -impl<'a, T: CoordNum> Iterator for CoordinatesIter<'a, T> { - type Item = &'a Coord; +impl<'a, C: geo_traits::Coord> Iterator for CoordinatesIter<'a, C> { + type Item = &'a C; fn next(&mut self) -> Option { self.0.next() @@ -187,13 +188,13 @@ impl<'a, T: CoordNum> Iterator for CoordinatesIter<'a, T> { } } -impl<'a, T: CoordNum> ExactSizeIterator for CoordinatesIter<'a, T> { +impl<'a, C: geo_traits::Coord> ExactSizeIterator for CoordinatesIter<'a, C> { fn len(&self) -> usize { self.0.len() } } -impl<'a, T: CoordNum> DoubleEndedIterator for CoordinatesIter<'a, T> { +impl<'a, C: geo_traits::Coord> DoubleEndedIterator for CoordinatesIter<'a, C> { fn next_back(&mut self) -> Option { self.0.next_back() } @@ -351,14 +352,14 @@ impl>> From> for LineString { } } -impl From> for LineString { - fn from(line: Line) -> Self { +impl From> for LineString { + fn from(line: Line) -> Self { LineString::from(&line) } } -impl From<&Line> for LineString { - fn from(line: &Line) -> Self { +impl From<&Line> for LineString { + fn from(line: &Line) -> Self { Self(vec![line.start, line.end]) } } @@ -371,18 +372,18 @@ impl>> FromIterator for LineString { } /// Iterate over all the [`Coord`]s in this [`LineString`]. -impl IntoIterator for LineString { - type Item = Coord; - type IntoIter = ::alloc::vec::IntoIter>; +impl IntoIterator for LineString { + type Item = C; + type IntoIter = ::alloc::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.0.into_iter() } } -impl<'a, T: CoordNum> IntoIterator for &'a LineString { - type Item = &'a Coord; - type IntoIter = CoordinatesIter<'a, T>; +impl<'a, C: geo_traits::Coord> IntoIterator for &'a LineString { + type Item = &'a C; + type IntoIter = CoordinatesIter<'a, C>; fn into_iter(self) -> Self::IntoIter { CoordinatesIter(self.0.iter()) @@ -390,33 +391,33 @@ impl<'a, T: CoordNum> IntoIterator for &'a LineString { } /// Mutably iterate over all the [`Coord`]s in this [`LineString`] -impl<'a, T: CoordNum> IntoIterator for &'a mut LineString { - type Item = &'a mut Coord; - type IntoIter = ::core::slice::IterMut<'a, Coord>; +impl<'a, C: geo_traits::Coord> IntoIterator for &'a mut LineString { + type Item = &'a mut C; + type IntoIter = ::core::slice::IterMut<'a, C>; - fn into_iter(self) -> ::core::slice::IterMut<'a, Coord> { + fn into_iter(self) -> ::core::slice::IterMut<'a, C> { self.0.iter_mut() } } -impl Index for LineString { - type Output = Coord; +impl Index for LineString { + type Output = C; - fn index(&self, index: usize) -> &Coord { + fn index(&self, index: usize) -> &C { self.0.index(index) } } -impl IndexMut for LineString { - fn index_mut(&mut self, index: usize) -> &mut Coord { +impl IndexMut for LineString { + fn index_mut(&mut self, index: usize) -> &mut C { self.0.index_mut(index) } } #[cfg(any(feature = "approx", test))] -impl RelativeEq for LineString +impl RelativeEq for LineString where - T: AbsDiffEq + CoordNum + RelativeEq, + C::Scalar: AbsDiffEq + CoordNum + RelativeEq, { #[inline] fn default_max_relative() -> Self::Epsilon { @@ -502,11 +503,11 @@ impl + CoordNum> AbsDiffEq for LineString { ))] macro_rules! impl_rstar_line_string { ($rstar:ident) => { - impl ::$rstar::RTreeObject for LineString + impl ::$rstar::RTreeObject for LineString where - T: ::num_traits::Float + ::$rstar::RTreeNum, + ::Scalar: ::num_traits::Float + ::$rstar::RTreeNum, { - type Envelope = ::$rstar::AABB>; + type Envelope = ::$rstar::AABB; fn envelope(&self) -> Self::Envelope { use num_traits::Bounded; @@ -524,7 +525,7 @@ macro_rules! impl_rstar_line_string { } } - impl ::$rstar::PointDistance for LineString + impl ::$rstar::PointDistance for LineString where T: ::num_traits::Float + ::$rstar::RTreeNum, { @@ -581,26 +582,26 @@ mod test { let delta = 1e-6; let coords = vec![(0., 0.), (5., 0.), (10., 10.)]; - let ls: LineString = coords.into_iter().collect(); + let ls: LineString = coords.into_iter().collect(); let coords_x = vec![(0., 0.), (5. + delta, 0.), (10., 10.)]; - let ls_x: LineString = coords_x.into_iter().collect(); + let ls_x: LineString = coords_x.into_iter().collect(); assert!(ls.abs_diff_eq(&ls_x, 1e-2)); assert!(ls.abs_diff_ne(&ls_x, 1e-12)); let coords_y = vec![(0., 0.), (5., 0. + delta), (10., 10.)]; - let ls_y: LineString = coords_y.into_iter().collect(); + let ls_y: LineString = coords_y.into_iter().collect(); assert!(ls.abs_diff_eq(&ls_y, 1e-2)); assert!(ls.abs_diff_ne(&ls_y, 1e-12)); // Undersized, but otherwise equal. let coords_x = vec![(0., 0.), (5., 0.)]; - let ls_under: LineString = coords_x.into_iter().collect(); + let ls_under: LineString = coords_x.into_iter().collect(); assert!(ls.abs_diff_ne(&ls_under, 1.)); // Oversized, but otherwise equal. let coords_x = vec![(0., 0.), (5., 0.), (10., 10.), (10., 100.)]; - let ls_oversized: LineString = coords_x.into_iter().collect(); + let ls_oversized: LineString = coords_x.into_iter().collect(); assert!(ls.abs_diff_ne(&ls_oversized, 1.)); } @@ -609,26 +610,26 @@ mod test { let delta = 1e-6; let coords = vec![(0., 0.), (5., 0.), (10., 10.)]; - let ls: LineString = coords.into_iter().collect(); + let ls: LineString = coords.into_iter().collect(); let coords_x = vec![(0., 0.), (5. + delta, 0.), (10., 10.)]; - let ls_x: LineString = coords_x.into_iter().collect(); + let ls_x: LineString = coords_x.into_iter().collect(); assert!(ls.relative_eq(&ls_x, 1e-2, 1e-2)); assert!(ls.relative_ne(&ls_x, 1e-12, 1e-12)); let coords_y = vec![(0., 0.), (5., 0. + delta), (10., 10.)]; - let ls_y: LineString = coords_y.into_iter().collect(); + let ls_y: LineString = coords_y.into_iter().collect(); assert!(ls.relative_eq(&ls_y, 1e-2, 1e-2)); assert!(ls.relative_ne(&ls_y, 1e-12, 1e-12)); // Undersized, but otherwise equal. let coords_x = vec![(0., 0.), (5., 0.)]; - let ls_under: LineString = coords_x.into_iter().collect(); + let ls_under: LineString = coords_x.into_iter().collect(); assert!(ls.relative_ne(&ls_under, 1., 1.)); // Oversized, but otherwise equal. let coords_x = vec![(0., 0.), (5., 0.), (10., 10.), (10., 100.)]; - let ls_oversized: LineString = coords_x.into_iter().collect(); + let ls_oversized: LineString = coords_x.into_iter().collect(); assert!(ls.relative_ne(&ls_oversized, 1., 1.)); } diff --git a/geo-types/src/geometry/rect.rs b/geo-types/src/geometry/rect.rs index 9d8a7b77d..cad6a04eb 100644 --- a/geo-types/src/geometry/rect.rs +++ b/geo-types/src/geometry/rect.rs @@ -1,4 +1,6 @@ +use crate::geo_traits; use crate::{coord, polygon, Coord, CoordFloat, CoordNum, Line, Polygon}; +use num_traits::One; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; @@ -39,12 +41,12 @@ use approx::{AbsDiffEq, RelativeEq}; /// ``` #[derive(Eq, PartialEq, Clone, Copy, Debug, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct Rect { - min: Coord, - max: Coord, +pub struct Rect { + min: C, + max: C, } -impl Rect { +impl Rect { /// Creates a new rectangle from two corner coordinates. /// /// # Examples @@ -59,21 +61,18 @@ impl Rect { /// assert_eq!(rect.min(), coord! { x: 10., y: 10. }); /// assert_eq!(rect.max(), coord! { x: 30., y: 20. }); /// ``` - pub fn new(c1: C, c2: C) -> Self - where - C: Into>, - { + pub fn new(c1: impl Into, c2: impl Into) -> Self { let c1 = c1.into(); let c2 = c2.into(); - let (min_x, max_x) = if c1.x < c2.x { - (c1.x, c2.x) + let (min_x, max_x) = if c1.x() < c2.x() { + (c1.x(), c2.x()) } else { - (c2.x, c1.x) + (c2.x(), c1.x()) }; - let (min_y, max_y) = if c1.y < c2.y { - (c1.y, c2.y) + let (min_y, max_y) = if c1.y() < c2.y() { + (c1.y(), c2.y()) } else { - (c2.y, c1.y) + (c2.y(), c1.y()) }; Self { min: coord! { x: min_x, y: min_y }, @@ -86,10 +85,10 @@ impl Rect { note = "Use `Rect::new` instead, since `Rect::try_new` will never Error" )] #[allow(deprecated)] - pub fn try_new(c1: C, c2: C) -> Result, InvalidRectCoordinatesError> - where - C: Into>, - { + pub fn try_new( + c1: impl Into, + c2: impl Into, + ) -> Result, InvalidRectCoordinatesError> { Ok(Rect::new(c1, c2)) } @@ -107,7 +106,7 @@ impl Rect { /// /// assert_eq!(rect.min(), coord! { x: 5., y: 5. }); /// ``` - pub fn min(self) -> Coord { + pub fn min(self) -> C { self.min } @@ -116,10 +115,7 @@ impl Rect { /// # Panics /// /// Panics if `min`’s x/y is greater than the maximum coordinate’s x/y. - pub fn set_min(&mut self, min: C) - where - C: Into>, - { + pub fn set_min(&mut self, min: impl Into) { self.min = min.into(); self.assert_valid_bounds(); } @@ -138,7 +134,7 @@ impl Rect { /// /// assert_eq!(rect.max(), coord! { x: 15., y: 15. }); /// ``` - pub fn max(self) -> Coord { + pub fn max(self) -> C { self.max } @@ -147,10 +143,7 @@ impl Rect { /// # Panics /// /// Panics if `max`’s x/y is less than the minimum coordinate’s x/y. - pub fn set_max(&mut self, max: C) - where - C: Into>, - { + pub fn set_max(&mut self, max: impl Into) { self.max = max.into(); self.assert_valid_bounds(); } @@ -169,8 +162,8 @@ impl Rect { /// /// assert_eq!(rect.width(), 10.); /// ``` - pub fn width(self) -> T { - self.max().x - self.min().x + pub fn width(self) -> C::Scalar { + self.max().x() - self.min().x() } /// Returns the height of the `Rect`. @@ -187,8 +180,8 @@ impl Rect { /// /// assert_eq!(rect.height(), 10.); /// ``` - pub fn height(self) -> T { - self.max().y - self.min().y + pub fn height(self) -> C::Scalar { + self.max().y() - self.min().y() } /// Create a `Polygon` from the `Rect`. @@ -214,56 +207,56 @@ impl Rect { /// ], /// ); /// ``` - pub fn to_polygon(self) -> Polygon { + pub fn to_polygon(self) -> Polygon { polygon![ - (x: self.min.x, y: self.min.y), - (x: self.min.x, y: self.max.y), - (x: self.max.x, y: self.max.y), - (x: self.max.x, y: self.min.y), - (x: self.min.x, y: self.min.y), + (x: self.min.x(), y: self.min.y()), + (x: self.min.x(), y: self.max.y()), + (x: self.max.x(), y: self.max.y()), + (x: self.max.x(), y: self.min.y()), + (x: self.min.x(), y: self.min.y()), ] } - pub fn to_lines(&self) -> [Line; 4] { + pub fn to_lines(&self) -> [Line; 4] { [ Line::new( coord! { - x: self.min.x, - y: self.min.y, + x: self.min.x(), + y: self.min.y(), }, coord! { - x: self.min.x, - y: self.max.y, + x: self.min.x(), + y: self.max.y(), }, ), Line::new( coord! { - x: self.min.x, - y: self.max.y, + x: self.min.x(), + y: self.max.y(), }, coord! { - x: self.max.x, - y: self.max.y, + x: self.max.x(), + y: self.max.y(), }, ), Line::new( coord! { - x: self.max.x, - y: self.max.y, + x: self.max.x(), + y: self.max.y(), }, coord! { - x: self.max.x, - y: self.min.y, + x: self.max.x(), + y: self.min.y(), }, ), Line::new( coord! { - x: self.max.x, - y: self.min.y, + x: self.max.x(), + y: self.min.y(), }, coord! { - x: self.min.x, - y: self.min.y, + x: self.min.x(), + y: self.min.y(), }, ), ] @@ -296,11 +289,11 @@ impl Rect { /// rect2, /// ); /// ``` - pub fn split_x(self) -> [Rect; 2] { - let two = T::one() + T::one(); - let mid_x = self.min().x + self.width() / two; + pub fn split_x(self) -> [Rect; 2] { + let two = C::Scalar::one() + C::Scalar::one(); + let mid_x = self.min().x() + self.width() / two; [ - Rect::new(self.min(), coord! { x: mid_x, y: self.max().y }), + Rect::new(self.min(), coord! { x: mid_x, y: self.max().y() }), Rect::new(coord! { x: mid_x, y: self.min().y }, self.max()), ] } @@ -485,28 +478,28 @@ mod test { #[test] fn rect() { - let rect = Rect::new((10, 10), (20, 20)); + let rect = Rect::>::new((10, 10), (20, 20)); assert_eq!(rect.min, coord! { x: 10, y: 10 }); assert_eq!(rect.max, coord! { x: 20, y: 20 }); - let rect = Rect::new((20, 20), (10, 10)); + let rect = Rect::>::new((20, 20), (10, 10)); assert_eq!(rect.min, coord! { x: 10, y: 10 }); assert_eq!(rect.max, coord! { x: 20, y: 20 }); - let rect = Rect::new((10, 20), (20, 10)); + let rect = Rect::>::new((10, 20), (20, 10)); assert_eq!(rect.min, coord! { x: 10, y: 10 }); assert_eq!(rect.max, coord! { x: 20, y: 20 }); } #[test] fn rect_width() { - let rect = Rect::new((10, 10), (20, 20)); - assert_eq!(rect.width(), 10); + let rect = Rect::::new((10., 10.), (20., 20.)); + assert_eq!(rect.width(), 10.); } #[test] fn rect_height() { - let rect = Rect::new((10., 10.), (20., 20.)); + let rect = Rect::::new((10., 10.), (20., 20.)); assert_relative_eq!(rect.height(), 10.); } diff --git a/geo-types/src/lib.rs b/geo-types/src/lib.rs index f4e402e10..02f6beaa4 100644 --- a/geo-types/src/lib.rs +++ b/geo-types/src/lib.rs @@ -140,13 +140,15 @@ mod arbitrary; pub mod geo_traits { use std::fmt; - pub trait Coord: Clone + Copy + fmt::Debug { + pub trait Coord: Clone + Copy + PartialEq + fmt::Debug { type Scalar: crate::CoordNum; fn x(&self) -> Self::Scalar; fn y(&self) -> Self::Scalar; - fn x_y(&self) -> (Self::Scalar, Self::Scalar) { + fn from_xy(x: Self::Scalar, y: Self::Scalar) -> Self; + + fn xy(&self) -> (Self::Scalar, Self::Scalar) { (self.x(), self.y()) } } diff --git a/geo-types/src/private_utils.rs b/geo-types/src/private_utils.rs index 1311a7b4f..cc6e9bf3d 100644 --- a/geo-types/src/private_utils.rs +++ b/geo-types/src/private_utils.rs @@ -3,46 +3,48 @@ // hidden module is public so the geo crate can reuse these algorithms to // prevent duplication. These functions are _not_ meant for public consumption. +use crate::geo_traits; +use num_traits::{Zero, One}; use crate::{Coord, CoordFloat, CoordNum, Line, LineString, Point, Rect}; -pub fn line_string_bounding_rect(line_string: &LineString) -> Option> +pub fn line_string_bounding_rect(line_string: &LineString) -> Option> where - T: CoordNum, + C: geo_traits::Coord, { get_bounding_rect(line_string.coords().cloned()) } -pub fn line_bounding_rect(line: Line) -> Rect +pub fn line_bounding_rect(line: Line) -> Rect where - T: CoordNum, + C: geo_traits::Coord, { Rect::new(line.start, line.end) } -pub fn get_bounding_rect(collection: I) -> Option> +pub fn get_bounding_rect(collection: I) -> Option> where - T: CoordNum, - I: IntoIterator>, + C: geo_traits::Coord, + I: IntoIterator, { let mut iter = collection.into_iter(); if let Some(pnt) = iter.next() { - let mut xrange = (pnt.x, pnt.x); - let mut yrange = (pnt.y, pnt.y); + let mut xrange = (pnt.x(), pnt.x()); + let mut yrange = (pnt.y(), pnt.y()); for pnt in iter { - let (px, py) = pnt.x_y(); + let (px, py) = pnt.xy(); xrange = get_min_max(px, xrange.0, xrange.1); yrange = get_min_max(py, yrange.0, yrange.1); } return Some(Rect::new( - coord! { - x: xrange.0, - y: yrange.0, - }, - coord! { - x: xrange.1, - y: yrange.1, - }, + C::from_xy( + xrange.0, + yrange.0, + ), + C::from_xy( + xrange.1, + yrange.1, + ), )); } None @@ -58,10 +60,13 @@ fn get_min_max(p: T, min: T, max: T) -> (T, T) { } } -pub fn line_segment_distance(point: C, start: C, end: C) -> T +pub fn line_segment_distance( + point: impl Into, + start: impl Into, + end: impl Into, +) -> C::Scalar where - T: CoordFloat, - C: Into>, + C: geo_traits::Coord, { let point = point.into(); let start = start.into(); @@ -70,22 +75,23 @@ where if start == end { return line_euclidean_length(Line::new(point, start)); } - let dx = end.x - start.x; - let dy = end.y - start.y; - let r = ((point.x - start.x) * dx + (point.y - start.y) * dy) / (dx.powi(2) + dy.powi(2)); - if r <= T::zero() { + let dx = end.x() - start.x(); + let dy = end.y() - start.y(); + let r = + ((point.x() - start.x()) * dx + (point.y() - start.y()) * dy) / (dx.powi(2) + dy.powi(2)); + if r <= C::Scalar::zero() { return line_euclidean_length(Line::new(point, start)); } - if r >= T::one() { + if r >= C::Scalar::one() { return line_euclidean_length(Line::new(point, end)); } - let s = ((start.y - point.y) * dx - (start.x - point.x) * dy) / (dx * dx + dy * dy); + let s = ((start.y() - point.y()) * dx - (start.x() - point.x()) * dy) / (dx * dx + dy * dy); s.abs() * dx.hypot(dy) } -pub fn line_euclidean_length(line: Line) -> T +pub fn line_euclidean_length(line: Line) -> C::Scalar where - T: CoordFloat, + C: geo_traits::Coord, { line.dx().hypot(line.dy()) } From 538f5c35fb8888eee5d639ccb13562d72cc13ae8 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Thu, 16 May 2024 19:47:28 +0000 Subject: [PATCH 4/8] progress --- geo-types/src/error.rs | 4 +- geo-types/src/geometry/coord.rs | 8 +++- geo-types/src/geometry/line.rs | 2 +- geo-types/src/geometry/line_string.rs | 33 ++++++++++------- geo-types/src/geometry/multi_polygon.rs | 5 ++- geo-types/src/geometry/point.rs | 4 ++ geo-types/src/geometry/polygon.rs | 49 +++++++++++++------------ geo-types/src/lib.rs | 4 ++ 8 files changed, 64 insertions(+), 45 deletions(-) diff --git a/geo-types/src/error.rs b/geo-types/src/error.rs index 9d0634cbd..efde7e121 100644 --- a/geo-types/src/error.rs +++ b/geo-types/src/error.rs @@ -23,7 +23,7 @@ impl fmt::Display for Error { #[cfg(test)] mod test { - use crate::{Geometry, Point, Rect}; + use crate::{Geometry, Point, Rect, Coord}; use alloc::string::ToString; use core::convert::TryFrom; @@ -32,7 +32,7 @@ mod test { let point = Point::new(1.0, 2.0); let point_geometry = Geometry::from(point); - let rect = Rect::new(Point::new(1.0, 2.0), Point::new(3.0, 4.0)); + let rect = Rect::::new(Point::new(1.0, 2.0), Point::new(3.0, 4.0)); let rect_geometry = Geometry::from(rect); Point::try_from(point_geometry).expect("failed to unwrap inner enum Point"); diff --git a/geo-types/src/geometry/coord.rs b/geo-types/src/geometry/coord.rs index c5b89b75b..023479215 100644 --- a/geo-types/src/geometry/coord.rs +++ b/geo-types/src/geometry/coord.rs @@ -43,6 +43,10 @@ impl geo_traits::Coord for Coord { fn y(&self) -> Self::Scalar { self.y } + + fn from_xy(x: Self::Scalar, y: Self::Scalar) -> Self { + Coord { x, y } + } } impl From<(T, T)> for Coord { @@ -65,9 +69,9 @@ impl From<[T; 2]> for Coord { } } -impl From> for Coord { +impl From> for Coord { #[inline] - fn from(point: Point) -> Self { + fn from(point: Point) -> Self { coord! { x: point.x(), y: point.y(), diff --git a/geo-types/src/geometry/line.rs b/geo-types/src/geometry/line.rs index 331ee733d..8a2f5684f 100644 --- a/geo-types/src/geometry/line.rs +++ b/geo-types/src/geometry/line.rs @@ -30,7 +30,7 @@ impl Line { /// assert_eq!(line.start, coord! { x: 0., y: 0. }); /// assert_eq!(line.end, coord! { x: 1., y: 2. }); /// ``` - pub fn new(start: impl Into, end: impl Into) -> Self { + pub fn new(start: impl Into, end: impl Into) -> Self { Self { start: start.into(), end: end.into(), diff --git a/geo-types/src/geometry/line_string.rs b/geo-types/src/geometry/line_string.rs index 1d02d89b0..f3faaf230 100644 --- a/geo-types/src/geometry/line_string.rs +++ b/geo-types/src/geometry/line_string.rs @@ -1,8 +1,8 @@ #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; -use crate::geo_traits; -use crate::{Coord, CoordNum, Line, Point, Triangle}; +use crate::geo_traits::{self, Coord}; +use crate::{Line, Point, Triangle}; use alloc::vec; use alloc::vec::Vec; use core::iter::FromIterator; @@ -149,10 +149,10 @@ impl<'a, C: fmt::Debug + geo_traits::Coord + 'a> fmt::Debug for PointsIter<'a, C } impl<'a, C: geo_traits::Coord + 'a> Iterator for PointsIter<'a, C> { - type Item = C; + type Item = Point; fn next(&mut self) -> Option { - self.0.next().map(|c| C::from(c.clone())) + self.0.next().map(|c| Point::from_coord(*c)) } fn size_hint(&self) -> (usize, Option) { @@ -168,7 +168,7 @@ impl<'a, C: geo_traits::Coord + 'a> ExactSizeIterator for PointsIter<'a, C> { impl<'a, C: geo_traits::Coord + 'a> DoubleEndedIterator for PointsIter<'a, C> { fn next_back(&mut self) -> Option { - self.0.next_back().map(|c| c.clone()) + self.0.next_back().map(|c| Point::from_coord(*c)) } } @@ -229,7 +229,7 @@ impl LineString { /// Return the coordinates of a [`LineString`] as a [`Vec`] of [`Point`]s pub fn into_points(self) -> Vec> { - self.0.into_iter().map(Point::from).collect() + self.0.into_iter().map(Point::from_coord).collect() } /// Return the coordinates of a [`LineString`] as a [`Vec`] of [`Coord`]s @@ -346,7 +346,7 @@ impl LineString { } /// Turn a [`Vec`] of [`Point`]-like objects into a [`LineString`]. -impl>> From> for LineString { +impl> From> for LineString { fn from(v: Vec) -> Self { Self(v.into_iter().map(|c| c.into()).collect()) } @@ -365,7 +365,7 @@ impl From<&Line> for LineString { } /// Turn an iterator of [`Point`]-like objects into a [`LineString`]. -impl>> FromIterator for LineString { +impl> FromIterator for LineString { fn from_iter>(iter: I) -> Self { Self(iter.into_iter().map(|c| c.into()).collect()) } @@ -415,13 +415,14 @@ impl IndexMut for LineString { } #[cfg(any(feature = "approx", test))] -impl RelativeEq for LineString +impl RelativeEq for LineString where - C::Scalar: AbsDiffEq + CoordNum + RelativeEq, + C: geo_traits::Coord + AbsDiffEq + RelativeEq, + C::Scalar: AbsDiffEq + RelativeEq, { #[inline] fn default_max_relative() -> Self::Epsilon { - T::default_max_relative() + C::Scalar::default_max_relative() } /// Equality assertion within a relative limit. @@ -462,12 +463,16 @@ where } #[cfg(any(feature = "approx", test))] -impl + CoordNum> AbsDiffEq for LineString { - type Epsilon = T; +impl AbsDiffEq for LineString +where + C: geo_traits::Coord + AbsDiffEq, + C::Scalar: AbsDiffEq, +{ + type Epsilon = C::Scalar; #[inline] fn default_epsilon() -> Self::Epsilon { - T::default_epsilon() + C::Scalar::default_epsilon() } /// Equality assertion with an absolute limit. diff --git a/geo-types/src/geometry/multi_polygon.rs b/geo-types/src/geometry/multi_polygon.rs index 86f68768d..f884cb45a 100644 --- a/geo-types/src/geometry/multi_polygon.rs +++ b/geo-types/src/geometry/multi_polygon.rs @@ -1,10 +1,11 @@ -use crate::{CoordNum, Polygon}; +use crate::{CoordNum, Polygon, Coord}; use alloc::vec; use alloc::vec::Vec; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; use core::iter::FromIterator; +use crate::geo_traits; /// A collection of [`Polygon`s](struct.Polygon.html). Can /// be created from a `Vec` of `Polygon`s, or from an @@ -29,7 +30,7 @@ use core::iter::FromIterator; /// predicates that operate on it. #[derive(Eq, PartialEq, Clone, Debug, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct MultiPolygon(pub Vec>); +pub struct MultiPolygon>(pub Vec>); impl>> From for MultiPolygon { fn from(x: IP) -> Self { diff --git a/geo-types/src/geometry/point.rs b/geo-types/src/geometry/point.rs index 28a389ef0..bdb951606 100644 --- a/geo-types/src/geometry/point.rs +++ b/geo-types/src/geometry/point.rs @@ -41,6 +41,10 @@ impl geo_traits::Coord for Point { fn y(&self) -> Self::Scalar { self.0.y() } + + fn from_xy(x: Self::Scalar, y: Self::Scalar) -> Self { + Self(Coord::from_xy(x, y)) + } } impl From> for Point { diff --git a/geo-types/src/geometry/polygon.rs b/geo-types/src/geometry/polygon.rs index d1c8f5a6f..217c1e5a8 100644 --- a/geo-types/src/geometry/polygon.rs +++ b/geo-types/src/geometry/polygon.rs @@ -1,7 +1,8 @@ -use crate::{CoordFloat, CoordNum, LineString, Point, Rect, Triangle}; +use crate::{CoordFloat, CoordNum, LineString, Point, Rect, Triangle, Coord}; use alloc::vec; use alloc::vec::Vec; use num_traits::{Float, Signed}; +use crate::geo_traits; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; @@ -68,12 +69,12 @@ use approx::{AbsDiffEq, RelativeEq}; /// [`LineString`]: line_string/struct.LineString.html #[derive(Eq, PartialEq, Clone, Debug, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct Polygon { - exterior: LineString, - interiors: Vec>, +pub struct Polygon> { + exterior: LineString, + interiors: Vec>, } -impl Polygon { +impl Polygon { /// Create a new `Polygon` with the provided exterior `LineString` ring and /// interior `LineString` rings. /// @@ -124,7 +125,7 @@ impl Polygon { /// &LineString::from(vec![(0., 0.), (1., 1.), (1., 0.), (0., 0.),]) /// ); /// ``` - pub fn new(mut exterior: LineString, mut interiors: Vec>) -> Self { + pub fn new(mut exterior: LineString, mut interiors: Vec>) -> Self { exterior.close(); for interior in &mut interiors { interior.close(); @@ -170,7 +171,7 @@ impl Polygon { /// ])] /// ); /// ``` - pub fn into_inner(self) -> (LineString, Vec>) { + pub fn into_inner(self) -> (LineString, Vec>) { (self.exterior, self.interiors) } @@ -187,7 +188,7 @@ impl Polygon { /// /// assert_eq!(polygon.exterior(), &exterior); /// ``` - pub fn exterior(&self) -> &LineString { + pub fn exterior(&self) -> &LineString { &self.exterior } @@ -240,7 +241,7 @@ impl Polygon { /// [will be closed]: #linestring-closing-operation pub fn exterior_mut(&mut self, f: F) where - F: FnOnce(&mut LineString), + F: FnOnce(&mut LineString), { f(&mut self.exterior); self.exterior.close(); @@ -249,7 +250,7 @@ impl Polygon { /// Fallible alternative to [`exterior_mut`](Polygon::exterior_mut). pub fn try_exterior_mut(&mut self, f: F) -> Result<(), E> where - F: FnOnce(&mut LineString) -> Result<(), E>, + F: FnOnce(&mut LineString) -> Result<(), E>, { f(&mut self.exterior)?; self.exterior.close(); @@ -277,7 +278,7 @@ impl Polygon { /// /// assert_eq!(interiors, polygon.interiors()); /// ``` - pub fn interiors(&self) -> &[LineString] { + pub fn interiors(&self) -> &[LineString] { &self.interiors } @@ -352,7 +353,7 @@ impl Polygon { /// [will be closed]: #linestring-closing-operation pub fn interiors_mut(&mut self, f: F) where - F: FnOnce(&mut [LineString]), + F: FnOnce(&mut [LineString]), { f(&mut self.interiors); for interior in &mut self.interiors { @@ -363,7 +364,7 @@ impl Polygon { /// Fallible alternative to [`interiors_mut`](Self::interiors_mut). pub fn try_interiors_mut(&mut self, f: F) -> Result<(), E> where - F: FnOnce(&mut [LineString]) -> Result<(), E>, + F: FnOnce(&mut [LineString]) -> Result<(), E>, { f(&mut self.interiors)?; for interior in &mut self.interiors { @@ -402,7 +403,7 @@ impl Polygon { /// ``` /// /// [will be closed]: #linestring-closing-operation - pub fn interiors_push(&mut self, new_interior: impl Into>) { + pub fn interiors_push(&mut self, new_interior: impl Into>) { let mut new_interior = new_interior.into(); new_interior.close(); self.interiors.push(new_interior); @@ -411,7 +412,7 @@ impl Polygon { /// Wrap-around previous-vertex fn previous_vertex(&self, current_vertex: usize) -> usize where - T: Float, + C: Float, { (current_vertex + (self.exterior.0.len() - 1) - 1) % (self.exterior.0.len() - 1) } @@ -515,15 +516,15 @@ impl Polygon { } } -impl From> for Polygon { - fn from(r: Rect) -> Self { +impl From> for Polygon { + fn from(r: Rect) -> Self { Polygon::new( vec![ - (r.min().x, r.min().y), - (r.max().x, r.min().y), - (r.max().x, r.max().y), - (r.min().x, r.max().y), - (r.min().x, r.min().y), + (r.min().x(), r.min().y()), + (r.max().x(), r.min().y()), + (r.max().x(), r.max().y()), + (r.min().x(), r.max().y()), + (r.min().x(), r.min().y()), ] .into(), Vec::new(), @@ -531,8 +532,8 @@ impl From> for Polygon { } } -impl From> for Polygon { - fn from(t: Triangle) -> Self { +impl From> for Polygon { + fn from(t: Triangle) -> Self { Polygon::new(vec![t.0, t.1, t.2, t.0].into(), Vec::new()) } } diff --git a/geo-types/src/lib.rs b/geo-types/src/lib.rs index 02f6beaa4..8231b6b54 100644 --- a/geo-types/src/lib.rs +++ b/geo-types/src/lib.rs @@ -148,6 +148,10 @@ pub mod geo_traits { fn from_xy(x: Self::Scalar, y: Self::Scalar) -> Self; + fn from_coord>(coord: Other) -> Self { + Self::from_xy(coord.x(), coord.y()) + } + fn xy(&self) -> (Self::Scalar, Self::Scalar) { (self.x(), self.y()) } From d07e530798535cf48126872212259f44529aca2c Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Thu, 16 May 2024 19:56:58 +0000 Subject: [PATCH 5/8] progress --- geo-types/src/geometry/line.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/geo-types/src/geometry/line.rs b/geo-types/src/geometry/line.rs index 8a2f5684f..3a29eaf02 100644 --- a/geo-types/src/geometry/line.rs +++ b/geo-types/src/geometry/line.rs @@ -1,4 +1,4 @@ -use crate::geo_traits; +use crate::geo_traits::{self, Coord as CoordTrait}; use crate::{Coord, CoordNum, Point}; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; @@ -141,11 +141,11 @@ impl Line { } pub fn start_point(&self) -> Point { - Point::from(self.start) + Point::from_coord(self.start) } pub fn end_point(&self) -> Point { - Point::from(self.end) + Point::from_coord(self.end) } pub fn points(&self) -> (Point, Point) { @@ -155,7 +155,10 @@ impl Line { impl From<[(C::Scalar, C::Scalar); 2]> for Line { fn from(coord: [(C::Scalar, C::Scalar); 2]) -> Self { - Line::new(coord[0], coord[1]) + Line::new( + C::from_xy(coord[0].0, coord[0].1), + C::from_xy(coord[1].0, coord[1].1), + ) } } #[cfg(any(feature = "approx", test))] From 0cb975ae123bad171ad50a6d65b091ed89724aa0 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Fri, 17 May 2024 17:54:30 +0000 Subject: [PATCH 6/8] progress --- geo-types/src/geometry/line.rs | 10 +++----- geo-types/src/geometry/polygon.rs | 41 ++++++++++++++++++------------- geo-types/src/lib.rs | 3 ++- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/geo-types/src/geometry/line.rs b/geo-types/src/geometry/line.rs index 3a29eaf02..dc5340659 100644 --- a/geo-types/src/geometry/line.rs +++ b/geo-types/src/geometry/line.rs @@ -155,16 +155,14 @@ impl Line { impl From<[(C::Scalar, C::Scalar); 2]> for Line { fn from(coord: [(C::Scalar, C::Scalar); 2]) -> Self { - Line::new( - C::from_xy(coord[0].0, coord[0].1), - C::from_xy(coord[1].0, coord[1].1), - ) + Line::new(C::from_xy(coord[0].0, coord[0].1), C::from_xy(coord[1].0, coord[1].1)) } } #[cfg(any(feature = "approx", test))] -impl RelativeEq for Line +impl RelativeEq for Line where - T: AbsDiffEq + CoordNum + RelativeEq, + C: geo_traits::Coord + AbsDiffEq + RelativeEq, + C::Scalar: AbsDiffEq + RelativeEq, { #[inline] fn default_max_relative() -> Self::Epsilon { diff --git a/geo-types/src/geometry/polygon.rs b/geo-types/src/geometry/polygon.rs index 217c1e5a8..0075cb61d 100644 --- a/geo-types/src/geometry/polygon.rs +++ b/geo-types/src/geometry/polygon.rs @@ -1,8 +1,8 @@ -use crate::{CoordFloat, CoordNum, LineString, Point, Rect, Triangle, Coord}; +use crate::geo_traits::{self, Coord}; +use crate::{Coord, CoordFloat, CoordNum, LineString, Point, Rect, Triangle}; use alloc::vec; use alloc::vec::Vec; use num_traits::{Float, Signed}; -use crate::geo_traits; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; @@ -477,7 +477,10 @@ enum ListSign { Mixed, } -impl Polygon { +impl Polygon +where + C::Scalar: CoordFloat + Signed, +{ /// Determine whether a Polygon is convex // For each consecutive pair of edges of the polygon (each triplet of points), // compute the z-component of the cross product of the vectors defined by the @@ -499,9 +502,9 @@ impl Polygon { .map(|(idx, _)| { let prev_1 = self.previous_vertex(idx); let prev_2 = self.previous_vertex(prev_1); - Point::from(self.exterior[prev_2]).cross_prod( - Point::from(self.exterior[prev_1]), - Point::from(self.exterior[idx]), + Point::from_coord(self.exterior[prev_2]).cross_prod( + Point::from_coord(self.exterior[prev_1]), + Point::from_coord(self.exterior[idx]), ) }) // accumulate and check cross-product result signs in a single pass @@ -520,11 +523,11 @@ impl From> for Polygon { fn from(r: Rect) -> Self { Polygon::new( vec![ - (r.min().x(), r.min().y()), - (r.max().x(), r.min().y()), - (r.max().x(), r.max().y()), - (r.min().x(), r.max().y()), - (r.min().x(), r.min().y()), + C::from_xy(r.min().x(), r.min().y()), + C::from_xy(r.max().x(), r.min().y()), + C::from_xy(r.max().x(), r.max().y()), + C::from_xy(r.min().x(), r.max().y()), + C::from_xy(r.min().x(), r.min().y()), ] .into(), Vec::new(), @@ -539,13 +542,14 @@ impl From> for Polygon { } #[cfg(any(feature = "approx", test))] -impl RelativeEq for Polygon +impl RelativeEq for Polygon where - T: AbsDiffEq + CoordNum + RelativeEq, + C: geo_traits::Coord + AbsDiffEq + RelativeEq, + C::Scalar: AbsDiffEq + RelativeEq, { #[inline] fn default_max_relative() -> Self::Epsilon { - T::default_max_relative() + C::Scalar::default_max_relative() } /// Equality assertion within a relative limit. @@ -584,12 +588,15 @@ where } #[cfg(any(feature = "approx", test))] -impl + CoordNum> AbsDiffEq for Polygon { - type Epsilon = T; +impl AbsDiffEq for Polygon +where + C: geo_traits::Coord + AbsDiffEq, +{ + type Epsilon = C::Scalar; #[inline] fn default_epsilon() -> Self::Epsilon { - T::default_epsilon() + C::Scalar::default_epsilon() } /// Equality assertion with an absolute limit. diff --git a/geo-types/src/lib.rs b/geo-types/src/lib.rs index 8231b6b54..eca45d72d 100644 --- a/geo-types/src/lib.rs +++ b/geo-types/src/lib.rs @@ -138,9 +138,10 @@ mod wkt_macro; mod arbitrary; pub mod geo_traits { + use core::ops; use std::fmt; - pub trait Coord: Clone + Copy + PartialEq + fmt::Debug { + pub trait Coord: Clone + Copy + PartialEq + fmt::Debug + ops::Sub { type Scalar: crate::CoordNum; fn x(&self) -> Self::Scalar; From 4cb5c072f8cb1748e9baa2d944089b430b2e002c Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 18 May 2024 09:08:15 +0000 Subject: [PATCH 7/8] progress --- geo-types/src/geometry/mod.rs | 44 +++++++++++++++---------------- geo-types/src/geometry/polygon.rs | 14 +++++----- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/geo-types/src/geometry/mod.rs b/geo-types/src/geometry/mod.rs index 4faf01753..7050d74af 100644 --- a/geo-types/src/geometry/mod.rs +++ b/geo-types/src/geometry/mod.rs @@ -24,7 +24,7 @@ pub use polygon::Polygon; pub use rect::Rect; pub use triangle::Triangle; -use crate::{CoordNum, Error}; +use crate::{CoordNum, Error, geo_traits}; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; @@ -49,41 +49,41 @@ use core::convert::TryFrom; /// #[derive(Eq, PartialEq, Clone, Debug, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub enum Geometry { - Point(Point), - Line(Line), - LineString(LineString), - Polygon(Polygon), - MultiPoint(MultiPoint), - MultiLineString(MultiLineString), - MultiPolygon(MultiPolygon), - GeometryCollection(GeometryCollection), - Rect(Rect), - Triangle(Triangle), +pub enum Geometry> { + Point(Point), + Line(Line), + LineString(LineString), + Polygon(Polygon), + MultiPoint(MultiPoint), + MultiLineString(MultiLineString), + MultiPolygon(MultiPolygon), + GeometryCollection(GeometryCollection), + Rect(Rect), + Triangle(Triangle), } -impl From> for Geometry { - fn from(x: Point) -> Self { +impl From> for Geometry { + fn from(x: Point) -> Self { Self::Point(x) } } -impl From> for Geometry { - fn from(x: Line) -> Self { +impl From> for Geometry { + fn from(x: Line) -> Self { Self::Line(x) } } -impl From> for Geometry { - fn from(x: LineString) -> Self { +impl From> for Geometry { + fn from(x: LineString) -> Self { Self::LineString(x) } } -impl From> for Geometry { - fn from(x: Polygon) -> Self { +impl From> for Geometry { + fn from(x: Polygon) -> Self { Self::Polygon(x) } } -impl From> for Geometry { - fn from(x: MultiPoint) -> Self { +impl From> for Geometry { + fn from(x: MultiPoint) -> Self { Self::MultiPoint(x) } } diff --git a/geo-types/src/geometry/polygon.rs b/geo-types/src/geometry/polygon.rs index 0075cb61d..360bc3d85 100644 --- a/geo-types/src/geometry/polygon.rs +++ b/geo-types/src/geometry/polygon.rs @@ -1,5 +1,5 @@ -use crate::geo_traits::{self, Coord}; -use crate::{Coord, CoordFloat, CoordNum, LineString, Point, Rect, Triangle}; +use crate::geo_traits::{self, Coord as CoordTrait}; +use crate::{Coord, CoordFloat, LineString, Point, Rect, Triangle}; use alloc::vec; use alloc::vec::Vec; use num_traits::{Float, Signed}; @@ -412,7 +412,7 @@ impl Polygon { /// Wrap-around previous-vertex fn previous_vertex(&self, current_vertex: usize) -> usize where - C: Float, + C::Scalar: Float, { (current_vertex + (self.exterior.0.len() - 1) - 1) % (self.exterior.0.len() - 1) } @@ -591,6 +591,7 @@ where impl AbsDiffEq for Polygon where C: geo_traits::Coord + AbsDiffEq, + C::Scalar: AbsDiffEq, { type Epsilon = C::Scalar; @@ -634,11 +635,12 @@ where ))] macro_rules! impl_rstar_polygon { ($rstar:ident) => { - impl $rstar::RTreeObject for Polygon + impl $rstar::RTreeObject for Polygon where - T: ::num_traits::Float + ::$rstar::RTreeNum, + C: geo_traits::Coord, + C::Scalar: Float + ::$rstar::RTreeNum, { - type Envelope = ::$rstar::AABB>; + type Envelope = ::$rstar::AABB>; fn envelope(&self) -> Self::Envelope { self.exterior.envelope() From 559dc725c104ae87b1b994b124c7aebe7dc98de4 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 18 May 2024 10:05:02 +0000 Subject: [PATCH 8/8] remove manual debug --- geo-types/src/geometry/line_string.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/geo-types/src/geometry/line_string.rs b/geo-types/src/geometry/line_string.rs index f3faaf230..a131873cd 100644 --- a/geo-types/src/geometry/line_string.rs +++ b/geo-types/src/geometry/line_string.rs @@ -7,7 +7,6 @@ use alloc::vec; use alloc::vec::Vec; use core::iter::FromIterator; use core::ops::{Index, IndexMut}; -use std::fmt; /// An ordered collection of two or more [`Coord`]s, representing a /// path between locations. @@ -139,15 +138,9 @@ use std::fmt; pub struct LineString>(pub Vec); /// A [`Point`] iterator returned by the `points` method +#[derive(Debug)] pub struct PointsIter<'a, C: geo_traits::Coord + 'a>(::core::slice::Iter<'a, C>); -impl<'a, C: fmt::Debug + geo_traits::Coord + 'a> fmt::Debug for PointsIter<'a, C> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let formatted = self.0.fmt(f); - f.debug_tuple("PointsIter").field(&formatted).finish() - } -} - impl<'a, C: geo_traits::Coord + 'a> Iterator for PointsIter<'a, C> { type Item = Point;