diff --git a/geo-types/src/coordinate.rs b/geo-types/src/coordinate.rs index c51c94a14..5c30dd751 100644 --- a/geo-types/src/coordinate.rs +++ b/geo-types/src/coordinate.rs @@ -1,4 +1,4 @@ -use crate::{CoordinateType, Point}; +use crate::{CoordNum, Point}; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq, UlpsEq}; @@ -27,13 +27,13 @@ use approx::{AbsDiffEq, RelativeEq, UlpsEq}; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Coordinate where - T: CoordinateType, + T: CoordNum, { pub x: T, pub y: T, } -impl From<(T, T)> for Coordinate { +impl From<(T, T)> for Coordinate { fn from(coords: (T, T)) -> Self { Coordinate { x: coords.0, @@ -42,7 +42,7 @@ impl From<(T, T)> for Coordinate { } } -impl From<[T; 2]> for Coordinate { +impl From<[T; 2]> for Coordinate { fn from(coords: [T; 2]) -> Self { Coordinate { x: coords[0], @@ -51,7 +51,7 @@ impl From<[T; 2]> for Coordinate { } } -impl From> for Coordinate { +impl From> for Coordinate { fn from(point: Point) -> Self { Coordinate { x: point.x(), @@ -62,7 +62,7 @@ impl From> for Coordinate { impl Coordinate where - T: CoordinateType, + T: CoordNum, { /// Returns a tuple that contains the x/horizontal & y/vertical component of the coordinate. /// @@ -102,7 +102,7 @@ use std::ops::{Add, Div, Mul, Neg, Sub}; /// ``` impl Neg for Coordinate where - T: CoordinateType + Neg, + T: CoordNum + Neg, { type Output = Coordinate; @@ -127,7 +127,7 @@ where /// ``` impl Add for Coordinate where - T: CoordinateType, + T: CoordNum, { type Output = Coordinate; @@ -152,7 +152,7 @@ where /// ``` impl Sub for Coordinate where - T: CoordinateType, + T: CoordNum, { type Output = Coordinate; @@ -176,7 +176,7 @@ where /// ``` impl Mul for Coordinate where - T: CoordinateType, + T: CoordNum, { type Output = Coordinate; @@ -200,7 +200,7 @@ where /// ``` impl Div for Coordinate where - T: CoordinateType, + T: CoordNum, { type Output = Coordinate; @@ -223,7 +223,7 @@ use num_traits::Zero; /// assert_eq!(p.x, 0.); /// assert_eq!(p.y, 0.); /// ``` -impl Coordinate { +impl Coordinate { pub fn zero() -> Self { Coordinate { x: T::zero(), @@ -232,7 +232,7 @@ impl Coordinate { } } -impl Zero for Coordinate { +impl Zero for Coordinate { fn zero() -> Self { Coordinate::zero() } @@ -242,7 +242,7 @@ impl Zero for Coordinate { } #[cfg(any(feature = "approx", test))] -impl AbsDiffEq for Coordinate +impl AbsDiffEq for Coordinate where T::Epsilon: Copy, { @@ -260,7 +260,7 @@ where } #[cfg(any(feature = "approx", test))] -impl RelativeEq for Coordinate +impl RelativeEq for Coordinate where T::Epsilon: Copy, { @@ -277,7 +277,7 @@ where } #[cfg(any(feature = "approx", test))] -impl UlpsEq for Coordinate +impl UlpsEq for Coordinate where T::Epsilon: Copy, { diff --git a/geo-types/src/geometry.rs b/geo-types/src/geometry.rs index a69870f8f..324962e2d 100644 --- a/geo-types/src/geometry.rs +++ b/geo-types/src/geometry.rs @@ -1,8 +1,7 @@ use crate::{ - CoordinateType, GeometryCollection, Line, LineString, MultiLineString, MultiPoint, - MultiPolygon, Point, Polygon, Rect, Triangle, + CoordNum, GeometryCollection, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, + Point, Polygon, Rect, Triangle, }; -use num_traits::Float; use std::convert::TryFrom; use std::error::Error; use std::fmt; @@ -26,7 +25,7 @@ use std::fmt; #[derive(Eq, PartialEq, Clone, Debug, Hash)] pub enum Geometry where - T: CoordinateType, + T: CoordNum, { Point(Point), Line(Line), @@ -40,55 +39,55 @@ where Triangle(Triangle), } -impl From> for Geometry { +impl From> for Geometry { fn from(x: Point) -> Geometry { Geometry::Point(x) } } -impl From> for Geometry { +impl From> for Geometry { fn from(x: Line) -> Geometry { Geometry::Line(x) } } -impl From> for Geometry { +impl From> for Geometry { fn from(x: LineString) -> Geometry { Geometry::LineString(x) } } -impl From> for Geometry { +impl From> for Geometry { fn from(x: Polygon) -> Geometry { Geometry::Polygon(x) } } -impl From> for Geometry { +impl From> for Geometry { fn from(x: MultiPoint) -> Geometry { Geometry::MultiPoint(x) } } -impl From> for Geometry { +impl From> for Geometry { fn from(x: MultiLineString) -> Geometry { Geometry::MultiLineString(x) } } -impl From> for Geometry { +impl From> for Geometry { fn from(x: MultiPolygon) -> Geometry { Geometry::MultiPolygon(x) } } -impl From> for Geometry { +impl From> for Geometry { fn from(x: Rect) -> Geometry { Geometry::Rect(x) } } -impl From> for Geometry { +impl From> for Geometry { fn from(x: Triangle) -> Geometry { Geometry::Triangle(x) } } -impl Geometry { +impl Geometry { /// If this Geometry is a Point, then return that, else None. /// /// # Examples @@ -198,10 +197,7 @@ impl Error for FailedToConvertError { } } -impl TryFrom> for Point -where - T: Float, -{ +impl TryFrom> for Point { type Error = FailedToConvertError; fn try_from(geom: Geometry) -> Result, Self::Error> { @@ -212,10 +208,7 @@ where } } -impl TryFrom> for Line -where - T: Float, -{ +impl TryFrom> for Line { type Error = FailedToConvertError; fn try_from(geom: Geometry) -> Result, Self::Error> { @@ -226,10 +219,7 @@ where } } -impl TryFrom> for LineString -where - T: Float, -{ +impl TryFrom> for LineString { type Error = FailedToConvertError; fn try_from(geom: Geometry) -> Result, Self::Error> { @@ -240,10 +230,7 @@ where } } -impl TryFrom> for Polygon -where - T: Float, -{ +impl TryFrom> for Polygon { type Error = FailedToConvertError; fn try_from(geom: Geometry) -> Result, Self::Error> { @@ -254,10 +241,7 @@ where } } -impl TryFrom> for MultiPoint -where - T: Float, -{ +impl TryFrom> for MultiPoint { type Error = FailedToConvertError; fn try_from(geom: Geometry) -> Result, Self::Error> { @@ -268,10 +252,7 @@ where } } -impl TryFrom> for MultiLineString -where - T: Float, -{ +impl TryFrom> for MultiLineString { type Error = FailedToConvertError; fn try_from(geom: Geometry) -> Result, Self::Error> { @@ -282,10 +263,7 @@ where } } -impl TryFrom> for MultiPolygon -where - T: Float, -{ +impl TryFrom> for MultiPolygon { type Error = FailedToConvertError; fn try_from(geom: Geometry) -> Result, Self::Error> { diff --git a/geo-types/src/geometry_collection.rs b/geo-types/src/geometry_collection.rs index 7ff1d75ea..c683398ca 100644 --- a/geo-types/src/geometry_collection.rs +++ b/geo-types/src/geometry_collection.rs @@ -1,4 +1,4 @@ -use crate::{CoordinateType, Geometry}; +use crate::{CoordNum, Geometry}; use std::iter::FromIterator; use std::ops::{Index, IndexMut}; @@ -69,15 +69,15 @@ use std::ops::{Index, IndexMut}; #[derive(Eq, PartialEq, Clone, Debug, Hash)] pub struct GeometryCollection(pub Vec>) where - T: CoordinateType; + T: CoordNum; -impl Default for GeometryCollection { +impl Default for GeometryCollection { fn default() -> Self { Self::new() } } -impl GeometryCollection { +impl GeometryCollection { /// Return an empty GeometryCollection pub fn new() -> GeometryCollection { GeometryCollection(Vec::new()) @@ -96,20 +96,20 @@ impl GeometryCollection { /// Convert any Geometry (or anything that can be converted to a Geometry) into a /// GeometryCollection -impl>> From for GeometryCollection { +impl>> From for GeometryCollection { fn from(x: IG) -> Self { GeometryCollection(vec![x.into()]) } } /// Collect Geometries (or what can be converted to a Geometry) into a GeometryCollection -impl>> FromIterator for GeometryCollection { +impl>> FromIterator for GeometryCollection { fn from_iter>(iter: I) -> Self { GeometryCollection(iter.into_iter().map(|g| g.into()).collect()) } } -impl Index for GeometryCollection { +impl Index for GeometryCollection { type Output = Geometry; fn index(&self, index: usize) -> &Geometry { @@ -117,7 +117,7 @@ impl Index for GeometryCollection { } } -impl IndexMut for GeometryCollection { +impl IndexMut for GeometryCollection { fn index_mut(&mut self, index: usize) -> &mut Geometry { self.0.index_mut(index) } @@ -125,13 +125,13 @@ impl IndexMut for GeometryCollection { // structure helper for consuming iterator #[derive(Debug)] -pub struct IntoIteratorHelper { +pub struct IntoIteratorHelper { iter: ::std::vec::IntoIter>, } // implement the IntoIterator trait for a consuming iterator. Iteration will // consume the GeometryCollection -impl IntoIterator for GeometryCollection { +impl IntoIterator for GeometryCollection { type Item = Geometry; type IntoIter = IntoIteratorHelper; @@ -144,7 +144,7 @@ impl IntoIterator for GeometryCollection { } // implement Iterator trait for the helper struct, to be used by adapters -impl Iterator for IntoIteratorHelper { +impl Iterator for IntoIteratorHelper { type Item = Geometry; // just return the reference @@ -155,13 +155,13 @@ impl Iterator for IntoIteratorHelper { // structure helper for non-consuming iterator #[derive(Debug)] -pub struct IterHelper<'a, T: CoordinateType> { +pub struct IterHelper<'a, T: CoordNum> { iter: ::std::slice::Iter<'a, Geometry>, } // implement the IntoIterator trait for a non-consuming iterator. Iteration will // borrow the GeometryCollection -impl<'a, T: CoordinateType> IntoIterator for &'a GeometryCollection { +impl<'a, T: CoordNum> IntoIterator for &'a GeometryCollection { type Item = &'a Geometry; type IntoIter = IterHelper<'a, T>; @@ -174,7 +174,7 @@ impl<'a, T: CoordinateType> IntoIterator for &'a GeometryCollection { } // implement the Iterator trait for the helper struct, to be used by adapters -impl<'a, T: CoordinateType> Iterator for IterHelper<'a, T> { +impl<'a, T: CoordNum> Iterator for IterHelper<'a, T> { type Item = &'a Geometry; // just return the str reference @@ -185,13 +185,13 @@ impl<'a, T: CoordinateType> Iterator for IterHelper<'a, T> { // structure helper for mutable non-consuming iterator #[derive(Debug)] -pub struct IterMutHelper<'a, T: CoordinateType> { +pub struct IterMutHelper<'a, T: CoordNum> { iter: ::std::slice::IterMut<'a, Geometry>, } // implement the IntoIterator trait for a mutable non-consuming iterator. Iteration will // mutably borrow the GeometryCollection -impl<'a, T: CoordinateType> IntoIterator for &'a mut GeometryCollection { +impl<'a, T: CoordNum> IntoIterator for &'a mut GeometryCollection { type Item = &'a mut Geometry; type IntoIter = IterMutHelper<'a, T>; @@ -204,7 +204,7 @@ impl<'a, T: CoordinateType> IntoIterator for &'a mut GeometryCollection { } // implement the Iterator trait for the helper struct, to be used by adapters -impl<'a, T: CoordinateType> Iterator for IterMutHelper<'a, T> { +impl<'a, T: CoordNum> Iterator for IterMutHelper<'a, T> { type Item = &'a mut Geometry; // just return the str reference @@ -213,7 +213,7 @@ impl<'a, T: CoordinateType> Iterator for IterMutHelper<'a, T> { } } -impl<'a, T: CoordinateType> GeometryCollection { +impl<'a, T: CoordNum> GeometryCollection { pub fn iter(&'a self) -> IterHelper<'a, T> { self.into_iter() } diff --git a/geo-types/src/lib.rs b/geo-types/src/lib.rs index 08e8fdd7c..bb8fb87d0 100644 --- a/geo-types/src/lib.rs +++ b/geo-types/src/lib.rs @@ -35,7 +35,8 @@ //! [JTS]: https://github.com/locationtech/jts //! [GEOS]: https://trac.osgeo.org/geos extern crate num_traits; -use num_traits::{Num, NumCast}; +use num_traits::{Float, Num, NumCast}; +use std::fmt::Debug; #[cfg(feature = "serde")] #[macro_use] @@ -48,14 +49,24 @@ extern crate rstar; #[macro_use] extern crate approx; +#[deprecated(since = "0.7", note = "use `CoordFloat` or `CoordNum` instead")] +pub trait CoordinateType: Num + Copy + NumCast + PartialOrd + Debug {} +#[allow(deprecated)] +impl CoordinateType for T {} + /// The type of an x or y value of a point/coordinate. /// -/// Floats (`f32` and `f64`) and Integers (`u8`, `i32` etc.) -/// implement this. Many algorithms only make sense for -/// Float types (like area, or length calculations). -pub trait CoordinateType: Num + Copy + NumCast + PartialOrd {} -// Little bit of a hack to make to make this work -impl CoordinateType for T {} +/// Floats (`f32` and `f64`) and Integers (`u8`, `i32` etc.) implement this. +/// +/// For algorithms which only make sense for floating point, like area or length calculations, +/// see [CoordFloat](trait.CoordFloat.html). +#[allow(deprecated)] +pub trait CoordNum: CoordinateType + Debug {} +#[allow(deprecated)] +impl CoordNum for T {} + +pub trait CoordFloat: CoordNum + Float {} +impl CoordFloat for T {} mod coordinate; pub use crate::coordinate::Coordinate; diff --git a/geo-types/src/line.rs b/geo-types/src/line.rs index 95b5a2839..3759cc102 100644 --- a/geo-types/src/line.rs +++ b/geo-types/src/line.rs @@ -1,4 +1,4 @@ -use crate::{Coordinate, CoordinateType, Point}; +use crate::{CoordNum, Coordinate, Point}; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; @@ -13,7 +13,7 @@ use approx::{AbsDiffEq, RelativeEq}; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Line where - T: CoordinateType, + T: CoordNum, { pub start: Coordinate, pub end: Coordinate, @@ -21,7 +21,7 @@ where impl Line where - T: CoordinateType, + T: CoordNum, { /// Creates a new line segment. /// @@ -161,7 +161,7 @@ where } } -impl From<[(T, T); 2]> for Line { +impl From<[(T, T); 2]> for Line { fn from(coord: [(T, T); 2]) -> Line { Line::new(coord[0], coord[1]) } @@ -169,7 +169,7 @@ impl From<[(T, T); 2]> for Line { #[cfg(any(feature = "approx", test))] impl RelativeEq for Line where - T: AbsDiffEq + CoordinateType + RelativeEq, + T: AbsDiffEq + CoordNum + RelativeEq, { #[inline] fn default_max_relative() -> Self::Epsilon { @@ -201,7 +201,7 @@ where } #[cfg(any(feature = "approx", test))] -impl + CoordinateType> AbsDiffEq for Line { +impl + CoordNum> AbsDiffEq for Line { type Epsilon = T; #[inline] diff --git a/geo-types/src/line_string.rs b/geo-types/src/line_string.rs index a64f675c2..a5f6b5d37 100644 --- a/geo-types/src/line_string.rs +++ b/geo-types/src/line_string.rs @@ -1,7 +1,7 @@ #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; -use crate::{Coordinate, CoordinateType, Line, Point, Triangle}; +use crate::{CoordNum, Coordinate, Line, Point, Triangle}; use std::iter::FromIterator; use std::ops::{Index, IndexMut}; @@ -112,13 +112,13 @@ use std::ops::{Index, IndexMut}; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct LineString(pub Vec>) where - T: CoordinateType; + T: CoordNum; /// A `Point` iterator returned by the `points_iter` method #[derive(Debug)] -pub struct PointsIter<'a, T: CoordinateType + 'a>(::std::slice::Iter<'a, Coordinate>); +pub struct PointsIter<'a, T: CoordNum + 'a>(::std::slice::Iter<'a, Coordinate>); -impl<'a, T: CoordinateType> Iterator for PointsIter<'a, T> { +impl<'a, T: CoordNum> Iterator for PointsIter<'a, T> { type Item = Point; fn next(&mut self) -> Option { @@ -126,13 +126,13 @@ impl<'a, T: CoordinateType> Iterator for PointsIter<'a, T> { } } -impl<'a, T: CoordinateType> DoubleEndedIterator for PointsIter<'a, T> { +impl<'a, T: CoordNum> DoubleEndedIterator for PointsIter<'a, T> { fn next_back(&mut self) -> Option { self.0.next_back().map(|c| Point(*c)) } } -impl LineString { +impl LineString { /// Return an iterator yielding the coordinates of a `LineString` as `Point`s pub fn points_iter(&self) -> PointsIter { PointsIter(self.0.iter()) @@ -248,21 +248,21 @@ 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 { LineString(v.into_iter().map(|c| c.into()).collect()) } } /// Turn an iterator of `Point`-like objects into a `LineString`. -impl>> FromIterator for LineString { +impl>> FromIterator for LineString { fn from_iter>(iter: I) -> Self { LineString(iter.into_iter().map(|c| c.into()).collect()) } } /// Iterate over all the [Coordinate](struct.Coordinates.html)s in this `LineString`. -impl IntoIterator for LineString { +impl IntoIterator for LineString { type Item = Coordinate; type IntoIter = ::std::vec::IntoIter>; @@ -272,7 +272,7 @@ impl IntoIterator for LineString { } /// Mutably iterate over all the [Coordinate](struct.Coordinates.html)s in this `LineString`. -impl<'a, T: CoordinateType> IntoIterator for &'a mut LineString { +impl<'a, T: CoordNum> IntoIterator for &'a mut LineString { type Item = &'a mut Coordinate; type IntoIter = ::std::slice::IterMut<'a, Coordinate>; @@ -281,7 +281,7 @@ impl<'a, T: CoordinateType> IntoIterator for &'a mut LineString { } } -impl Index for LineString { +impl Index for LineString { type Output = Coordinate; fn index(&self, index: usize) -> &Coordinate { @@ -289,7 +289,7 @@ impl Index for LineString { } } -impl IndexMut for LineString { +impl IndexMut for LineString { fn index_mut(&mut self, index: usize) -> &mut Coordinate { self.0.index_mut(index) } @@ -298,7 +298,7 @@ impl IndexMut for LineString { #[cfg(any(feature = "approx", test))] impl RelativeEq for LineString where - T: AbsDiffEq + CoordinateType + RelativeEq, + T: AbsDiffEq + CoordNum + RelativeEq, { #[inline] fn default_max_relative() -> Self::Epsilon { @@ -343,7 +343,7 @@ where } #[cfg(any(feature = "approx", test))] -impl + CoordinateType> AbsDiffEq for LineString { +impl + CoordNum> AbsDiffEq for LineString { type Epsilon = T; #[inline] diff --git a/geo-types/src/multi_line_string.rs b/geo-types/src/multi_line_string.rs index 785a34ec5..527421a69 100644 --- a/geo-types/src/multi_line_string.rs +++ b/geo-types/src/multi_line_string.rs @@ -1,4 +1,4 @@ -use crate::{CoordinateType, LineString}; +use crate::{CoordNum, LineString}; use std::iter::FromIterator; /// A collection of @@ -32,9 +32,9 @@ use std::iter::FromIterator; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct MultiLineString(pub Vec>) where - T: CoordinateType; + T: CoordNum; -impl MultiLineString { +impl MultiLineString { /// True if the MultiLineString is empty or if all of its LineStrings are closed - see /// [`LineString::is_closed`]. /// @@ -61,19 +61,19 @@ impl MultiLineString { } } -impl>> From for MultiLineString { +impl>> From for MultiLineString { fn from(ls: ILS) -> Self { MultiLineString(vec![ls.into()]) } } -impl>> FromIterator for MultiLineString { +impl>> FromIterator for MultiLineString { fn from_iter>(iter: I) -> Self { MultiLineString(iter.into_iter().map(|ls| ls.into()).collect()) } } -impl IntoIterator for MultiLineString { +impl IntoIterator for MultiLineString { type Item = LineString; type IntoIter = ::std::vec::IntoIter>; @@ -82,7 +82,7 @@ impl IntoIterator for MultiLineString { } } -impl<'a, T: CoordinateType> IntoIterator for &'a MultiLineString { +impl<'a, T: CoordNum> IntoIterator for &'a MultiLineString { type Item = &'a LineString; type IntoIter = ::std::slice::Iter<'a, LineString>; @@ -91,7 +91,7 @@ impl<'a, T: CoordinateType> IntoIterator for &'a MultiLineString { } } -impl<'a, T: CoordinateType> IntoIterator for &'a mut MultiLineString { +impl<'a, T: CoordNum> IntoIterator for &'a mut MultiLineString { type Item = &'a mut LineString; type IntoIter = ::std::slice::IterMut<'a, LineString>; @@ -100,7 +100,7 @@ impl<'a, T: CoordinateType> IntoIterator for &'a mut MultiLineString { } } -impl MultiLineString { +impl MultiLineString { pub fn iter(&self) -> impl Iterator> { self.0.iter() } diff --git a/geo-types/src/multi_point.rs b/geo-types/src/multi_point.rs index 83facc604..b0af933a1 100644 --- a/geo-types/src/multi_point.rs +++ b/geo-types/src/multi_point.rs @@ -1,4 +1,4 @@ -use crate::{CoordinateType, Point}; +use crate::{CoordNum, Point}; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; @@ -32,9 +32,9 @@ use std::iter::FromIterator; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct MultiPoint(pub Vec>) where - T: CoordinateType; + T: CoordNum; -impl>> From for MultiPoint { +impl>> From for MultiPoint { /// Convert a single `Point` (or something which can be converted to a `Point`) into a /// one-member `MultiPoint` fn from(x: IP) -> MultiPoint { @@ -42,7 +42,7 @@ impl>> From for MultiPoint { } } -impl>> From> for MultiPoint { +impl>> From> for MultiPoint { /// Convert a `Vec` of `Points` (or `Vec` of things which can be converted to a `Point`) into a /// `MultiPoint`. fn from(v: Vec) -> MultiPoint { @@ -50,7 +50,7 @@ impl>> From> for MultiPoint { } } -impl>> FromIterator for MultiPoint { +impl>> FromIterator for MultiPoint { /// Collect the results of a `Point` iterator into a `MultiPoint` fn from_iter>(iter: I) -> Self { MultiPoint(iter.into_iter().map(|p| p.into()).collect()) @@ -58,7 +58,7 @@ impl>> FromIterator for MultiPoint { } /// Iterate over the `Point`s in this `MultiPoint`. -impl IntoIterator for MultiPoint { +impl IntoIterator for MultiPoint { type Item = Point; type IntoIter = ::std::vec::IntoIter>; @@ -67,7 +67,7 @@ impl IntoIterator for MultiPoint { } } -impl<'a, T: CoordinateType> IntoIterator for &'a MultiPoint { +impl<'a, T: CoordNum> IntoIterator for &'a MultiPoint { type Item = &'a Point; type IntoIter = ::std::slice::Iter<'a, Point>; @@ -76,7 +76,7 @@ impl<'a, T: CoordinateType> IntoIterator for &'a MultiPoint { } } -impl<'a, T: CoordinateType> IntoIterator for &'a mut MultiPoint { +impl<'a, T: CoordNum> IntoIterator for &'a mut MultiPoint { type Item = &'a mut Point; type IntoIter = ::std::slice::IterMut<'a, Point>; @@ -85,7 +85,7 @@ impl<'a, T: CoordinateType> IntoIterator for &'a mut MultiPoint { } } -impl MultiPoint { +impl MultiPoint { pub fn iter(&self) -> impl Iterator> { self.0.iter() } @@ -98,7 +98,7 @@ impl MultiPoint { #[cfg(any(feature = "approx", test))] impl RelativeEq for MultiPoint where - T: AbsDiffEq + CoordinateType + RelativeEq, + T: AbsDiffEq + CoordNum + RelativeEq, { #[inline] fn default_max_relative() -> Self::Epsilon { @@ -137,7 +137,7 @@ where #[cfg(any(feature = "approx", test))] impl AbsDiffEq for MultiPoint where - T: AbsDiffEq + CoordinateType, + T: AbsDiffEq + CoordNum, T::Epsilon: Copy, { type Epsilon = T; diff --git a/geo-types/src/multi_polygon.rs b/geo-types/src/multi_polygon.rs index 1f44b2911..e01cca445 100644 --- a/geo-types/src/multi_polygon.rs +++ b/geo-types/src/multi_polygon.rs @@ -1,4 +1,4 @@ -use crate::{CoordinateType, Polygon}; +use crate::{CoordNum, Polygon}; use std::iter::FromIterator; /// A collection of [`Polygon`s](struct.Polygon.html). Can @@ -26,27 +26,27 @@ use std::iter::FromIterator; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct MultiPolygon(pub Vec>) where - T: CoordinateType; + T: CoordNum; -impl>> From for MultiPolygon { +impl>> From for MultiPolygon { fn from(x: IP) -> Self { MultiPolygon(vec![x.into()]) } } -impl>> From> for MultiPolygon { +impl>> From> for MultiPolygon { fn from(x: Vec) -> Self { MultiPolygon(x.into_iter().map(|p| p.into()).collect()) } } -impl>> FromIterator for MultiPolygon { +impl>> FromIterator for MultiPolygon { fn from_iter>(iter: I) -> Self { MultiPolygon(iter.into_iter().map(|p| p.into()).collect()) } } -impl IntoIterator for MultiPolygon { +impl IntoIterator for MultiPolygon { type Item = Polygon; type IntoIter = ::std::vec::IntoIter>; @@ -55,7 +55,7 @@ impl IntoIterator for MultiPolygon { } } -impl<'a, T: CoordinateType> IntoIterator for &'a MultiPolygon { +impl<'a, T: CoordNum> IntoIterator for &'a MultiPolygon { type Item = &'a Polygon; type IntoIter = ::std::slice::Iter<'a, Polygon>; @@ -64,7 +64,7 @@ impl<'a, T: CoordinateType> IntoIterator for &'a MultiPolygon { } } -impl<'a, T: CoordinateType> IntoIterator for &'a mut MultiPolygon { +impl<'a, T: CoordNum> IntoIterator for &'a mut MultiPolygon { type Item = &'a mut Polygon; type IntoIter = ::std::slice::IterMut<'a, Polygon>; @@ -73,7 +73,7 @@ impl<'a, T: CoordinateType> IntoIterator for &'a mut MultiPolygon { } } -impl MultiPolygon { +impl MultiPolygon { pub fn iter(&self) -> impl Iterator> { self.0.iter() } diff --git a/geo-types/src/point.rs b/geo-types/src/point.rs index 87c2afa68..d15791c7f 100644 --- a/geo-types/src/point.rs +++ b/geo-types/src/point.rs @@ -1,9 +1,8 @@ -use crate::{Coordinate, CoordinateType}; +use crate::{CoordFloat, CoordNum, Coordinate}; #[cfg(any(feature = "approx", test))] use approx::{AbsDiffEq, RelativeEq}; -use num_traits::Float; use std::ops::{Add, Div, Mul, Neg, Sub}; /// A single point in 2D space. @@ -31,21 +30,21 @@ use std::ops::{Add, Div, Mul, Neg, Sub}; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Point(pub Coordinate) where - T: CoordinateType; + T: CoordNum; -impl From> for Point { +impl From> for Point { fn from(x: Coordinate) -> Point { Point(x) } } -impl From<(T, T)> for Point { +impl From<(T, T)> for Point { fn from(coords: (T, T)) -> Point { Point::new(coords.0, coords.1) } } -impl From<[T; 2]> for Point { +impl From<[T; 2]> for Point { fn from(coords: [T; 2]) -> Point { Point::new(coords[0], coords[1]) } @@ -53,7 +52,7 @@ impl From<[T; 2]> for Point { impl Point where - T: CoordinateType, + T: CoordNum, { /// Creates a new point. /// @@ -215,7 +214,7 @@ where impl Point where - T: CoordinateType, + T: CoordNum, { /// Returns the dot product of the two points: /// `dot = x1 * x2 + y1 * y2` @@ -259,7 +258,7 @@ where impl Point where - T: CoordinateType + Float, + T: CoordFloat, { /// Converts the (x,y) components of Point to degrees /// @@ -300,7 +299,7 @@ where impl Neg for Point where - T: CoordinateType + Neg, + T: CoordNum + Neg, { type Output = Point; @@ -323,7 +322,7 @@ where impl Add for Point where - T: CoordinateType, + T: CoordNum, { type Output = Point; @@ -346,7 +345,7 @@ where impl Sub for Point where - T: CoordinateType, + T: CoordNum, { type Output = Point; @@ -369,7 +368,7 @@ where impl Mul for Point where - T: CoordinateType, + T: CoordNum, { type Output = Point; @@ -392,7 +391,7 @@ where impl Div for Point where - T: CoordinateType, + T: CoordNum, { type Output = Point; @@ -416,7 +415,7 @@ where #[cfg(any(feature = "approx", test))] impl RelativeEq for Point where - T: AbsDiffEq + CoordinateType + RelativeEq, + T: AbsDiffEq + CoordNum + RelativeEq, { #[inline] fn default_max_relative() -> Self::Epsilon { @@ -449,7 +448,7 @@ where #[cfg(any(feature = "approx", test))] impl AbsDiffEq for Point where - T: AbsDiffEq + CoordinateType, + T: AbsDiffEq + CoordNum, T::Epsilon: Copy, { type Epsilon = T::Epsilon; diff --git a/geo-types/src/polygon.rs b/geo-types/src/polygon.rs index 1ab4edad8..11c8139fa 100644 --- a/geo-types/src/polygon.rs +++ b/geo-types/src/polygon.rs @@ -1,4 +1,4 @@ -use crate::{CoordinateType, LineString, Point, Rect, Triangle}; +use crate::{CoordFloat, CoordNum, LineString, Point, Rect, Triangle}; use num_traits::{Float, Signed}; /// A bounded two-dimensional area. @@ -65,7 +65,7 @@ use num_traits::{Float, Signed}; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Polygon where - T: CoordinateType, + T: CoordNum, { exterior: LineString, interiors: Vec>, @@ -73,7 +73,7 @@ where impl Polygon where - T: CoordinateType, + T: CoordNum, { /// Create a new `Polygon` with the provided exterior `LineString` ring and /// interior `LineString` rings. @@ -407,7 +407,7 @@ enum ListSign { impl Polygon where - T: Float + Signed, + T: CoordFloat + Signed, { /// Determine whether a Polygon is convex // For each consecutive pair of edges of the polygon (each triplet of points), @@ -445,7 +445,7 @@ where } } -impl From> for Polygon { +impl From> for Polygon { fn from(r: Rect) -> Polygon { Polygon::new( vec![ @@ -461,7 +461,7 @@ impl From> for Polygon { } } -impl From> for Polygon { +impl From> for Polygon { fn from(t: Triangle) -> Polygon { Polygon::new(vec![t.0, t.1, t.2, t.0].into(), Vec::new()) } diff --git a/geo-types/src/private_utils.rs b/geo-types/src/private_utils.rs index b84f258be..25866e390 100644 --- a/geo-types/src/private_utils.rs +++ b/geo-types/src/private_utils.rs @@ -3,19 +3,18 @@ // 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::{Coordinate, CoordinateType, Line, LineString, Point, Rect}; -use num_traits::Float; +use crate::{CoordFloat, CoordNum, Coordinate, Line, LineString, Point, Rect}; pub fn line_string_bounding_rect(line_string: &LineString) -> Option> where - T: CoordinateType, + T: CoordNum, { get_bounding_rect(line_string.0.iter().cloned()) } pub fn line_bounding_rect(line: Line) -> Rect where - T: CoordinateType, + T: CoordNum, { let a = line.start; let b = line.end; @@ -30,7 +29,7 @@ where pub fn get_bounding_rect(collection: I) -> Option> where - T: CoordinateType, + T: CoordNum, I: IntoIterator>, { let mut iter = collection.into_iter(); @@ -59,7 +58,7 @@ where fn get_min_max(p: T, min: T, max: T) -> (T, T) where - T: CoordinateType, + T: CoordNum, { if p > max { (min, p) @@ -72,7 +71,7 @@ where pub fn line_segment_distance(point: C, start: C, end: C) -> T where - T: Float, + T: CoordFloat, C: Into>, { let point = point.into(); @@ -97,14 +96,14 @@ where pub fn line_euclidean_length(line: Line) -> T where - T: Float, + T: CoordFloat, { line.dx().hypot(line.dy()) } pub fn point_line_string_euclidean_distance(p: Point, l: &LineString) -> T where - T: Float, + T: CoordFloat, { // No need to continue if the point is on the LineString, or it's empty if line_string_contains_point(l, p) || l.0.is_empty() { @@ -117,14 +116,14 @@ where pub fn point_line_euclidean_distance(p: Point, l: Line) -> T where - T: Float, + T: CoordFloat, { line_segment_distance(p.0, l.start, l.end) } pub fn point_contains_point(p1: Point, p2: Point) -> bool where - T: Float, + T: CoordFloat, { let distance = line_euclidean_length(Line::new(p1, p2)).to_f32().unwrap(); approx::relative_eq!(distance, 0.0) @@ -132,7 +131,7 @@ where pub fn line_string_contains_point(line_string: &LineString, point: Point) -> bool where - T: Float, + T: CoordFloat, { // LineString without points if line_string.0.is_empty() { diff --git a/geo-types/src/rect.rs b/geo-types/src/rect.rs index ab7a404ff..991be1274 100644 --- a/geo-types/src/rect.rs +++ b/geo-types/src/rect.rs @@ -1,5 +1,4 @@ -use crate::{polygon, Coordinate, CoordinateType, Polygon}; -use num_traits::Float; +use crate::{polygon, CoordFloat, CoordNum, Coordinate, Polygon}; /// An _axis-aligned_ bounded 2D rectangle whose area is /// defined by minimum and maximum `Coordinate`s. @@ -39,13 +38,13 @@ use num_traits::Float; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Rect where - T: CoordinateType, + T: CoordNum, { min: Coordinate, max: Coordinate, } -impl Rect { +impl Rect { /// Creates a new rectangle from two corner coordinates. /// /// # Examples @@ -235,7 +234,7 @@ impl Rect { } } -impl Rect { +impl Rect { /// Returns the center `Coordinate` of the `Rect`. /// /// # Examples diff --git a/geo-types/src/triangle.rs b/geo-types/src/triangle.rs index 508648f87..42725f07c 100644 --- a/geo-types/src/triangle.rs +++ b/geo-types/src/triangle.rs @@ -1,4 +1,4 @@ -use crate::{polygon, Coordinate, CoordinateType, Line, Polygon}; +use crate::{polygon, CoordNum, Coordinate, Line, Polygon}; /// A bounded 2D area whose three vertices are defined by /// `Coordinate`s. The semantics and validity are that of @@ -6,9 +6,9 @@ use crate::{polygon, Coordinate, CoordinateType, Line, Polygon}; /// 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 Coordinate, pub Coordinate, pub Coordinate); +pub struct Triangle(pub Coordinate, pub Coordinate, pub Coordinate); -impl Triangle { +impl Triangle { pub fn to_array(&self) -> [Coordinate; 3] { [self.0, self.1, self.2] } @@ -49,7 +49,7 @@ impl Triangle { } } -impl> + Copy, T: CoordinateType> From<[IC; 3]> for Triangle { +impl> + Copy, T: CoordNum> From<[IC; 3]> for Triangle { fn from(array: [IC; 3]) -> Triangle { Triangle(array[0].into(), array[1].into(), array[2].into()) } diff --git a/geo/benches/concave_hull.rs b/geo/benches/concave_hull.rs index 99bc8b7ad..f778ff9b7 100644 --- a/geo/benches/concave_hull.rs +++ b/geo/benches/concave_hull.rs @@ -4,13 +4,13 @@ extern crate geo; use criterion::Criterion; use geo::algorithm::concave_hull::ConcaveHull; -use geo::{Coordinate, CoordinateType, LineString}; +use geo::{CoordNum, Coordinate, LineString}; use num_traits::Signed; use rand::distributions::uniform::SampleUniform; use rand::Rng; -pub fn uniform_points_in_range( +pub fn uniform_points_in_range( range: S, size: usize, rng: &mut R, diff --git a/geo/benches/convex_hull.rs b/geo/benches/convex_hull.rs index e5fae368e..54af15b87 100644 --- a/geo/benches/convex_hull.rs +++ b/geo/benches/convex_hull.rs @@ -4,12 +4,12 @@ extern crate geo; use criterion::Criterion; use geo::prelude::*; -use geo::{Coordinate, CoordinateType, LineString}; +use geo::{CoordNum, Coordinate, LineString}; use num_traits::Signed; use rand::distributions::uniform::SampleUniform; use rand::Rng; -pub fn uniform_points_in_range( +pub fn uniform_points_in_range( range: S, size: usize, rng: &mut R, diff --git a/geo/src/algorithm/area.rs b/geo/src/algorithm/area.rs index 502bc5183..7b77533b5 100644 --- a/geo/src/algorithm/area.rs +++ b/geo/src/algorithm/area.rs @@ -1,12 +1,11 @@ use crate::{ - CoordinateType, Geometry, GeometryCollection, Line, LineString, MultiLineString, MultiPoint, - MultiPolygon, Point, Polygon, Rect, Triangle, + CoordFloat, CoordNum, Geometry, GeometryCollection, Line, LineString, MultiLineString, + MultiPoint, MultiPolygon, Point, Polygon, Rect, Triangle, }; -use num_traits::Float; pub(crate) fn twice_signed_ring_area(linestring: &LineString) -> T where - T: CoordinateType, + T: CoordNum, { // LineString with less than 3 points is empty, or a // single point, or is not closed. @@ -70,7 +69,7 @@ where /// ``` pub trait Area where - T: CoordinateType, + T: CoordNum, { fn signed_area(&self) -> T; @@ -80,14 +79,14 @@ where // Calculation of simple (no interior holes) Polygon area pub(crate) fn get_linestring_area(linestring: &LineString) -> T where - T: Float, + T: CoordFloat, { twice_signed_ring_area(linestring) / (T::one() + T::one()) } impl Area for Point where - T: CoordinateType, + T: CoordNum, { fn signed_area(&self) -> T { T::zero() @@ -100,7 +99,7 @@ where impl Area for LineString where - T: CoordinateType, + T: CoordNum, { fn signed_area(&self) -> T { T::zero() @@ -113,7 +112,7 @@ where impl Area for Line where - T: CoordinateType, + T: CoordNum, { fn signed_area(&self) -> T { T::zero() @@ -129,7 +128,7 @@ where /// the output is the same as that of the exterior shell. impl Area for Polygon where - T: Float, + T: CoordFloat, { fn signed_area(&self) -> T { let area = get_linestring_area(self.exterior()); @@ -156,7 +155,7 @@ where impl Area for MultiPoint where - T: CoordinateType, + T: CoordNum, { fn signed_area(&self) -> T { T::zero() @@ -169,7 +168,7 @@ where impl Area for MultiLineString where - T: CoordinateType, + T: CoordNum, { fn signed_area(&self) -> T { T::zero() @@ -188,7 +187,7 @@ where /// same. impl Area for MultiPolygon where - T: Float, + T: CoordFloat, { fn signed_area(&self) -> T { self.0 @@ -206,7 +205,7 @@ where /// Because a `Rect` has no winding order, the area will always be positive. impl Area for Rect where - T: CoordinateType, + T: CoordNum, { fn signed_area(&self) -> T { self.width() * self.height() @@ -219,7 +218,7 @@ where impl Area for Triangle where - T: Float, + T: CoordFloat, { fn signed_area(&self) -> T { self.to_lines() @@ -235,7 +234,7 @@ where impl Area for Geometry where - T: Float, + T: CoordFloat, { fn signed_area(&self) -> T { match self { @@ -270,7 +269,7 @@ where impl Area for GeometryCollection where - T: Float, + T: CoordFloat, { fn signed_area(&self) -> T { self.0 diff --git a/geo/src/algorithm/bearing.rs b/geo/src/algorithm/bearing.rs index ed44f3061..a6ec6d883 100644 --- a/geo/src/algorithm/bearing.rs +++ b/geo/src/algorithm/bearing.rs @@ -1,12 +1,11 @@ -use crate::Point; -use num_traits::Float; +use crate::{CoordFloat, Point}; /// Returns the bearing to another Point in degrees. /// /// Bullock, R.: Great Circle Distances and Bearings Between Two Locations, 2007. /// (https://dtcenter.org/met/users/docs/write_ups/gc_simple.pdf) -pub trait Bearing { +pub trait Bearing { /// Returns the bearing to another Point in degrees, where North is 0° and East is 90°. /// /// # Examples @@ -27,7 +26,7 @@ pub trait Bearing { impl Bearing for Point where - T: Float, + T: CoordFloat, { fn bearing(&self, point: Point) -> T { let (lng_a, lat_a) = (self.x().to_radians(), self.y().to_radians()); diff --git a/geo/src/algorithm/bounding_rect.rs b/geo/src/algorithm/bounding_rect.rs index 781c68930..e82c558e5 100644 --- a/geo/src/algorithm/bounding_rect.rs +++ b/geo/src/algorithm/bounding_rect.rs @@ -1,12 +1,12 @@ use crate::utils::{partial_max, partial_min}; use crate::{ - Coordinate, CoordinateType, Geometry, GeometryCollection, Line, LineString, MultiLineString, + CoordNum, Coordinate, Geometry, GeometryCollection, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, Rect, Triangle, }; use geo_types::private_utils::{get_bounding_rect, line_string_bounding_rect}; /// Calculation of the bounding rectangle of a geometry. -pub trait BoundingRect { +pub trait BoundingRect { type Output; /// Return the bounding rectangle of a geometry @@ -35,7 +35,7 @@ pub trait BoundingRect { impl BoundingRect for Point where - T: CoordinateType, + T: CoordNum, { type Output = Rect; @@ -48,7 +48,7 @@ where impl BoundingRect for MultiPoint where - T: CoordinateType, + T: CoordNum, { type Output = Option>; @@ -61,7 +61,7 @@ where impl BoundingRect for Line where - T: CoordinateType, + T: CoordNum, { type Output = Rect; @@ -79,7 +79,7 @@ where impl BoundingRect for LineString where - T: CoordinateType, + T: CoordNum, { type Output = Option>; @@ -92,7 +92,7 @@ where impl BoundingRect for MultiLineString where - T: CoordinateType, + T: CoordNum, { type Output = Option>; @@ -105,7 +105,7 @@ where impl BoundingRect for Polygon where - T: CoordinateType, + T: CoordNum, { type Output = Option>; @@ -119,7 +119,7 @@ where impl BoundingRect for MultiPolygon where - T: CoordinateType, + T: CoordNum, { type Output = Option>; @@ -135,7 +135,7 @@ where impl BoundingRect for Triangle where - T: CoordinateType, + T: CoordNum, { type Output = Rect; @@ -146,7 +146,7 @@ where impl BoundingRect for Rect where - T: CoordinateType, + T: CoordNum, { type Output = Rect; @@ -157,7 +157,7 @@ where impl BoundingRect for Geometry where - T: CoordinateType, + T: CoordNum, { type Output = Option>; @@ -179,7 +179,7 @@ where impl BoundingRect for GeometryCollection where - T: CoordinateType, + T: CoordNum, { type Output = Option>; @@ -197,7 +197,7 @@ where } // Return a new rectangle that encompasses the provided rectangles -fn bounding_rect_merge(a: Rect, b: Rect) -> Rect { +fn bounding_rect_merge(a: Rect, b: Rect) -> Rect { Rect::new( Coordinate { x: partial_min(a.min().x, b.min().x), diff --git a/geo/src/algorithm/centroid.rs b/geo/src/algorithm/centroid.rs index b25644548..73a6c10fa 100644 --- a/geo/src/algorithm/centroid.rs +++ b/geo/src/algorithm/centroid.rs @@ -1,9 +1,11 @@ -use num_traits::{Float, FromPrimitive}; +use num_traits::FromPrimitive; use std::iter::Sum; use crate::algorithm::area::{get_linestring_area, Area}; use crate::algorithm::euclidean_length::EuclideanLength; -use crate::{Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, Rect}; +use crate::{ + CoordFloat, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, Rect, +}; /// Calculation of the centroid. /// The centroid is the arithmetic mean position of all points in the shape. @@ -59,7 +61,7 @@ pub trait Centroid { // Calculation of a Polygon centroid without interior rings fn simple_polygon_centroid(poly_ext: &LineString) -> Option> where - T: Float + FromPrimitive + Sum, + T: CoordFloat + FromPrimitive + Sum, { let area = get_linestring_area(poly_ext); if area == T::zero() { @@ -90,7 +92,7 @@ where impl Centroid for Line where - T: Float, + T: CoordFloat, { type Output = Point; @@ -104,7 +106,7 @@ where impl Centroid for LineString where - T: Float, + T: CoordFloat, { type Output = Option>; @@ -140,7 +142,7 @@ where impl Centroid for MultiLineString where - T: Float + FromPrimitive + Sum, + T: CoordFloat + FromPrimitive + Sum, { type Output = Option>; @@ -188,7 +190,7 @@ where impl Centroid for Polygon where - T: Float + FromPrimitive + Sum, + T: CoordFloat + FromPrimitive + Sum, { type Output = Option>; @@ -244,7 +246,7 @@ where impl Centroid for MultiPolygon where - T: Float + FromPrimitive + Sum, + T: CoordFloat + FromPrimitive + Sum, { type Output = Option>; @@ -299,7 +301,7 @@ where impl Centroid for Rect where - T: Float, + T: CoordFloat, { type Output = Point; @@ -310,7 +312,7 @@ where impl Centroid for Point where - T: Float, + T: CoordFloat, { type Output = Point; @@ -333,7 +335,7 @@ where /// ``` impl Centroid for MultiPoint where - T: Float, + T: CoordFloat, { type Output = Option>; @@ -358,17 +360,17 @@ mod test { use crate::algorithm::euclidean_distance::EuclideanDistance; use crate::line_string; use crate::{ - polygon, Coordinate, Line, LineString, MultiLineString, MultiPolygon, Point, Polygon, Rect, + polygon, CoordFloat, Coordinate, Line, LineString, MultiLineString, MultiPolygon, Point, + Polygon, Rect, }; - use num_traits::Float; /// small helper to create a coordinate - fn c(x: T, y: T) -> Coordinate { + fn c(x: T, y: T) -> Coordinate { Coordinate { x, y } } /// small helper to create a point - fn p(x: T, y: T) -> Point { + fn p(x: T, y: T) -> Point { Point(c(x, y)) } diff --git a/geo/src/algorithm/chamberlain_duquette_area.rs b/geo/src/algorithm/chamberlain_duquette_area.rs index 41eaded93..77fd1dae1 100644 --- a/geo/src/algorithm/chamberlain_duquette_area.rs +++ b/geo/src/algorithm/chamberlain_duquette_area.rs @@ -1,4 +1,4 @@ -use crate::{CoordinateType, LineString, Polygon, EQUATORIAL_EARTH_RADIUS}; +use crate::{CoordNum, LineString, Polygon, EQUATORIAL_EARTH_RADIUS}; use num_traits::Float; /// Calculate the signed approximate geodesic area of a `Geometry`. @@ -46,7 +46,7 @@ use num_traits::Float; /// ``` pub trait ChamberlainDuquetteArea where - T: Float + CoordinateType, + T: Float + CoordNum, { fn chamberlain_duquette_signed_area(&self) -> T; @@ -55,7 +55,7 @@ where impl ChamberlainDuquetteArea for Polygon where - T: Float + CoordinateType, + T: Float + CoordNum, { fn chamberlain_duquette_signed_area(&self) -> T { self.interiors() @@ -72,7 +72,7 @@ where fn ring_area(coords: &LineString) -> T where - T: Float + CoordinateType, + T: Float + CoordNum, { let mut total = T::zero(); let coords_len = coords.0.len(); diff --git a/geo/src/algorithm/concave_hull.rs b/geo/src/algorithm/concave_hull.rs index 0d585a32d..6416d4daa 100644 --- a/geo/src/algorithm/concave_hull.rs +++ b/geo/src/algorithm/concave_hull.rs @@ -6,7 +6,7 @@ use crate::utils::partial_min; use crate::{ GeoFloat, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, }; -use geo_types::{Coordinate, CoordinateType}; +use geo_types::{CoordNum, Coordinate}; use rstar::{RTree, RTreeNum}; use std::collections::VecDeque; @@ -45,7 +45,7 @@ use std::collections::VecDeque; /// assert_eq!(res.exterior(), &correct_hull); /// ``` pub trait ConcaveHull { - type Scalar: CoordinateType; + type Scalar: CoordNum; fn concave_hull(&self, concavity: Self::Scalar) -> Polygon; } diff --git a/geo/src/algorithm/contains/geometry.rs b/geo/src/algorithm/contains/geometry.rs index 7d1666886..d5d957a92 100644 --- a/geo/src/algorithm/contains/geometry.rs +++ b/geo/src/algorithm/contains/geometry.rs @@ -1,5 +1,4 @@ use super::Contains; -use crate::kernels::*; use crate::*; // ┌──────────────────────────────┐ @@ -8,7 +7,7 @@ use crate::*; impl Contains> for Geometry where - T: HasKernel, + T: GeoNum, { fn contains(&self, coord: &Coordinate) -> bool { match self { @@ -28,7 +27,7 @@ where impl Contains> for Geometry where - T: HasKernel, + T: GeoNum, { fn contains(&self, point: &Point) -> bool { self.contains(&point.0) @@ -41,7 +40,7 @@ where impl Contains> for GeometryCollection where - T: HasKernel, + T: GeoNum, { fn contains(&self, coord: &Coordinate) -> bool { self.iter().any(|geometry| geometry.contains(coord)) @@ -50,7 +49,7 @@ where impl Contains> for GeometryCollection where - T: HasKernel, + T: GeoNum, { fn contains(&self, point: &Point) -> bool { self.contains(&point.0) diff --git a/geo/src/algorithm/contains/line.rs b/geo/src/algorithm/contains/line.rs index 9b60b2e8e..d9912a83b 100644 --- a/geo/src/algorithm/contains/line.rs +++ b/geo/src/algorithm/contains/line.rs @@ -1,7 +1,6 @@ use super::Contains; use crate::intersects::Intersects; -use crate::kernels::*; -use crate::*; +use crate::{Coordinate, GeoNum, Line, LineString, Point}; // ┌──────────────────────────┐ // │ Implementations for Line │ @@ -9,7 +8,7 @@ use crate::*; impl Contains> for Line where - T: HasKernel, + T: GeoNum, { fn contains(&self, coord: &Coordinate) -> bool { if self.start == self.end { @@ -22,7 +21,7 @@ where impl Contains> for Line where - T: HasKernel, + T: GeoNum, { fn contains(&self, p: &Point) -> bool { self.contains(&p.0) @@ -31,7 +30,7 @@ where impl Contains> for Line where - T: HasKernel, + T: GeoNum, { fn contains(&self, line: &Line) -> bool { if line.start == line.end { @@ -44,7 +43,7 @@ where impl Contains> for Line where - T: HasKernel, + T: GeoNum, { fn contains(&self, linestring: &LineString) -> bool { // Empty linestring has no interior, and not diff --git a/geo/src/algorithm/contains/line_string.rs b/geo/src/algorithm/contains/line_string.rs index 961ace51b..8272208aa 100644 --- a/geo/src/algorithm/contains/line_string.rs +++ b/geo/src/algorithm/contains/line_string.rs @@ -1,7 +1,6 @@ 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 │ @@ -9,7 +8,7 @@ use intersects::Intersects; impl Contains> for LineString where - T: HasKernel, + T: GeoNum, { fn contains(&self, coord: &Coordinate) -> bool { if self.0.is_empty() { @@ -28,7 +27,7 @@ where impl Contains> for LineString where - T: HasKernel, + T: GeoNum, { fn contains(&self, p: &Point) -> bool { self.contains(&p.0) @@ -37,7 +36,7 @@ where impl Contains> for LineString where - T: HasKernel, + T: GeoNum, { fn contains(&self, line: &Line) -> bool { if line.start == line.end { @@ -107,7 +106,7 @@ where impl Contains> for LineString where - T: HasKernel, + T: GeoNum, { fn contains(&self, rhs: &LineString) -> bool { rhs.lines().all(|l| self.contains(&l)) @@ -119,7 +118,7 @@ where // └─────────────────────────────────────┘ impl Contains for MultiLineString where - T: CoordinateType, + T: CoordNum, LineString: Contains, { fn contains(&self, rhs: &G) -> bool { diff --git a/geo/src/algorithm/contains/point.rs b/geo/src/algorithm/contains/point.rs index 34a3bc305..7c72abc50 100644 --- a/geo/src/algorithm/contains/point.rs +++ b/geo/src/algorithm/contains/point.rs @@ -7,7 +7,7 @@ use crate::*; impl Contains> for Point where - T: CoordinateType, + T: CoordNum, { fn contains(&self, coord: &Coordinate) -> bool { &self.0 == coord @@ -16,7 +16,7 @@ where impl Contains> for Point where - T: CoordinateType, + T: CoordNum, { fn contains(&self, p: &Point) -> bool { self.contains(&p.0) @@ -28,7 +28,7 @@ where // └────────────────────────────────┘ impl Contains for MultiPoint where - T: CoordinateType, + T: CoordNum, Point: Contains, { fn contains(&self, rhs: &G) -> bool { diff --git a/geo/src/algorithm/contains/polygon.rs b/geo/src/algorithm/contains/polygon.rs index 2f2f4c2fe..6953438ba 100644 --- a/geo/src/algorithm/contains/polygon.rs +++ b/geo/src/algorithm/contains/polygon.rs @@ -1,7 +1,6 @@ use super::Contains; use crate::intersects::Intersects; -use crate::kernels::HasKernel; -use crate::{Coordinate, CoordinateType, Line, LineString, MultiPolygon, Point, Polygon}; +use crate::{CoordNum, Coordinate, GeoNum, Line, LineString, MultiPolygon, Point, Polygon}; // ┌─────────────────────────────┐ // │ Implementations for Polygon │ @@ -9,7 +8,7 @@ use crate::{Coordinate, CoordinateType, Line, LineString, MultiPolygon, Point, P impl Contains> for Polygon where - T: HasKernel, + T: GeoNum, { fn contains(&self, coord: &Coordinate) -> bool { use crate::algorithm::coordinate_position::{CoordPos, CoordinatePosition}; @@ -20,7 +19,7 @@ where impl Contains> for Polygon where - T: HasKernel, + T: GeoNum, { fn contains(&self, p: &Point) -> bool { self.contains(&p.0) @@ -31,7 +30,7 @@ where // line.start and line.end is on the boundaries impl Contains> for Polygon where - T: HasKernel, + T: GeoNum, { fn contains(&self, line: &Line) -> bool { // both endpoints are contained in the polygon and the line @@ -46,7 +45,7 @@ where // TODO: also check interiors impl Contains> for Polygon where - T: HasKernel, + T: GeoNum, { fn contains(&self, poly: &Polygon) -> bool { // decompose poly's exterior ring into Lines, and check each for containment @@ -57,7 +56,7 @@ where // TODO: ensure DE-9IM compliance impl Contains> for Polygon where - T: HasKernel, + T: GeoNum, { fn contains(&self, linestring: &LineString) -> bool { // All LineString points must be inside the Polygon @@ -80,7 +79,7 @@ where // TODO: ensure DE-9IM compliance impl Contains for MultiPolygon where - T: CoordinateType, + T: CoordNum, Polygon: Contains, { fn contains(&self, rhs: &G) -> bool { diff --git a/geo/src/algorithm/contains/rect.rs b/geo/src/algorithm/contains/rect.rs index d32a0eab4..39b04b522 100644 --- a/geo/src/algorithm/contains/rect.rs +++ b/geo/src/algorithm/contains/rect.rs @@ -7,7 +7,7 @@ use crate::*; impl Contains> for Rect where - T: CoordinateType, + T: CoordNum, { fn contains(&self, coord: &Coordinate) -> bool { coord.x > self.min().x @@ -19,7 +19,7 @@ where impl Contains> for Rect where - T: CoordinateType, + T: CoordNum, { fn contains(&self, p: &Point) -> bool { self.contains(&p.0) @@ -28,7 +28,7 @@ where impl Contains> for Rect where - T: CoordinateType, + T: CoordNum, { fn contains(&self, other: &Rect) -> bool { // TODO: check for degenerate rectangle (which is a line or a point) diff --git a/geo/src/algorithm/contains/triangle.rs b/geo/src/algorithm/contains/triangle.rs index a8cf84183..27fe10236 100644 --- a/geo/src/algorithm/contains/triangle.rs +++ b/geo/src/algorithm/contains/triangle.rs @@ -1,6 +1,5 @@ use super::Contains; -use crate::kernels::*; -use crate::*; +use crate::{Coordinate, GeoNum, LineString, Point, Triangle}; // ┌──────────────────────────────┐ // │ Implementations for Triangle │ @@ -8,18 +7,18 @@ use crate::*; impl Contains> for Triangle where - T: HasKernel, + T: GeoNum, { fn contains(&self, coord: &Coordinate) -> 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 Contains> for Triangle where - T: HasKernel, + T: GeoNum, { fn contains(&self, point: &Point) -> bool { self.contains(&point.0) diff --git a/geo/src/algorithm/convex_hull/graham.rs b/geo/src/algorithm/convex_hull/graham.rs index 186d8bd74..3a7127d3d 100644 --- a/geo/src/algorithm/convex_hull/graham.rs +++ b/geo/src/algorithm/convex_hull/graham.rs @@ -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 @@ -20,7 +20,7 @@ use crate::{Coordinate, LineString}; /// [Graham's scan]: //en.wikipedia.org/wiki/Graham_scan pub fn graham_hull(mut points: &mut [Coordinate], include_on_hull: bool) -> LineString where - T: HasKernel, + T: GeoNum, { if points.len() < 4 { // Nothing to build with fewer than four points. @@ -89,8 +89,7 @@ where mod test { use super::*; use crate::algorithm::is_convex::IsConvex; - use std::fmt::Debug; - fn test_convexity(initial: &[(T, T)]) { + fn test_convexity(initial: &[(T, T)]) { let mut v: Vec<_> = initial .iter() .map(|e| Coordinate::from((e.0, e.1))) diff --git a/geo/src/algorithm/convex_hull/mod.rs b/geo/src/algorithm/convex_hull/mod.rs index 3ba09c957..3264b6e41 100644 --- a/geo/src/algorithm/convex_hull/mod.rs +++ b/geo/src/algorithm/convex_hull/mod.rs @@ -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. /// @@ -38,13 +37,13 @@ use crate::*; /// assert_eq!(res.exterior(), &correct_hull); /// ``` pub trait ConvexHull { - type Scalar: CoordinateType; + type Scalar: GeoNum; fn convex_hull(&self) -> Polygon; } impl ConvexHull for Polygon where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn convex_hull(&self) -> Polygon { @@ -54,7 +53,7 @@ where impl ConvexHull for MultiPolygon where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn convex_hull(&self) -> Polygon { @@ -69,7 +68,7 @@ where impl ConvexHull for LineString where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn convex_hull(&self) -> Polygon { @@ -79,7 +78,7 @@ where impl ConvexHull for MultiLineString where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn convex_hull(&self) -> Polygon { @@ -90,7 +89,7 @@ where impl ConvexHull for MultiPoint where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn convex_hull(&self) -> Polygon { @@ -111,7 +110,7 @@ pub use graham::graham_hull; // required. fn trivial_hull(points: &mut [Coordinate], include_on_hull: bool) -> LineString where - T: HasKernel, + T: GeoNum, { assert!(points.len() < 4); diff --git a/geo/src/algorithm/convex_hull/qhull.rs b/geo/src/algorithm/convex_hull/qhull.rs index dfb737853..b01c54d63 100644 --- a/geo/src/algorithm/convex_hull/qhull.rs +++ b/geo/src/algorithm/convex_hull/qhull.rs @@ -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 @@ -11,16 +11,16 @@ use crate::{Coordinate, LineString}; #[inline] fn is_ccw(p_a: Coordinate, p_b: Coordinate, p_c: Coordinate) -> bool where - T: HasKernel, + T: GeoNum, { - let o = T::Ker::orient2d(p_a, p_b, p_c); + let o = ::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(mut points: &mut [Coordinate]) -> LineString where - T: HasKernel, + T: GeoNum, { // can't build a hull from fewer than four points if points.len() < 4 { @@ -70,7 +70,7 @@ fn hull_set( mut set: &mut [Coordinate], hull: &mut Vec>, ) where - T: HasKernel, + T: GeoNum, { if set.is_empty() { return; diff --git a/geo/src/algorithm/coordinate_position.rs b/geo/src/algorithm/coordinate_position.rs index 879fc7ff2..f2b3171f3 100644 --- a/geo/src/algorithm/coordinate_position.rs +++ b/geo/src/algorithm/coordinate_position.rs @@ -1,10 +1,9 @@ use crate::algorithm::{ bounding_rect::BoundingRect, dimensions::HasDimensions, intersects::Intersects, - kernels::HasKernel, }; use crate::{ - Coordinate, Geometry, GeometryCollection, Line, LineString, MultiLineString, MultiPoint, - MultiPolygon, Point, Polygon, Rect, Triangle, + Coordinate, GeoNum, Geometry, GeometryCollection, Line, LineString, MultiLineString, + MultiPoint, MultiPolygon, Point, Polygon, Rect, Triangle, }; /// The position of a `Coordinate` relative to a `Geometry` @@ -35,7 +34,7 @@ pub enum CoordPos { /// assert_eq!(square_poly.coordinate_position(&outside_coord), CoordPos::Outside); /// ``` pub trait CoordinatePosition { - type Scalar: HasKernel; + type Scalar: GeoNum; fn coordinate_position(&self, coord: &Coordinate) -> CoordPos { let mut is_inside = false; let mut boundary_count = 0; @@ -69,7 +68,7 @@ pub trait CoordinatePosition { impl CoordinatePosition for Coordinate where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn calculate_coordinate_position( @@ -86,7 +85,7 @@ where impl CoordinatePosition for Point where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn calculate_coordinate_position( @@ -103,7 +102,7 @@ where impl CoordinatePosition for Line where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn calculate_coordinate_position( @@ -129,7 +128,7 @@ where impl CoordinatePosition for LineString where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn calculate_coordinate_position( @@ -178,7 +177,7 @@ where impl CoordinatePosition for Triangle where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn calculate_coordinate_position( @@ -195,7 +194,7 @@ where impl CoordinatePosition for Rect where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn calculate_coordinate_position( @@ -212,7 +211,7 @@ where impl CoordinatePosition for MultiPoint where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn calculate_coordinate_position( @@ -229,7 +228,7 @@ where impl CoordinatePosition for Polygon where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn calculate_coordinate_position( @@ -274,7 +273,7 @@ where impl CoordinatePosition for MultiLineString where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn calculate_coordinate_position( @@ -291,7 +290,7 @@ where impl CoordinatePosition for MultiPolygon where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn calculate_coordinate_position( @@ -308,7 +307,7 @@ where impl CoordinatePosition for GeometryCollection where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn calculate_coordinate_position( @@ -325,7 +324,7 @@ where impl CoordinatePosition for Geometry where - T: HasKernel, + T: GeoNum, { type Scalar = T; fn calculate_coordinate_position( @@ -377,7 +376,7 @@ where /// closed `LineString`. pub fn coord_pos_relative_to_ring(coord: Coordinate, linestring: &LineString) -> CoordPos where - T: HasKernel, + T: GeoNum, { // Use the ray-tracing algorithm: count #times a // horizontal ray from point (to positive infinity). diff --git a/geo/src/algorithm/coords_iter.rs b/geo/src/algorithm/coords_iter.rs index da1b26380..6509c0b6d 100644 --- a/geo/src/algorithm/coords_iter.rs +++ b/geo/src/algorithm/coords_iter.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; use crate::{ - Coordinate, CoordinateType, Geometry, GeometryCollection, Line, LineString, MultiLineString, + CoordNum, Coordinate, Geometry, GeometryCollection, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, Rect, Triangle, }; @@ -13,7 +13,7 @@ type CoordinateChainOnce = iter::Chain>, iter::Once< pub trait CoordsIter<'a> { type Iter: Iterator>; type ExteriorIter: Iterator>; - type Scalar: CoordinateType; + type Scalar: CoordNum; /// Iterate over all exterior and (if any) interior coordinates of a geometry. /// @@ -97,7 +97,7 @@ pub trait CoordsIter<'a> { // │ Implementation for Point │ // └──────────────────────────┘ -impl<'a, T: CoordinateType> CoordsIter<'a> for Point { +impl<'a, T: CoordNum> CoordsIter<'a> for Point { type Iter = iter::Once>; type ExteriorIter = Self::Iter; type Scalar = T; @@ -120,7 +120,7 @@ impl<'a, T: CoordinateType> CoordsIter<'a> for Point { // │ Implementation for Line │ // └─────────────────────────┘ -impl<'a, T: CoordinateType> CoordsIter<'a> for Line { +impl<'a, T: CoordNum> CoordsIter<'a> for Line { type Iter = iter::Chain>, iter::Once>>; type ExteriorIter = Self::Iter; type Scalar = T; @@ -145,7 +145,7 @@ impl<'a, T: CoordinateType> CoordsIter<'a> for Line { type LineStringIter<'a, T> = iter::Copied>>; -impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for LineString { +impl<'a, T: CoordNum + 'a> CoordsIter<'a> for LineString { type Iter = LineStringIter<'a, T>; type ExteriorIter = Self::Iter; type Scalar = T; @@ -173,7 +173,7 @@ type PolygonIter<'a, T> = iter::Chain< iter::Flatten>, LineString>>, >; -impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for Polygon { +impl<'a, T: CoordNum + 'a> CoordsIter<'a> for Polygon { type Iter = PolygonIter<'a, T>; type ExteriorIter = LineStringIter<'a, T>; type Scalar = T; @@ -203,7 +203,7 @@ impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for Polygon { // │ Implementation for MultiPoint │ // └───────────────────────────────┘ -impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for MultiPoint { +impl<'a, T: CoordNum + 'a> CoordsIter<'a> for MultiPoint { type Iter = iter::Flatten>, Point>>; type ExteriorIter = Self::Iter; type Scalar = T; @@ -226,7 +226,7 @@ impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for MultiPoint { // │ Implementation for MultiLineString │ // └────────────────────────────────────┘ -impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for MultiLineString { +impl<'a, T: CoordNum + 'a> CoordsIter<'a> for MultiLineString { type Iter = iter::Flatten>, LineString>>; type ExteriorIter = Self::Iter; type Scalar = T; @@ -252,7 +252,7 @@ impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for MultiLineString { // │ Implementation for MultiPolygon │ // └─────────────────────────────────┘ -impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for MultiPolygon { +impl<'a, T: CoordNum + 'a> CoordsIter<'a> for MultiPolygon { type Iter = iter::Flatten>, Polygon>>; type ExteriorIter = iter::Flatten>, Polygon>>; @@ -276,7 +276,7 @@ impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for MultiPolygon { // │ Implementation for GeometryCollection │ // └───────────────────────────────────────┘ -impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for GeometryCollection { +impl<'a, T: CoordNum + 'a> CoordsIter<'a> for GeometryCollection { type Iter = Box> + 'a>; type ExteriorIter = Box> + 'a>; type Scalar = T; @@ -308,7 +308,7 @@ type RectIter = iter::Chain< iter::Once>, >; -impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for Rect { +impl<'a, T: CoordNum + 'a> CoordsIter<'a> for Rect { type Iter = RectIter; type ExteriorIter = Self::Iter; type Scalar = T; @@ -349,7 +349,7 @@ impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for Rect { // │ Implementation for Triangle │ // └─────────────────────────────┘ -impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for Triangle { +impl<'a, T: CoordNum + 'a> CoordsIter<'a> for Triangle { type Iter = iter::Chain, iter::Once>>; type ExteriorIter = Self::Iter; type Scalar = T; @@ -374,7 +374,7 @@ impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for Triangle { // │ Implementation for Geometry │ // └─────────────────────────────┘ -impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for Geometry { +impl<'a, T: CoordNum + 'a> CoordsIter<'a> for Geometry { type Iter = GeometryCoordsIter<'a, T>; type ExteriorIter = GeometryExteriorCoordsIter<'a, T>; type Scalar = T; @@ -447,12 +447,12 @@ impl<'a, T: CoordinateType + 'a> CoordsIter<'a> for Geometry { #[derive(Debug)] pub struct MapCoordsIter< 'a, - T: 'a + CoordinateType, + T: 'a + CoordNum, Iter1: Iterator, Iter2: 'a + CoordsIter<'a>, >(Iter1, marker::PhantomData); -impl<'a, T: 'a + CoordinateType, Iter1: Iterator, Iter2: CoordsIter<'a>> Iterator +impl<'a, T: 'a + CoordNum, Iter1: Iterator, Iter2: CoordsIter<'a>> Iterator for MapCoordsIter<'a, T, Iter1, Iter2> { type Item = Iter2::Iter; @@ -471,12 +471,12 @@ impl<'a, T: 'a + CoordinateType, Iter1: Iterator, Iter2: Coord #[derive(Debug)] pub struct MapExteriorCoordsIter< 'a, - T: 'a + CoordinateType, + T: 'a + CoordNum, Iter1: Iterator, Iter2: 'a + CoordsIter<'a>, >(Iter1, marker::PhantomData); -impl<'a, T: 'a + CoordinateType, Iter1: Iterator, Iter2: CoordsIter<'a>> Iterator +impl<'a, T: 'a + CoordNum, Iter1: Iterator, Iter2: CoordsIter<'a>> Iterator for MapExteriorCoordsIter<'a, T, Iter1, Iter2> { type Item = Iter2::ExteriorIter; @@ -492,7 +492,7 @@ impl<'a, T: 'a + CoordinateType, Iter1: Iterator, Iter2: Coord // Utility to transform Geometry into Iterator #[doc(hidden)] -pub enum GeometryCoordsIter<'a, T: CoordinateType + 'a> { +pub enum GeometryCoordsIter<'a, T: CoordNum + 'a> { Point( as CoordsIter<'a>>::Iter), Line( as CoordsIter<'a>>::Iter), LineString( as CoordsIter<'a>>::Iter), @@ -505,7 +505,7 @@ pub enum GeometryCoordsIter<'a, T: CoordinateType + 'a> { Triangle( as CoordsIter<'a>>::Iter), } -impl<'a, T: CoordinateType> Iterator for GeometryCoordsIter<'a, T> { +impl<'a, T: CoordNum> Iterator for GeometryCoordsIter<'a, T> { type Item = Coordinate; fn next(&mut self) -> Option { @@ -539,7 +539,7 @@ impl<'a, T: CoordinateType> Iterator for GeometryCoordsIter<'a, T> { } } -impl<'a, T: CoordinateType + Debug> fmt::Debug for GeometryCoordsIter<'a, T> { +impl<'a, T: CoordNum + Debug> fmt::Debug for GeometryCoordsIter<'a, T> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match self { GeometryCoordsIter::Point(i) => fmt.debug_tuple("Point").field(i).finish(), @@ -565,7 +565,7 @@ impl<'a, T: CoordinateType + Debug> fmt::Debug for GeometryCoordsIter<'a, T> { // Utility to transform Geometry into Iterator #[doc(hidden)] -pub enum GeometryExteriorCoordsIter<'a, T: CoordinateType + 'a> { +pub enum GeometryExteriorCoordsIter<'a, T: CoordNum + 'a> { Point( as CoordsIter<'a>>::ExteriorIter), Line( as CoordsIter<'a>>::ExteriorIter), LineString( as CoordsIter<'a>>::ExteriorIter), @@ -578,7 +578,7 @@ pub enum GeometryExteriorCoordsIter<'a, T: CoordinateType + 'a> { Triangle( as CoordsIter<'a>>::ExteriorIter), } -impl<'a, T: CoordinateType> Iterator for GeometryExteriorCoordsIter<'a, T> { +impl<'a, T: CoordNum> Iterator for GeometryExteriorCoordsIter<'a, T> { type Item = Coordinate; fn next(&mut self) -> Option { @@ -612,7 +612,7 @@ impl<'a, T: CoordinateType> Iterator for GeometryExteriorCoordsIter<'a, T> { } } -impl<'a, T: CoordinateType + Debug> fmt::Debug for GeometryExteriorCoordsIter<'a, T> { +impl<'a, T: CoordNum + Debug> fmt::Debug for GeometryExteriorCoordsIter<'a, T> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match self { GeometryExteriorCoordsIter::Point(i) => fmt.debug_tuple("Point").field(i).finish(), diff --git a/geo/src/algorithm/dimensions.rs b/geo/src/algorithm/dimensions.rs index eb0cafbe3..066df3dc5 100644 --- a/geo/src/algorithm/dimensions.rs +++ b/geo/src/algorithm/dimensions.rs @@ -1,5 +1,5 @@ use crate::{ - CoordinateType, Geometry, GeometryCollection, Line, LineString, MultiLineString, MultiPoint, + CoordNum, Geometry, GeometryCollection, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, Rect, Triangle, }; @@ -131,7 +131,7 @@ pub trait HasDimensions { fn boundary_dimensions(&self) -> Dimensions; } -impl HasDimensions for Geometry { +impl HasDimensions for Geometry { fn is_empty(&self) -> bool { match self { Geometry::Point(g) => g.is_empty(), @@ -178,7 +178,7 @@ impl HasDimensions for Geometry { } } -impl HasDimensions for Point { +impl HasDimensions for Point { fn is_empty(&self) -> bool { false } @@ -192,7 +192,7 @@ impl HasDimensions for Point { } } -impl HasDimensions for Line { +impl HasDimensions for Line { fn is_empty(&self) -> bool { false } @@ -216,7 +216,7 @@ impl HasDimensions for Line { } } -impl HasDimensions for LineString { +impl HasDimensions for LineString { fn is_empty(&self) -> bool { self.0.is_empty() } @@ -259,7 +259,7 @@ impl HasDimensions for LineString { } } -impl HasDimensions for Polygon { +impl HasDimensions for Polygon { fn is_empty(&self) -> bool { self.exterior().is_empty() } @@ -273,7 +273,7 @@ impl HasDimensions for Polygon { } } -impl HasDimensions for MultiPoint { +impl HasDimensions for MultiPoint { fn is_empty(&self) -> bool { self.0.is_empty() } @@ -291,7 +291,7 @@ impl HasDimensions for MultiPoint { } } -impl HasDimensions for MultiLineString { +impl HasDimensions for MultiLineString { fn is_empty(&self) -> bool { self.iter().all(LineString::is_empty) } @@ -326,7 +326,7 @@ impl HasDimensions for MultiLineString { } } -impl HasDimensions for MultiPolygon { +impl HasDimensions for MultiPolygon { fn is_empty(&self) -> bool { self.iter().all(Polygon::is_empty) } @@ -348,7 +348,7 @@ impl HasDimensions for MultiPolygon { } } -impl HasDimensions for GeometryCollection { +impl HasDimensions for GeometryCollection { fn is_empty(&self) -> bool { if self.0.is_empty() { true @@ -385,7 +385,7 @@ impl HasDimensions for GeometryCollection { } } -impl HasDimensions for Rect { +impl HasDimensions for Rect { fn is_empty(&self) -> bool { false } @@ -414,7 +414,7 @@ impl HasDimensions for Rect { } } -impl HasDimensions for Triangle { +impl HasDimensions for Triangle { fn is_empty(&self) -> bool { false } diff --git a/geo/src/algorithm/euclidean_distance.rs b/geo/src/algorithm/euclidean_distance.rs index b5f7915f8..40875c350 100644 --- a/geo/src/algorithm/euclidean_distance.rs +++ b/geo/src/algorithm/euclidean_distance.rs @@ -2,12 +2,10 @@ use crate::algorithm::contains::Contains; use crate::algorithm::euclidean_length::EuclideanLength; use crate::algorithm::intersects::Intersects; use crate::algorithm::polygon_distance_fast_path::*; -use crate::kernels::*; use crate::utils::{coord_pos_relative_to_ring, CoordPos}; -use crate::GeoFloat; use crate::{ - Coordinate, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, - Triangle, + Coordinate, GeoFloat, GeoNum, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, + Point, Polygon, Triangle, }; use num_traits::{float::FloatConst, Bounded, Float, Signed}; @@ -184,7 +182,7 @@ where impl EuclideanDistance> for Point where - T: GeoFloat + HasKernel, + T: GeoFloat, { /// Minimum distance from a Point to a Polygon fn euclidean_distance(&self, polygon: &Polygon) -> T { @@ -215,7 +213,7 @@ where impl EuclideanDistance> for Point where - T: GeoFloat + HasKernel, + T: GeoFloat, { /// Minimum distance from a Point to a MultiPolygon fn euclidean_distance(&self, mpolygon: &MultiPolygon) -> T { @@ -268,7 +266,7 @@ where /// Line to Line distance impl EuclideanDistance> for Line where - T: GeoFloat + FloatConst + Signed + RTreeNum + HasKernel, + T: GeoFloat + FloatConst + Signed + RTreeNum, { fn euclidean_distance(&self, other: &Line) -> T { if self.intersects(other) || self.contains(other) { @@ -286,7 +284,7 @@ where /// Line to LineString impl EuclideanDistance> for Line where - T: GeoFloat + FloatConst + Signed + RTreeNum + HasKernel, + T: GeoFloat + FloatConst + Signed + RTreeNum, { fn euclidean_distance(&self, other: &LineString) -> T { other.euclidean_distance(self) @@ -296,7 +294,7 @@ where // Line to Polygon distance impl EuclideanDistance> for Line where - T: GeoFloat + Signed + RTreeNum + FloatConst + HasKernel, + T: GeoFloat + Signed + RTreeNum + FloatConst, { fn euclidean_distance(&self, other: &Polygon) -> T { if other.contains(self) || self.intersects(other) { @@ -330,7 +328,7 @@ where /// Line to MultiPolygon distance impl EuclideanDistance> for Line where - T: GeoFloat + FloatConst + Signed + RTreeNum + HasKernel, + T: GeoFloat + FloatConst + Signed + RTreeNum, { fn euclidean_distance(&self, mpolygon: &MultiPolygon) -> T { mpolygon @@ -358,7 +356,7 @@ where /// LineString to Line impl EuclideanDistance> for LineString where - T: GeoFloat + FloatConst + Signed + RTreeNum + HasKernel, + T: GeoFloat + FloatConst + Signed + RTreeNum, { fn euclidean_distance(&self, other: &Line) -> T { self.lines().fold(Bounded::max_value(), |acc, line| { @@ -370,7 +368,7 @@ where /// LineString-LineString distance impl EuclideanDistance> for LineString where - T: GeoFloat + HasKernel + Signed + RTreeNum, + T: GeoFloat + Signed + RTreeNum, { fn euclidean_distance(&self, other: &LineString) -> T { if self.intersects(other) { @@ -384,7 +382,7 @@ where /// LineString to Polygon impl EuclideanDistance> for LineString where - T: GeoFloat + FloatConst + Signed + RTreeNum + HasKernel, + T: GeoFloat + FloatConst + Signed + RTreeNum, { fn euclidean_distance(&self, other: &Polygon) -> T { if self.intersects(other) || other.contains(self) { @@ -422,7 +420,7 @@ where impl EuclideanDistance> for Polygon where - T: GeoFloat + HasKernel, + T: GeoFloat, { /// Minimum distance from a Polygon to a Point fn euclidean_distance(&self, point: &Point) -> T { @@ -433,7 +431,7 @@ where // Polygon to Line distance impl EuclideanDistance> for Polygon where - T: GeoFloat + FloatConst + Signed + RTreeNum + HasKernel, + T: GeoFloat + FloatConst + Signed + RTreeNum, { fn euclidean_distance(&self, other: &Line) -> T { other.euclidean_distance(self) @@ -443,7 +441,7 @@ where /// Polygon to LineString distance impl EuclideanDistance> for Polygon where - T: GeoFloat + FloatConst + Signed + RTreeNum + HasKernel, + T: GeoFloat + FloatConst + Signed + RTreeNum, { fn euclidean_distance(&self, other: &LineString) -> T { other.euclidean_distance(self) @@ -453,7 +451,7 @@ where // Polygon to Polygon distance impl EuclideanDistance> for Polygon where - T: GeoFloat + FloatConst + RTreeNum + HasKernel, + T: GeoFloat + FloatConst + RTreeNum, { /// This implementation has a "fast path" in cases where both input polygons are convex: /// it switches to an implementation of the "rotating calipers" method described in [Pirzadeh (1999), pp24—30](http://digitool.library.mcgill.ca/R/?func=dbin-jump-full&object_id=21623&local_base=GEN01-MCG02), @@ -495,7 +493,7 @@ where impl EuclideanDistance> for MultiPolygon where - T: GeoFloat + HasKernel, + T: GeoFloat, { /// Minimum distance from a MultiPolygon to a Point fn euclidean_distance(&self, point: &Point) -> T { @@ -506,7 +504,7 @@ where /// MultiPolygon to Line distance impl EuclideanDistance> for MultiPolygon where - T: GeoFloat + FloatConst + Signed + RTreeNum + HasKernel, + T: GeoFloat + FloatConst + Signed + RTreeNum, { fn euclidean_distance(&self, other: &Line) -> T { other.euclidean_distance(self) @@ -519,7 +517,7 @@ where impl EuclideanDistance> for Triangle where - T: GeoFloat + HasKernel, + T: GeoFloat, { fn euclidean_distance(&self, point: &Point) -> T { if self.contains(point) { @@ -543,7 +541,7 @@ where /// contain a point from the candidate Polygon's outer shell in their simple representations fn ring_contains_point(poly: &Polygon, p: Point) -> bool where - T: HasKernel, + T: GeoNum, { match coord_pos_relative_to_ring(p.0, &poly.exterior()) { CoordPos::Inside => true, diff --git a/geo/src/algorithm/euclidean_length.rs b/geo/src/algorithm/euclidean_length.rs index b18ecfd4f..9f20ff773 100644 --- a/geo/src/algorithm/euclidean_length.rs +++ b/geo/src/algorithm/euclidean_length.rs @@ -1,7 +1,6 @@ -use num_traits::Float; use std::iter::Sum; -use crate::{Line, LineString, MultiLineString}; +use crate::{CoordFloat, Line, LineString, MultiLineString}; /// Calculation of the length @@ -29,7 +28,7 @@ pub trait EuclideanLength { impl EuclideanLength for Line where - T: Float, + T: CoordFloat, { fn euclidean_length(&self) -> T { ::geo_types::private_utils::line_euclidean_length(*self) @@ -38,7 +37,7 @@ where impl EuclideanLength for LineString where - T: Float + Sum, + T: CoordFloat + Sum, { fn euclidean_length(&self) -> T { self.lines().map(|line| line.euclidean_length()).sum() @@ -47,7 +46,7 @@ where impl EuclideanLength for MultiLineString where - T: Float + Sum, + T: CoordFloat + Sum, { fn euclidean_length(&self) -> T { self.0 diff --git a/geo/src/algorithm/extremes.rs b/geo/src/algorithm/extremes.rs index 4a597de1c..2122c5836 100644 --- a/geo/src/algorithm/extremes.rs +++ b/geo/src/algorithm/extremes.rs @@ -1,5 +1,5 @@ use crate::algorithm::coords_iter::CoordsIter; -use crate::{Coordinate, CoordinateType}; +use crate::{CoordNum, Coordinate}; /// Find the extreme coordinates and indices of a geometry. /// @@ -24,18 +24,18 @@ use crate::{Coordinate, CoordinateType}; /// assert_eq!(extremes.y_max.coord.x, 1.); /// assert_eq!(extremes.y_max.coord.y, 2.); /// ``` -pub trait Extremes<'a, T: CoordinateType> { +pub trait Extremes<'a, T: CoordNum> { fn extremes(&'a self) -> Option>; } #[derive(Debug, PartialEq)] -pub struct Extreme { +pub struct Extreme { pub index: usize, pub coord: Coordinate, } #[derive(Debug, PartialEq)] -pub struct Outcome { +pub struct Outcome { pub x_min: Extreme, pub y_min: Extreme, pub x_max: Extreme, @@ -45,7 +45,7 @@ pub struct Outcome { impl<'a, T, G> Extremes<'a, T> for G where G: CoordsIter<'a, Scalar = T>, - T: CoordinateType, + T: CoordNum, { fn extremes(&'a self) -> Option> { let mut iter = self.exterior_coords_iter().enumerate(); diff --git a/geo/src/algorithm/haversine_destination.rs b/geo/src/algorithm/haversine_destination.rs index b6bc232cb..ab995e6f4 100644 --- a/geo/src/algorithm/haversine_destination.rs +++ b/geo/src/algorithm/haversine_destination.rs @@ -1,11 +1,11 @@ -use crate::{Point, MEAN_EARTH_RADIUS}; -use num_traits::{Float, FromPrimitive}; +use crate::{CoordFloat, Point, MEAN_EARTH_RADIUS}; +use num_traits::FromPrimitive; /// Returns a new Point using the distance to the existing Point and a bearing for the direction /// /// *Note*: this implementation uses a mean earth radius of 6371.088 km, based on the [recommendation of /// the IUGG](ftp://athena.fsv.cvut.cz/ZFG/grs80-Moritz.pdf) -pub trait HaversineDestination { +pub trait HaversineDestination { /// Returns a new Point using distance to the existing Point and a bearing for the direction /// /// # Units @@ -28,7 +28,7 @@ pub trait HaversineDestination { impl HaversineDestination for Point where - T: Float + FromPrimitive, + T: CoordFloat + FromPrimitive, { fn haversine_destination(&self, bearing: T, distance: T) -> Point { let center_lng = self.x().to_radians(); @@ -67,10 +67,9 @@ mod test { fn direct_and_indirect_destinations_are_close() { let p_1 = Point::::new(9.177789688110352, 48.776781529534965); let p_2 = p_1.haversine_destination(45., 10000.); - let square_edge = { pow(10000., 2) / 2. }.sqrt(); + let square_edge = { pow(10000., 2) / 2f64 }.sqrt(); let p_3 = p_1.haversine_destination(0., square_edge); let p_4 = p_3.haversine_destination(90., square_edge); - assert_relative_eq!(p_4.x(), p_2.x(), epsilon = 1.0e-6); - assert_relative_eq!(p_4.y(), p_2.y(), epsilon = 1.0e-6); + assert_relative_eq!(p_4, p_2, epsilon = 1.0e-6); } } diff --git a/geo/src/algorithm/haversine_distance.rs b/geo/src/algorithm/haversine_distance.rs index ece7bf54c..ace3f65ea 100644 --- a/geo/src/algorithm/haversine_distance.rs +++ b/geo/src/algorithm/haversine_distance.rs @@ -1,5 +1,5 @@ -use crate::{Point, MEAN_EARTH_RADIUS}; -use num_traits::{Float, FromPrimitive}; +use crate::{CoordFloat, Point, MEAN_EARTH_RADIUS}; +use num_traits::FromPrimitive; /// Determine the distance between two geometries using the [haversine formula]. /// @@ -41,7 +41,7 @@ pub trait HaversineDistance { impl HaversineDistance> for Point where - T: Float + FromPrimitive, + T: CoordFloat + FromPrimitive, { fn haversine_distance(&self, rhs: &Point) -> T { let two = T::one() + T::one(); diff --git a/geo/src/algorithm/haversine_intermediate.rs b/geo/src/algorithm/haversine_intermediate.rs index 29210d994..144eeac3a 100644 --- a/geo/src/algorithm/haversine_intermediate.rs +++ b/geo/src/algorithm/haversine_intermediate.rs @@ -1,9 +1,9 @@ -use crate::{Point, MEAN_EARTH_RADIUS}; -use num_traits::{Float, FromPrimitive}; +use crate::{CoordFloat, Point, MEAN_EARTH_RADIUS}; +use num_traits::FromPrimitive; /// Returns a new Point along a great circle route between two existing points -pub trait HaversineIntermediate { +pub trait HaversineIntermediate { /// Returns a new Point along a great circle route between two existing points. /// /// # Examples @@ -41,7 +41,7 @@ pub trait HaversineIntermediate { impl HaversineIntermediate for Point where - T: Float + FromPrimitive, + T: CoordFloat + FromPrimitive, { fn haversine_intermediate(&self, other: &Point, f: T) -> Point { let params = get_params(&self, &other); @@ -88,7 +88,7 @@ where } #[allow(clippy::many_single_char_names)] -struct HaversineParams { +struct HaversineParams { d: T, n: T, o: T, @@ -99,7 +99,7 @@ struct HaversineParams { } #[allow(clippy::many_single_char_names)] -fn get_point(params: &HaversineParams, f: T) -> Point { +fn get_point(params: &HaversineParams, f: T) -> Point { let one = T::one(); let HaversineParams { @@ -126,7 +126,7 @@ fn get_point(params: &HaversineParams, f: T) -> Poi } #[allow(clippy::many_single_char_names)] -fn get_params(p1: &Point, p2: &Point) -> HaversineParams { +fn get_params(p1: &Point, p2: &Point) -> HaversineParams { let one = T::one(); let two = one + one; diff --git a/geo/src/algorithm/haversine_length.rs b/geo/src/algorithm/haversine_length.rs index ee0ec92ca..3b0ee385b 100644 --- a/geo/src/algorithm/haversine_length.rs +++ b/geo/src/algorithm/haversine_length.rs @@ -1,7 +1,7 @@ -use num_traits::{Float, FromPrimitive}; +use num_traits::FromPrimitive; use crate::algorithm::haversine_distance::HaversineDistance; -use crate::{Line, LineString, MultiLineString}; +use crate::{CoordFloat, Line, LineString, MultiLineString}; /// Determine the length of a geometry using the [haversine formula]. /// @@ -43,7 +43,7 @@ pub trait HaversineLength { impl HaversineLength for Line where - T: Float + FromPrimitive, + T: CoordFloat + FromPrimitive, { fn haversine_length(&self) -> T { let (start, end) = self.points(); @@ -53,7 +53,7 @@ where impl HaversineLength for LineString where - T: Float + FromPrimitive, + T: CoordFloat + FromPrimitive, { fn haversine_length(&self) -> T { self.lines().fold(T::zero(), |total_length, line| { @@ -64,7 +64,7 @@ where impl HaversineLength for MultiLineString where - T: Float + FromPrimitive, + T: CoordFloat + FromPrimitive, { fn haversine_length(&self) -> T { self.0 diff --git a/geo/src/algorithm/intersects/collections.rs b/geo/src/algorithm/intersects/collections.rs index ac0e280c9..25b5557fd 100644 --- a/geo/src/algorithm/intersects/collections.rs +++ b/geo/src/algorithm/intersects/collections.rs @@ -3,7 +3,7 @@ use crate::*; impl Intersects for Geometry where - T: CoordinateType, + T: CoordNum, Point: Intersects, MultiPoint: Intersects, Line: Intersects, @@ -36,7 +36,7 @@ symmetric_intersects_impl!(Polygon, Geometry); impl Intersects for GeometryCollection where - T: CoordinateType, + T: CoordNum, Geometry: Intersects, { fn intersects(&self, rhs: &G) -> bool { diff --git a/geo/src/algorithm/intersects/coordinate.rs b/geo/src/algorithm/intersects/coordinate.rs index c25798b58..d80075f6a 100644 --- a/geo/src/algorithm/intersects/coordinate.rs +++ b/geo/src/algorithm/intersects/coordinate.rs @@ -3,7 +3,7 @@ use crate::*; impl Intersects> for Coordinate where - T: CoordinateType, + T: CoordNum, { fn intersects(&self, rhs: &Coordinate) -> bool { self == rhs @@ -13,7 +13,7 @@ where // The other side of this is handled via a blanket impl. impl Intersects> for Coordinate where - T: CoordinateType, + T: CoordNum, { fn intersects(&self, rhs: &Point) -> bool { self == &rhs.0 diff --git a/geo/src/algorithm/intersects/line.rs b/geo/src/algorithm/intersects/line.rs index 2ab38c50f..c8b765065 100644 --- a/geo/src/algorithm/intersects/line.rs +++ b/geo/src/algorithm/intersects/line.rs @@ -4,7 +4,7 @@ use crate::*; impl Intersects> for Line where - T: HasKernel, + T: GeoNum, { fn intersects(&self, rhs: &Coordinate) -> bool { // First we check if the point is collinear with the line. @@ -19,7 +19,7 @@ symmetric_intersects_impl!(Line, Point); impl Intersects> for Line where - T: HasKernel, + T: GeoNum, { fn intersects(&self, line: &Line) -> bool { // Special case: self is equiv. to a point. diff --git a/geo/src/algorithm/intersects/line_string.rs b/geo/src/algorithm/intersects/line_string.rs index 2248a0078..f7d833b5e 100644 --- a/geo/src/algorithm/intersects/line_string.rs +++ b/geo/src/algorithm/intersects/line_string.rs @@ -4,7 +4,7 @@ use crate::*; // Blanket implementation using self.lines().any(). impl Intersects for LineString where - T: CoordinateType, + T: CoordNum, Line: Intersects, { fn intersects(&self, geom: &G) -> bool { @@ -17,7 +17,7 @@ symmetric_intersects_impl!(Line, LineString); // Blanket implementation from LineString impl Intersects for MultiLineString where - T: CoordinateType, + T: CoordNum, LineString: Intersects, { fn intersects(&self, rhs: &G) -> bool { diff --git a/geo/src/algorithm/intersects/mod.rs b/geo/src/algorithm/intersects/mod.rs index 17eed1f07..18d691eb2 100644 --- a/geo/src/algorithm/intersects/mod.rs +++ b/geo/src/algorithm/intersects/mod.rs @@ -55,7 +55,7 @@ macro_rules! symmetric_intersects_impl { impl $crate::algorithm::intersects::Intersects<$k> for $t where $k: $crate::algorithm::intersects::Intersects<$t>, - T: CoordinateType, + T: CoordNum, { fn intersects(&self, rhs: &$k) -> bool { rhs.intersects(self) @@ -102,7 +102,7 @@ where #[inline] fn point_in_rect(value: Coordinate, bound_1: Coordinate, bound_2: Coordinate) -> bool where - T: CoordinateType, + T: CoordNum, { value_in_between(value.x, bound_1.x, bound_2.x) && value_in_between(value.y, bound_1.y, bound_2.y) diff --git a/geo/src/algorithm/intersects/point.rs b/geo/src/algorithm/intersects/point.rs index 7e19f951f..d5947f82d 100644 --- a/geo/src/algorithm/intersects/point.rs +++ b/geo/src/algorithm/intersects/point.rs @@ -4,7 +4,7 @@ use crate::*; // Blanket implementation from Coordinate impl Intersects for Point where - T: CoordinateType, + T: CoordNum, Coordinate: Intersects, { fn intersects(&self, rhs: &G) -> bool { @@ -15,7 +15,7 @@ where // Blanket implementation from Point impl Intersects for MultiPoint where - T: CoordinateType, + T: CoordNum, Point: Intersects, { fn intersects(&self, rhs: &G) -> bool { diff --git a/geo/src/algorithm/intersects/polygon.rs b/geo/src/algorithm/intersects/polygon.rs index 7e39bf069..a113d3d36 100644 --- a/geo/src/algorithm/intersects/polygon.rs +++ b/geo/src/algorithm/intersects/polygon.rs @@ -1,11 +1,13 @@ use super::Intersects; -use crate::kernels::*; use crate::utils::{coord_pos_relative_to_ring, CoordPos}; -use crate::*; +use crate::{ + CoordNum, Coordinate, GeoNum, Line, LineString, MultiLineString, MultiPolygon, Point, Polygon, + Rect, +}; impl Intersects> for Polygon where - T: HasKernel, + T: GeoNum, { fn intersects(&self, p: &Coordinate) -> bool { coord_pos_relative_to_ring(*p, &self.exterior()) != CoordPos::Outside @@ -20,7 +22,7 @@ symmetric_intersects_impl!(Polygon, Point); impl Intersects> for Polygon where - T: HasKernel, + T: GeoNum, { fn intersects(&self, line: &Line) -> bool { self.exterior().intersects(line) @@ -35,7 +37,7 @@ symmetric_intersects_impl!(Polygon, MultiLineString); impl Intersects> for Polygon where - T: HasKernel, + T: GeoNum, { fn intersects(&self, rect: &Rect) -> bool { self.intersects(&rect.clone().to_polygon()) @@ -45,7 +47,7 @@ symmetric_intersects_impl!(Rect, Polygon); impl Intersects> for Polygon where - T: HasKernel, + T: GeoNum, { fn intersects(&self, polygon: &Polygon) -> bool { // self intersects (or contains) any line in polygon @@ -60,7 +62,7 @@ where impl Intersects for MultiPolygon where - T: HasKernel, + T: GeoNum, Polygon: Intersects, { fn intersects(&self, rhs: &G) -> bool { diff --git a/geo/src/algorithm/intersects/rect.rs b/geo/src/algorithm/intersects/rect.rs index 103e2081f..4d9182130 100644 --- a/geo/src/algorithm/intersects/rect.rs +++ b/geo/src/algorithm/intersects/rect.rs @@ -1,10 +1,9 @@ use super::{value_in_range, Intersects}; -use crate::kernels::*; use crate::*; impl Intersects> for Rect where - T: CoordinateType, + T: CoordNum, { fn intersects(&self, rhs: &Coordinate) -> bool { // Funnily, we don't use point_in_rect, as we know @@ -20,7 +19,7 @@ symmetric_intersects_impl!(Rect, MultiPoint); impl Intersects> for Rect where - T: CoordinateType, + T: CoordNum, { fn intersects(&self, other: &Rect) -> bool { let x_overlap = value_in_range(self.min().x, other.min().x, other.max().x) @@ -37,7 +36,7 @@ where // an allocation. impl Intersects> for Rect where - T: HasKernel, + T: GeoNum, { fn intersects(&self, rhs: &Line) -> bool { let lt = self.min(); diff --git a/geo/src/algorithm/intersects/triangle.rs b/geo/src/algorithm/intersects/triangle.rs index 8f116bab9..e2ff6bf7d 100644 --- a/geo/src/algorithm/intersects/triangle.rs +++ b/geo/src/algorithm/intersects/triangle.rs @@ -3,7 +3,7 @@ use crate::*; impl Intersects for Triangle where - T: CoordinateType, + T: CoordNum, Polygon: Intersects, { fn intersects(&self, rhs: &G) -> bool { diff --git a/geo/src/algorithm/kernels/mod.rs b/geo/src/algorithm/kernels/mod.rs index 7d8a95c2f..dbee159d0 100644 --- a/geo/src/algorithm/kernels/mod.rs +++ b/geo/src/algorithm/kernels/mod.rs @@ -1,4 +1,4 @@ -use crate::{Coordinate, CoordinateType}; +use crate::{CoordNum, Coordinate}; use num_traits::Zero; #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] @@ -10,7 +10,7 @@ pub enum Orientation { /// Kernel trait to provide predicates to operate on /// different scalar types. -pub trait Kernel { +pub trait Kernel { /// Gives the orientation of 3 2-dimensional points: /// ccw, cw or collinear (None) fn orient2d(p: Coordinate, q: Coordinate, r: Coordinate) -> Orientation { @@ -43,7 +43,7 @@ pub trait Kernel { } /// Marker trait to assign Kernel for scalars -pub trait HasKernel: CoordinateType { +pub trait HasKernel: CoordNum { type Ker: Kernel; } diff --git a/geo/src/algorithm/kernels/robust.rs b/geo/src/algorithm/kernels/robust.rs index 310babb45..d628ee485 100644 --- a/geo/src/algorithm/kernels/robust.rs +++ b/geo/src/algorithm/kernels/robust.rs @@ -1,6 +1,8 @@ -use super::{Kernel, Orientation}; +use super::{CoordNum, Kernel, Orientation}; use crate::Coordinate; +use num_traits::{Float, NumCast}; + /// Robust kernel that uses [fast robust /// predicates](//www.cs.cmu.edu/~quake/robust.html) to /// provide robust floating point predicates. Should only be @@ -9,8 +11,10 @@ use crate::Coordinate; #[derive(Default, Debug)] pub struct RobustKernel; -use num_traits::{Float, NumCast}; -impl Kernel for RobustKernel { +impl Kernel for RobustKernel +where + T: CoordNum + Float, +{ fn orient2d(p: Coordinate, q: Coordinate, r: Coordinate) -> Orientation { use robust::{orient2d, Coord}; diff --git a/geo/src/algorithm/kernels/simple.rs b/geo/src/algorithm/kernels/simple.rs index 8978c31ea..84c2aa5ab 100644 --- a/geo/src/algorithm/kernels/simple.rs +++ b/geo/src/algorithm/kernels/simple.rs @@ -1,5 +1,5 @@ use super::Kernel; -use crate::CoordinateType; +use crate::CoordNum; /// Simple kernel provides the direct implementation of the /// predicates. These are meant to be used with exact @@ -7,4 +7,4 @@ use crate::CoordinateType; #[derive(Default, Debug)] pub struct SimpleKernel; -impl Kernel for SimpleKernel {} +impl Kernel for SimpleKernel {} diff --git a/geo/src/algorithm/line_interpolate_point.rs b/geo/src/algorithm/line_interpolate_point.rs index 99801e536..6e352a88b 100644 --- a/geo/src/algorithm/line_interpolate_point.rs +++ b/geo/src/algorithm/line_interpolate_point.rs @@ -1,10 +1,7 @@ use crate::coords_iter::CoordsIter; -use num_traits::Float; use std::ops::AddAssign; -use crate::{ - algorithm::euclidean_length::EuclideanLength, CoordinateType, Line, LineString, Point, -}; +use crate::{algorithm::euclidean_length::EuclideanLength, CoordFloat, Line, LineString, Point}; /// Returns an option of the point that lies a given fraction along the line. /// @@ -34,7 +31,7 @@ use crate::{ /// assert_eq!(linestring.line_interpolate_point(0.75), Some(point!(x: 0.0, y: 0.5))); /// assert_eq!(linestring.line_interpolate_point(2.0), Some(point!(x: 0.0, y: 1.0))); /// ``` -pub trait LineInterpolatePoint { +pub trait LineInterpolatePoint { type Output; fn line_interpolate_point(&self, fraction: F) -> Self::Output; @@ -42,7 +39,7 @@ pub trait LineInterpolatePoint { impl LineInterpolatePoint for Line where - T: CoordinateType + Float, + T: CoordFloat, { type Output = Option>; @@ -72,7 +69,7 @@ where impl LineInterpolatePoint for LineString where - T: CoordinateType + Float + AddAssign + std::fmt::Debug, + T: CoordFloat + AddAssign + std::fmt::Debug, Line: EuclideanLength, LineString: EuclideanLength, { @@ -117,6 +114,7 @@ mod test { algorithm::{closest_point::ClosestPoint, line_locate_point::LineLocatePoint}, point, Coordinate, }; + use num_traits::Float; #[test] fn test_line_interpolate_point_line() { diff --git a/geo/src/algorithm/line_locate_point.rs b/geo/src/algorithm/line_locate_point.rs index 4fc846aba..623c70a68 100644 --- a/geo/src/algorithm/line_locate_point.rs +++ b/geo/src/algorithm/line_locate_point.rs @@ -1,8 +1,7 @@ use crate::{ algorithm::{euclidean_distance::EuclideanDistance, euclidean_length::EuclideanLength}, - CoordinateType, Line, LineString, Point, + CoordFloat, Line, LineString, Point, }; -use num_traits::Float; use std::ops::AddAssign; /// Returns a (option of the) fraction of the line's total length @@ -41,7 +40,7 @@ pub trait LineLocatePoint { impl LineLocatePoint> for Line where - T: CoordinateType + Float, + T: CoordFloat, { type Output = Option; type Rhs = Point; @@ -78,7 +77,7 @@ where impl LineLocatePoint> for LineString where - T: CoordinateType + Float + AddAssign, + T: CoordFloat + AddAssign, Line: EuclideanDistance> + EuclideanLength, LineString: EuclideanLength, { @@ -111,6 +110,7 @@ where mod test { use super::*; use crate::{point, Coordinate}; + use num_traits::Float; #[test] fn test_line_locate_point_line() { diff --git a/geo/src/algorithm/map_coords.rs b/geo/src/algorithm/map_coords.rs index 2d9379047..ecd343761 100644 --- a/geo/src/algorithm/map_coords.rs +++ b/geo/src/algorithm/map_coords.rs @@ -35,7 +35,7 @@ //! ``` use crate::{ - Coordinate, CoordinateType, Geometry, GeometryCollection, Line, LineString, MultiLineString, + CoordNum, Coordinate, Geometry, GeometryCollection, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, Rect, Triangle, }; use std::error::Error; @@ -71,8 +71,8 @@ pub trait MapCoords { /// ``` fn map_coords(&self, func: impl Fn(&(T, T)) -> (NT, NT) + Copy) -> Self::Output where - T: CoordinateType, - NT: CoordinateType; + T: CoordNum, + NT: CoordNum; } /// Map a fallible function over all the coordinates in a geometry, returning a Result @@ -135,8 +135,8 @@ pub trait TryMapCoords { func: impl Fn(&(T, T)) -> Result<(NT, NT), Box> + Copy, ) -> Result> where - T: CoordinateType, - NT: CoordinateType; + T: CoordNum, + NT: CoordNum; } /// Map a function over all the coordinates in an object in place @@ -156,10 +156,10 @@ pub trait MapCoordsInplace { /// ``` fn map_coords_inplace(&mut self, func: impl Fn(&(T, T)) -> (T, T) + Copy) where - T: CoordinateType; + T: CoordNum; } -impl MapCoords for Point { +impl MapCoords for Point { type Output = Point; fn map_coords(&self, func: impl Fn(&(T, T)) -> (NT, NT) + Copy) -> Self::Output { @@ -168,7 +168,7 @@ impl MapCoords for Point { } } -impl TryMapCoords for Point { +impl TryMapCoords for Point { type Output = Point; fn try_map_coords( @@ -180,7 +180,7 @@ impl TryMapCoords for Point { } } -impl MapCoordsInplace for Point { +impl MapCoordsInplace for Point { fn map_coords_inplace(&mut self, func: impl Fn(&(T, T)) -> (T, T)) { let new_point = func(&(self.0.x, self.0.y)); self.0.x = new_point.0; @@ -188,7 +188,7 @@ impl MapCoordsInplace for Point { } } -impl MapCoords for Line { +impl MapCoords for Line { type Output = Line; fn map_coords(&self, func: impl Fn(&(T, T)) -> (NT, NT) + Copy) -> Self::Output { @@ -199,7 +199,7 @@ impl MapCoords for Line { } } -impl TryMapCoords for Line { +impl TryMapCoords for Line { type Output = Line; fn try_map_coords( @@ -213,7 +213,7 @@ impl TryMapCoords for Line { } } -impl MapCoordsInplace for Line { +impl MapCoordsInplace for Line { fn map_coords_inplace(&mut self, func: impl Fn(&(T, T)) -> (T, T)) { let new_start = func(&(self.start.x, self.start.y)); self.start.x = new_start.0; @@ -225,7 +225,7 @@ impl MapCoordsInplace for Line { } } -impl MapCoords for LineString { +impl MapCoords for LineString { type Output = LineString; fn map_coords(&self, func: impl Fn(&(T, T)) -> (NT, NT) + Copy) -> Self::Output { @@ -237,7 +237,7 @@ impl MapCoords for LineString { } } -impl TryMapCoords for LineString { +impl TryMapCoords for LineString { type Output = LineString; fn try_map_coords( @@ -252,7 +252,7 @@ impl TryMapCoords for LineString MapCoordsInplace for LineString { +impl MapCoordsInplace for LineString { fn map_coords_inplace(&mut self, func: impl Fn(&(T, T)) -> (T, T)) { for p in &mut self.0 { let new_coords = func(&(p.x, p.y)); @@ -262,7 +262,7 @@ impl MapCoordsInplace for LineString { } } -impl MapCoords for Polygon { +impl MapCoords for Polygon { type Output = Polygon; fn map_coords(&self, func: impl Fn(&(T, T)) -> (NT, NT) + Copy) -> Self::Output { @@ -276,7 +276,7 @@ impl MapCoords for Polygon { } } -impl TryMapCoords for Polygon { +impl TryMapCoords for Polygon { type Output = Polygon; fn try_map_coords( @@ -293,7 +293,7 @@ impl TryMapCoords for Polygon { } } -impl MapCoordsInplace for Polygon { +impl MapCoordsInplace for Polygon { fn map_coords_inplace(&mut self, func: impl Fn(&(T, T)) -> (T, T) + Copy) { self.exterior_mut(|line_string| { line_string.map_coords_inplace(func); @@ -307,7 +307,7 @@ impl MapCoordsInplace for Polygon { } } -impl MapCoords for MultiPoint { +impl MapCoords for MultiPoint { type Output = MultiPoint; fn map_coords(&self, func: impl Fn(&(T, T)) -> (NT, NT) + Copy) -> Self::Output { @@ -315,7 +315,7 @@ impl MapCoords for MultiPoint { } } -impl TryMapCoords for MultiPoint { +impl TryMapCoords for MultiPoint { type Output = MultiPoint; fn try_map_coords( @@ -331,7 +331,7 @@ impl TryMapCoords for MultiPoint MapCoordsInplace for MultiPoint { +impl MapCoordsInplace for MultiPoint { fn map_coords_inplace(&mut self, func: impl Fn(&(T, T)) -> (T, T) + Copy) { for p in &mut self.0 { p.map_coords_inplace(func); @@ -339,7 +339,7 @@ impl MapCoordsInplace for MultiPoint { } } -impl MapCoords for MultiLineString { +impl MapCoords for MultiLineString { type Output = MultiLineString; fn map_coords(&self, func: impl Fn(&(T, T)) -> (NT, NT) + Copy) -> Self::Output { @@ -347,7 +347,7 @@ impl MapCoords for MultiLineString } } -impl TryMapCoords for MultiLineString { +impl TryMapCoords for MultiLineString { type Output = MultiLineString; fn try_map_coords( @@ -363,7 +363,7 @@ impl TryMapCoords for MultiLineStr } } -impl MapCoordsInplace for MultiLineString { +impl MapCoordsInplace for MultiLineString { fn map_coords_inplace(&mut self, func: impl Fn(&(T, T)) -> (T, T) + Copy) { for p in &mut self.0 { p.map_coords_inplace(func); @@ -371,7 +371,7 @@ impl MapCoordsInplace for MultiLineString { } } -impl MapCoords for MultiPolygon { +impl MapCoords for MultiPolygon { type Output = MultiPolygon; fn map_coords(&self, func: impl Fn(&(T, T)) -> (NT, NT) + Copy) -> Self::Output { @@ -379,7 +379,7 @@ impl MapCoords for MultiPolygon } } -impl TryMapCoords for MultiPolygon { +impl TryMapCoords for MultiPolygon { type Output = MultiPolygon; fn try_map_coords( @@ -395,7 +395,7 @@ impl TryMapCoords for MultiPolygon } } -impl MapCoordsInplace for MultiPolygon { +impl MapCoordsInplace for MultiPolygon { fn map_coords_inplace(&mut self, func: impl Fn(&(T, T)) -> (T, T) + Copy) { for p in &mut self.0 { p.map_coords_inplace(func); @@ -403,7 +403,7 @@ impl MapCoordsInplace for MultiPolygon { } } -impl MapCoords for Geometry { +impl MapCoords for Geometry { type Output = Geometry; fn map_coords(&self, func: impl Fn(&(T, T)) -> (NT, NT) + Copy) -> Self::Output { @@ -422,7 +422,7 @@ impl MapCoords for Geometry { } } -impl TryMapCoords for Geometry { +impl TryMapCoords for Geometry { type Output = Geometry; fn try_map_coords( @@ -448,7 +448,7 @@ impl TryMapCoords for Geometry } } -impl MapCoordsInplace for Geometry { +impl MapCoordsInplace for Geometry { fn map_coords_inplace(&mut self, func: impl Fn(&(T, T)) -> (T, T) + Copy) { match *self { Geometry::Point(ref mut x) => x.map_coords_inplace(func), @@ -465,7 +465,7 @@ impl MapCoordsInplace for Geometry { } } -impl MapCoords for GeometryCollection { +impl MapCoords for GeometryCollection { type Output = GeometryCollection; fn map_coords(&self, func: impl Fn(&(T, T)) -> (NT, NT) + Copy) -> Self::Output { @@ -473,7 +473,7 @@ impl MapCoords for GeometryCollect } } -impl TryMapCoords for GeometryCollection { +impl TryMapCoords for GeometryCollection { type Output = GeometryCollection; fn try_map_coords( @@ -489,7 +489,7 @@ impl TryMapCoords for GeometryColl } } -impl MapCoordsInplace for GeometryCollection { +impl MapCoordsInplace for GeometryCollection { fn map_coords_inplace(&mut self, func: impl Fn(&(T, T)) -> (T, T) + Copy) { for p in &mut self.0 { p.map_coords_inplace(func); @@ -507,7 +507,7 @@ fn normalize_rect_bounds(min: &mut (T, T), max: &mut (T, T)) { } } -impl MapCoords for Rect { +impl MapCoords for Rect { type Output = Rect; fn map_coords(&self, func: impl Fn(&(T, T)) -> (NT, NT) + Copy) -> Self::Output { @@ -528,7 +528,7 @@ impl MapCoords for Rect { } } -impl TryMapCoords for Rect { +impl TryMapCoords for Rect { type Output = Rect; fn try_map_coords( @@ -552,7 +552,7 @@ impl TryMapCoords for Rect { } } -impl MapCoordsInplace for Rect { +impl MapCoordsInplace for Rect { fn map_coords_inplace(&mut self, func: impl Fn(&(T, T)) -> (T, T)) { let mut new_min = func(&self.min().x_y()); let mut new_max = func(&self.max().x_y()); @@ -564,7 +564,7 @@ impl MapCoordsInplace for Rect { } } -impl MapCoords for Triangle { +impl MapCoords for Triangle { type Output = Triangle; fn map_coords(&self, func: impl Fn(&(T, T)) -> (NT, NT) + Copy) -> Self::Output { @@ -580,7 +580,7 @@ impl MapCoords for Triangle { } } -impl TryMapCoords for Triangle { +impl TryMapCoords for Triangle { type Output = Triangle; fn try_map_coords( @@ -599,7 +599,7 @@ impl TryMapCoords for Triangle } } -impl MapCoordsInplace for Triangle { +impl MapCoordsInplace for Triangle { fn map_coords_inplace(&mut self, func: impl Fn(&(T, T)) -> (T, T)) { let p1 = func(&self.0.x_y()); let p2 = func(&self.1.x_y()); diff --git a/geo/src/algorithm/orient.rs b/geo/src/algorithm/orient.rs index 20003b07a..3dd437560 100644 --- a/geo/src/algorithm/orient.rs +++ b/geo/src/algorithm/orient.rs @@ -1,5 +1,4 @@ -use super::kernels::*; -use crate::{MultiPolygon, Polygon}; +use crate::{GeoNum, MultiPolygon, Polygon}; use crate::algorithm::winding_order::{Winding, WindingOrder}; @@ -68,7 +67,7 @@ pub trait Orient { impl Orient for Polygon where - T: HasKernel, + T: GeoNum, { fn orient(&self, direction: Direction) -> Polygon { orient(self, direction) @@ -77,7 +76,7 @@ where impl Orient for MultiPolygon where - T: HasKernel, + T: GeoNum, { fn orient(&self, direction: Direction) -> MultiPolygon { MultiPolygon(self.iter().map(|poly| poly.orient(direction)).collect()) @@ -100,7 +99,7 @@ pub enum Direction { // and the interior ring(s) will be oriented clockwise fn orient(poly: &Polygon, direction: Direction) -> Polygon where - T: HasKernel, + T: GeoNum, { let interiors = poly .interiors() diff --git a/geo/src/algorithm/rotate.rs b/geo/src/algorithm/rotate.rs index 97013234a..33fc1f681 100644 --- a/geo/src/algorithm/rotate.rs +++ b/geo/src/algorithm/rotate.rs @@ -1,13 +1,15 @@ use crate::algorithm::centroid::Centroid; use crate::algorithm::map_coords::MapCoords; -use crate::{Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon}; -use num_traits::{Float, FromPrimitive}; +use crate::{ + CoordFloat, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, +}; +use num_traits::FromPrimitive; use std::iter::Sum; #[inline] fn rotate_inner(x: T, y: T, x0: T, y0: T, sin_theta: T, cos_theta: T) -> Point where - T: Float, + T: CoordFloat, { let x = x - x0; let y = y - y0; @@ -19,7 +21,7 @@ where // Rotate a single point "angle" degrees about an origin. Origin can be an // arbitrary point. Pass Point::new(0., 0.) for the actual origin. -fn rotate_one(angle: T, origin: Point, point: Point) -> Point { +fn rotate_one(angle: T, origin: Point, point: Point) -> Point { let (sin_theta, cos_theta) = angle.to_radians().sin_cos(); rotate_inner( point.x(), @@ -39,7 +41,7 @@ fn rotate_many( points: impl Iterator>, ) -> impl Iterator> where - T: Float, + T: CoordFloat, { let (sin_theta, cos_theta) = angle.to_radians().sin_cos(); let (x0, y0) = origin.x_y(); @@ -79,7 +81,7 @@ pub trait Rotate { /// ``` fn rotate(&self, angle: T) -> Self where - T: Float; + T: CoordFloat; } pub trait RotatePoint { @@ -116,12 +118,12 @@ pub trait RotatePoint { /// ``` fn rotate_around_point(&self, angle: T, point: Point) -> Self where - T: Float; + T: CoordFloat; } impl RotatePoint for G where - T: Float, + T: CoordFloat, G: MapCoords, { fn rotate_around_point(&self, angle: T, point: Point) -> Self { @@ -133,7 +135,7 @@ where impl Rotate for Point where - T: Float, + T: CoordFloat, { /// Rotate the Point about itself by the given number of degrees /// This operation leaves the point coordinates unchanged @@ -144,7 +146,7 @@ where impl Rotate for Line where - T: Float, + T: CoordFloat, { fn rotate(&self, angle: T) -> Self { let centroid = self.centroid(); @@ -157,7 +159,7 @@ where impl Rotate for LineString where - T: Float, + T: CoordFloat, { /// Rotate the LineString about its centroid by the given number of degrees fn rotate(&self, angle: T) -> Self { @@ -167,7 +169,7 @@ where impl Rotate for Polygon where - T: Float + FromPrimitive + Sum, + T: CoordFloat + FromPrimitive + Sum, { /// Rotate the Polygon about its centroid by the given number of degrees fn rotate(&self, angle: T) -> Self { @@ -189,7 +191,7 @@ where impl Rotate for MultiPolygon where - T: Float + FromPrimitive + Sum, + T: CoordFloat + FromPrimitive + Sum, { /// Rotate the contained Polygons about their centroids by the given number of degrees fn rotate(&self, angle: T) -> Self { @@ -199,7 +201,7 @@ where impl Rotate for MultiLineString where - T: Float + FromPrimitive, + T: CoordFloat + FromPrimitive, { /// Rotate the contained LineStrings about their centroids by the given number of degrees fn rotate(&self, angle: T) -> Self { @@ -209,7 +211,7 @@ where impl Rotate for MultiPoint where - T: Float + FromPrimitive, + T: CoordFloat + FromPrimitive, { /// Rotate the contained Points about their centroids by the given number of degrees fn rotate(&self, angle: T) -> Self { diff --git a/geo/src/algorithm/simplifyvw.rs b/geo/src/algorithm/simplifyvw.rs index 7a3d16056..540b16e2a 100644 --- a/geo/src/algorithm/simplifyvw.rs +++ b/geo/src/algorithm/simplifyvw.rs @@ -1,8 +1,8 @@ use crate::prelude::*; use crate::{ - Coordinate, Line, LineString, MultiLineString, MultiPolygon, Point, Polygon, Triangle, + CoordFloat, Coordinate, Line, LineString, MultiLineString, MultiPolygon, Point, Polygon, + Triangle, }; -use num_traits::Float; use std::cmp::Ordering; use std::collections::BinaryHeap; @@ -13,7 +13,7 @@ use rstar::{RTree, RTreeNum}; #[derive(Debug)] struct VScore where - T: Float, + T: CoordFloat, { left: usize, current: usize, @@ -26,7 +26,7 @@ where // These impls give us a min-heap impl Ord for VScore where - T: Float, + T: CoordFloat, { fn cmp(&self, other: &VScore) -> Ordering { other.area.partial_cmp(&self.area).unwrap() @@ -35,22 +35,22 @@ where impl PartialOrd for VScore where - T: Float, + T: CoordFloat, { fn partial_cmp(&self, other: &VScore) -> Option { Some(self.cmp(other)) } } -impl Eq for VScore where T: Float {} +impl Eq for VScore where T: CoordFloat {} impl PartialEq for VScore where - T: Float, + T: CoordFloat, { fn eq(&self, other: &VScore) -> bool where - T: Float, + T: CoordFloat, { self.area == other.area } @@ -93,7 +93,7 @@ struct GeomSettings { // https://github.com/huonw/isrustfastyet/blob/25e7a68ff26673a8556b170d3c9af52e1c818288/mem/line_simplify.rs fn visvalingam_indices(orig: &LineString, epsilon: &T) -> Vec where - T: Float, + T: CoordFloat, { // No need to continue without at least three points if orig.0.len() < 3 { @@ -189,7 +189,7 @@ where // Wrapper for visvalingam_indices, mapping indices back to points fn visvalingam(orig: &LineString, epsilon: &T) -> Vec> where - T: Float, + T: CoordFloat, { // Epsilon must be greater than zero for any meaningful simplification to happen if *epsilon <= T::zero() { @@ -215,7 +215,7 @@ fn vwp_wrapper( epsilon: &T, ) -> Vec>> where - T: Float + RTreeNum, + T: CoordFloat + RTreeNum, { let mut rings = vec![]; // Populate R* tree with exterior and interior samples, if any @@ -253,7 +253,7 @@ fn visvalingam_preserve( tree: &mut RTree>, ) -> Vec> where - T: Float + RTreeNum, + T: CoordFloat + RTreeNum, { if orig.0.len() < 3 || *epsilon <= T::zero() { return orig.0.to_vec(); @@ -380,7 +380,7 @@ where /// is p1 -> p2 -> p3 wound counterclockwise? fn ccw(p1: Point, p2: Point, p3: Point) -> bool where - T: Float, + T: CoordFloat, { (p3.y() - p1.y()) * (p2.x() - p1.x()) > (p2.y() - p1.y()) * (p3.x() - p1.x()) } @@ -388,7 +388,7 @@ where /// checks whether line segments with p1-p4 as their start and endpoints touch or cross fn cartesian_intersect(p1: Point, p2: Point, p3: Point, p4: Point) -> bool where - T: Float, + T: CoordFloat, { (ccw(p1, p3, p4) ^ ccw(p2, p3, p4)) & (ccw(p1, p2, p3) ^ ccw(p1, p2, p4)) } @@ -400,7 +400,7 @@ fn tree_intersect( orig: &[Coordinate], ) -> bool where - T: Float + RTreeNum, + T: CoordFloat + RTreeNum, { let point_a = orig[triangle.left]; let point_c = orig[triangle.right]; @@ -462,7 +462,7 @@ pub trait SimplifyVW { /// ``` fn simplifyvw(&self, epsilon: &T) -> Self where - T: Float; + T: CoordFloat; } /// Simplifies a geometry, returning the retained _indices_ of the output @@ -502,7 +502,7 @@ pub trait SimplifyVwIdx { /// ``` fn simplifyvw_idx(&self, epsilon: &T) -> Vec where - T: Float; + T: CoordFloat; } /// Simplifies a geometry, preserving its topology by removing self-intersections @@ -563,12 +563,12 @@ pub trait SimplifyVWPreserve { /// ``` fn simplifyvw_preserve(&self, epsilon: &T) -> Self where - T: Float + RTreeNum; + T: CoordFloat + RTreeNum; } impl SimplifyVWPreserve for LineString where - T: Float + RTreeNum, + T: CoordFloat + RTreeNum, { fn simplifyvw_preserve(&self, epsilon: &T) -> LineString { let gt = GeomSettings { @@ -583,7 +583,7 @@ where impl SimplifyVWPreserve for MultiLineString where - T: Float + RTreeNum, + T: CoordFloat + RTreeNum, { fn simplifyvw_preserve(&self, epsilon: &T) -> MultiLineString { MultiLineString( @@ -597,7 +597,7 @@ where impl SimplifyVWPreserve for Polygon where - T: Float + RTreeNum, + T: CoordFloat + RTreeNum, { fn simplifyvw_preserve(&self, epsilon: &T) -> Polygon { let gt = GeomSettings { @@ -614,7 +614,7 @@ where impl SimplifyVWPreserve for MultiPolygon where - T: Float + RTreeNum, + T: CoordFloat + RTreeNum, { fn simplifyvw_preserve(&self, epsilon: &T) -> MultiPolygon { MultiPolygon( @@ -628,7 +628,7 @@ where impl SimplifyVW for LineString where - T: Float, + T: CoordFloat, { fn simplifyvw(&self, epsilon: &T) -> LineString { LineString::from(visvalingam(self, epsilon)) @@ -637,7 +637,7 @@ where impl SimplifyVwIdx for LineString where - T: Float, + T: CoordFloat, { fn simplifyvw_idx(&self, epsilon: &T) -> Vec { visvalingam_indices(self, epsilon) @@ -646,7 +646,7 @@ where impl SimplifyVW for MultiLineString where - T: Float, + T: CoordFloat, { fn simplifyvw(&self, epsilon: &T) -> MultiLineString { MultiLineString(self.iter().map(|l| l.simplifyvw(epsilon)).collect()) @@ -655,7 +655,7 @@ where impl SimplifyVW for Polygon where - T: Float, + T: CoordFloat, { fn simplifyvw(&self, epsilon: &T) -> Polygon { Polygon::new( @@ -670,7 +670,7 @@ where impl SimplifyVW for MultiPolygon where - T: Float, + T: CoordFloat, { fn simplifyvw(&self, epsilon: &T) -> MultiPolygon { MultiPolygon(self.iter().map(|p| p.simplifyvw(epsilon)).collect()) diff --git a/geo/src/algorithm/translate.rs b/geo/src/algorithm/translate.rs index 2f2b924a7..e7c933b9d 100644 --- a/geo/src/algorithm/translate.rs +++ b/geo/src/algorithm/translate.rs @@ -1,5 +1,5 @@ use crate::algorithm::map_coords::{MapCoords, MapCoordsInplace}; -use crate::CoordinateType; +use crate::CoordNum; pub trait Translate { /// Translate a Geometry along its axes by the given offsets @@ -26,17 +26,17 @@ pub trait Translate { /// ``` fn translate(&self, xoff: T, yoff: T) -> Self where - T: CoordinateType; + T: CoordNum; /// Translate a Geometry along its axes, but in place. fn translate_inplace(&mut self, xoff: T, yoff: T) where - T: CoordinateType; + T: CoordNum; } impl Translate for G where - T: CoordinateType, + T: CoordNum, G: MapCoords + MapCoordsInplace, { fn translate(&self, xoff: T, yoff: T) -> Self { diff --git a/geo/src/algorithm/vincenty_distance.rs b/geo/src/algorithm/vincenty_distance.rs index d450f2720..0368b55ba 100644 --- a/geo/src/algorithm/vincenty_distance.rs +++ b/geo/src/algorithm/vincenty_distance.rs @@ -4,8 +4,8 @@ // - https://nathanrooy.github.io/posts/2016-12-18/vincenty-formula-with-python/ // - https://github.com/janantala/GPS-distance/blob/master/java/Distance.java -use crate::{Point, EARTH_FLATTENING, EQUATORIAL_EARTH_RADIUS, POLAR_EARTH_RADIUS}; -use num_traits::{Float, FromPrimitive}; +use crate::{CoordFloat, Point, EARTH_FLATTENING, EQUATORIAL_EARTH_RADIUS, POLAR_EARTH_RADIUS}; +use num_traits::FromPrimitive; use std::{error, fmt}; /// Determine the distance between two geometries using [Vincenty’s formulae]. @@ -45,7 +45,7 @@ pub trait VincentyDistance { impl VincentyDistance> for Point where - T: Float + FromPrimitive, + T: CoordFloat + FromPrimitive, { #[allow(non_snake_case)] fn vincenty_distance(&self, rhs: &Point) -> Result { diff --git a/geo/src/algorithm/vincenty_length.rs b/geo/src/algorithm/vincenty_length.rs index 8b8987ca6..8c65ab62c 100644 --- a/geo/src/algorithm/vincenty_length.rs +++ b/geo/src/algorithm/vincenty_length.rs @@ -1,7 +1,7 @@ -use num_traits::{Float, FromPrimitive}; +use num_traits::FromPrimitive; use crate::algorithm::vincenty_distance::{FailedToConvergeError, VincentyDistance}; -use crate::{Line, LineString, MultiLineString}; +use crate::{CoordFloat, Line, LineString, MultiLineString}; /// Determine the length of a geometry using [Vincenty’s formulae]. /// @@ -42,7 +42,7 @@ pub trait VincentyLength { impl VincentyLength for Line where - T: Float + FromPrimitive, + T: CoordFloat + FromPrimitive, { /// The units of the returned value is meters. fn vincenty_length(&self) -> Result { @@ -53,7 +53,7 @@ where impl VincentyLength for LineString where - T: Float + FromPrimitive, + T: CoordFloat + FromPrimitive, { fn vincenty_length(&self) -> Result { let mut length = T::zero(); @@ -66,7 +66,7 @@ where impl VincentyLength for MultiLineString where - T: Float + FromPrimitive, + T: CoordFloat + FromPrimitive, { fn vincenty_length(&self) -> Result { let mut length = T::zero(); diff --git a/geo/src/algorithm/winding_order.rs b/geo/src/algorithm/winding_order.rs index fd74759a8..8c1f0e137 100644 --- a/geo/src/algorithm/winding_order.rs +++ b/geo/src/algorithm/winding_order.rs @@ -1,7 +1,7 @@ use super::kernels::*; use crate::coords_iter::CoordsIter; use crate::utils::EitherIter; -use crate::{CoordinateType, LineString, Point}; +use crate::{CoordNum, LineString, Point}; use geo_types::PointsIter; use std::iter::Rev; @@ -11,11 +11,11 @@ pub struct Points<'a, T>( pub(crate) EitherIter, PointsIter<'a, T>, Rev>>, ) where - T: CoordinateType + 'a; + T: CoordNum + 'a; impl<'a, T> Iterator for Points<'a, T> where - T: CoordinateType, + T: CoordNum, { type Item = Point; @@ -37,7 +37,7 @@ pub enum WindingOrder { /// /// [CGAL's Polygon_2::orientation]: //doc.cgal.org/latest/Polygon/classCGAL_1_1Polygon__2.html#a4ce8b4b8395406243ac16c2a120ffc15 pub trait Winding { - type Scalar: CoordinateType; + type Scalar: CoordNum; /// Return the winding order of this object if it /// contains at least three distinct coordinates, and diff --git a/geo/src/lib.rs b/geo/src/lib.rs index c84f1e570..69c198c37 100644 --- a/geo/src/lib.rs +++ b/geo/src/lib.rs @@ -54,8 +54,8 @@ pub use crate::traits::ToGeo; pub use crate::types::*; pub use geo_types::{ - line_string, point, polygon, Coordinate, CoordinateType, Geometry, GeometryCollection, Line, - LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, Rect, Triangle, + line_string, point, polygon, CoordFloat, CoordNum, Coordinate, Geometry, GeometryCollection, + Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, Rect, Triangle, }; /// This module includes all the functions of geometric calculations @@ -123,12 +123,13 @@ pub mod prelude { pub use crate::algorithm::vincenty_length::VincentyLength; } -/// A common floating point trait used for geo algorithms. +/// A common numeric trait used for geo algorithms. /// /// Different numeric types have different tradeoffs. `geo` strives to utilize generics to allow /// users to choose their numeric types. If you are writing a function which you'd like to be -/// generic over the floating point types supported by geo, you probably want to constrain -/// your function input to GeoFloat. +/// generic over all the numeric types supported by geo, you probably want to constraint +/// your function input to `GeoFloat`. For methods which work for integers, and not just floating +/// point, see [`GeoNum`]. /// /// # Examples /// @@ -152,11 +153,8 @@ pub mod prelude { /// }) /// } /// ``` -pub trait GeoFloat: - num_traits::Float + CoordinateType + algorithm::kernels::HasKernel + std::fmt::Debug -{ -} -impl GeoFloat for T where - T: num_traits::Float + CoordinateType + algorithm::kernels::HasKernel + std::fmt::Debug -{ -} +pub trait GeoFloat: num_traits::Float + GeoNum {} +impl GeoFloat for T where T: num_traits::Float + GeoNum {} + +pub trait GeoNum: CoordNum + algorithm::kernels::HasKernel {} +impl GeoNum for T where T: CoordNum + algorithm::kernels::HasKernel {} diff --git a/geo/src/traits.rs b/geo/src/traits.rs index 05f1f5b3a..77f8f27ca 100644 --- a/geo/src/traits.rs +++ b/geo/src/traits.rs @@ -1,10 +1,10 @@ pub use crate::Geometry; -use crate::CoordinateType; +use crate::CoordNum; #[deprecated( note = "Will be removed in an upcoming version. Switch to std::convert::Into or std::convert::TryInto." )] -pub trait ToGeo { +pub trait ToGeo { fn to_geo(&self) -> Geometry; } diff --git a/geo/src/utils.rs b/geo/src/utils.rs index 9ae734fb2..c9f4d9bd8 100644 --- a/geo/src/utils.rs +++ b/geo/src/utils.rs @@ -1,6 +1,6 @@ //! Internal utility functions, types, and data structures. -use geo_types::{Coordinate, CoordinateType}; +use geo_types::{CoordNum, Coordinate}; /// Partition a mutable slice in-place so that it contains all elements for /// which `predicate(e)` is `true`, followed by all elements for which @@ -83,7 +83,7 @@ use std::cmp::Ordering; /// x coordinate, and break ties with the y coordinate. /// Expects none of coordinates to be uncomparable (eg. nan) #[inline] -pub fn lex_cmp(p: &Coordinate, q: &Coordinate) -> Ordering { +pub fn lex_cmp(p: &Coordinate, q: &Coordinate) -> Ordering { p.x.partial_cmp(&q.x) .unwrap() .then(p.y.partial_cmp(&q.y).unwrap()) @@ -94,7 +94,7 @@ pub fn lex_cmp(p: &Coordinate, q: &Coordinate) -> Order /// /// Should only be called on a non-empty slice with no `nan` /// coordinates. -pub fn least_index(pts: &[Coordinate]) -> usize { +pub fn least_index(pts: &[Coordinate]) -> usize { pts.iter() .enumerate() .min_by(|(_, p), (_, q)| lex_cmp(p, q)) @@ -107,7 +107,7 @@ pub fn least_index(pts: &[Coordinate]) -> usize { /// /// Should only be called on a non-empty slice with no `nan` /// coordinates. -pub fn least_and_greatest_index(pts: &[Coordinate]) -> (usize, usize) { +pub fn least_and_greatest_index(pts: &[Coordinate]) -> (usize, usize) { assert_ne!(pts.len(), 0); let (min, max) = pts .iter()