From 91e159b1a62087b659a190032c72a3d7809cc9a9 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Wed, 8 Feb 2023 23:07:02 -0500 Subject: [PATCH 01/11] Base traits implementation --- geo-types/src/lib.rs | 3 + geo-types/src/traits/coord.rs | 78 ++++++++++++++++++++ geo-types/src/traits/geometry.rs | 82 +++++++++++++++++++++ geo-types/src/traits/geometry_collection.rs | 53 +++++++++++++ geo-types/src/traits/line_string.rs | 58 +++++++++++++++ geo-types/src/traits/mod.rs | 18 +++++ geo-types/src/traits/multi_line_string.rs | 53 +++++++++++++ geo-types/src/traits/multi_point.rs | 53 +++++++++++++ geo-types/src/traits/multi_polygon.rs | 53 +++++++++++++ geo-types/src/traits/point.rs | 78 ++++++++++++++++++++ geo-types/src/traits/polygon.rs | 64 ++++++++++++++++ 11 files changed, 593 insertions(+) create mode 100644 geo-types/src/traits/coord.rs create mode 100644 geo-types/src/traits/geometry.rs create mode 100644 geo-types/src/traits/geometry_collection.rs create mode 100644 geo-types/src/traits/line_string.rs create mode 100644 geo-types/src/traits/mod.rs create mode 100644 geo-types/src/traits/multi_line_string.rs create mode 100644 geo-types/src/traits/multi_point.rs create mode 100644 geo-types/src/traits/multi_polygon.rs create mode 100644 geo-types/src/traits/point.rs create mode 100644 geo-types/src/traits/polygon.rs diff --git a/geo-types/src/lib.rs b/geo-types/src/lib.rs index 84bb21026..2a7a1a38c 100644 --- a/geo-types/src/lib.rs +++ b/geo-types/src/lib.rs @@ -126,6 +126,9 @@ pub use geometry::line_string::PointsIter; #[allow(deprecated)] pub use geometry::rect::InvalidRectCoordinatesError; +pub mod traits; +// pub use traits::*; + mod error; pub use error::Error; diff --git a/geo-types/src/traits/coord.rs b/geo-types/src/traits/coord.rs new file mode 100644 index 000000000..331c06ddf --- /dev/null +++ b/geo-types/src/traits/coord.rs @@ -0,0 +1,78 @@ +use crate::{Coord, CoordNum, Point}; + +pub trait CoordTrait: Send + Sync { + type T: CoordNum + Send + Sync; + + /// x component of this coord + fn x(&self) -> Self::T; + + /// y component of this coord + fn y(&self) -> Self::T; + + /// Returns a tuple that contains the x/horizontal & y/vertical component of the coord. + fn x_y(&self) -> (Self::T, Self::T); +} + +impl CoordTrait for Point { + type T = T; + + fn x(&self) -> T { + self.0.x + } + + fn y(&self) -> T { + self.0.y + } + + fn x_y(&self) -> (T, T) { + (self.0.x, self.0.y) + } +} + +impl CoordTrait for &Point { + type T = T; + + fn x(&self) -> T { + self.0.x + } + + fn y(&self) -> T { + self.0.y + } + + fn x_y(&self) -> (T, T) { + (self.0.x, self.0.y) + } +} + +impl CoordTrait for Coord { + type T = T; + + fn x(&self) -> T { + self.x + } + + fn y(&self) -> T { + self.y + } + + fn x_y(&self) -> (T, T) { + (self.x, self.y) + } +} + +impl CoordTrait for &Coord { + type T = T; + + fn x(&self) -> T { + self.x + } + + fn y(&self) -> T { + self.y + } + + fn x_y(&self) -> (T, T) { + (self.x, self.y) + } +} diff --git a/geo-types/src/traits/geometry.rs b/geo-types/src/traits/geometry.rs new file mode 100644 index 000000000..d5e72c078 --- /dev/null +++ b/geo-types/src/traits/geometry.rs @@ -0,0 +1,82 @@ +use crate::{ + CoordNum, Geometry, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, +}; + +use super::{ + LineStringTrait, MultiLineStringTrait, MultiPointTrait, MultiPolygonTrait, PointTrait, + PolygonTrait, +}; + +pub trait GeometryTrait<'a>: Send + Sync { + type Point: 'a + PointTrait; + type LineString: 'a + LineStringTrait<'a>; + type Polygon: 'a + PolygonTrait<'a>; + type MultiPoint: 'a + MultiPointTrait<'a>; + type MultiLineString: 'a + MultiLineStringTrait<'a>; + type MultiPolygon: 'a + MultiPolygonTrait<'a>; + // type GeometryCollection: 'a + GeometryCollection<'a>; + fn as_type( + &'a self, + ) -> GeometryType< + 'a, + Self::Point, + Self::LineString, + Self::Polygon, + Self::MultiPoint, + Self::MultiLineString, + Self::MultiPolygon, + // Self::GeometryCollection, + >; +} + +pub enum GeometryType<'a, P, L, Y, MP, ML, MY> +where + P: 'a + PointTrait, + L: 'a + LineStringTrait<'a>, + Y: 'a + PolygonTrait<'a>, + MP: 'a + MultiPointTrait<'a>, + ML: 'a + MultiLineStringTrait<'a>, + MY: 'a + MultiPolygonTrait<'a>, + // GC: 'a + GeometryCollection<'a>, +{ + Point(&'a P), + LineString(&'a L), + Polygon(&'a Y), + MultiPoint(&'a MP), + MultiLineString(&'a ML), + MultiPolygon(&'a MY), + // GeometryCollection(&'a GC), +} + +impl<'a, T: CoordNum + Send + Sync + 'a> GeometryTrait<'a> for Geometry { + type Point = Point; + type LineString = LineString; + type Polygon = Polygon; + type MultiPoint = MultiPoint; + type MultiLineString = MultiLineString; + type MultiPolygon = MultiPolygon; + + fn as_type( + &'a self, + ) -> GeometryType< + 'a, + // Self::Point, + as GeometryTrait>::Point, + as GeometryTrait>::LineString, + as GeometryTrait>::Polygon, + as GeometryTrait>::MultiPoint, + as GeometryTrait>::MultiLineString, + as GeometryTrait>::MultiPolygon, + // Self::GeometryCollection, + > { + match self { + Geometry::Point(p) => GeometryType::Point(p), + Geometry::LineString(p) => GeometryType::LineString(p), + Geometry::Polygon(p) => GeometryType::Polygon(p), + Geometry::MultiPoint(p) => GeometryType::MultiPoint(p), + Geometry::MultiLineString(p) => GeometryType::MultiLineString(p), + Geometry::MultiPolygon(p) => GeometryType::MultiPolygon(p), + _ => todo!(), + } + } +} diff --git a/geo-types/src/traits/geometry_collection.rs b/geo-types/src/traits/geometry_collection.rs new file mode 100644 index 000000000..f8bad21c2 --- /dev/null +++ b/geo-types/src/traits/geometry_collection.rs @@ -0,0 +1,53 @@ +use super::GeometryTrait; +use crate::{CoordNum, Geometry, GeometryCollection, LineString}; +use std::iter::Cloned; +use std::slice::Iter; + +pub trait GeometryCollectionTrait<'a>: Send + Sync { + type ItemType: 'a + GeometryTrait<'a>; + type Iter: Iterator; + + /// An iterator over the LineStrings in this GeometryCollection + fn geometries(&'a self) -> Self::Iter; + + /// The number of lines in this GeometryCollection + fn num_geometries(&'a self) -> usize; + + /// Access to a specified line in this GeometryCollection + /// Will return None if the provided index is out of bounds + fn geometry(&'a self, i: usize) -> Option; +} + +impl<'a, T: CoordNum + Send + Sync + 'a> GeometryCollectionTrait<'a> for GeometryCollection { + type ItemType = Geometry; + type Iter = Cloned>; + + fn geometries(&'a self) -> Self::Iter { + self.0.iter().cloned() + } + + fn num_geometries(&'a self) -> usize { + self.0.len() + } + + fn geometry(&'a self, i: usize) -> Option { + self.0.get(i).cloned() + } +} + +impl<'a, T: CoordNum + Send + Sync + 'a> GeometryCollectionTrait<'a> for &GeometryCollection { + type ItemType = LineString; + type Iter = Cloned>; + + fn geometries(&'a self) -> Self::Iter { + self.0.iter().cloned() + } + + fn num_geometries(&'a self) -> usize { + self.0.len() + } + + fn geometry(&'a self, i: usize) -> Option { + self.0.get(i).cloned() + } +} diff --git a/geo-types/src/traits/line_string.rs b/geo-types/src/traits/line_string.rs new file mode 100644 index 000000000..06a0a4f4b --- /dev/null +++ b/geo-types/src/traits/line_string.rs @@ -0,0 +1,58 @@ +use crate::CoordNum; +use crate::{Coord, LineString}; + +use super::point::PointTrait; +use std::iter::Cloned; +use std::slice::Iter; + +pub trait LineStringTrait<'a>: Send + Sync { + type T: CoordNum + Send + Sync; + type ItemType: 'a + PointTrait; + type Iter: Iterator; + + /// An iterator over the points in this LineString + fn points(&'a self) -> Self::Iter; + + /// The number of points in this LineString + fn num_points(&'a self) -> usize; + + /// Access to a specified point in this LineString + /// Will return None if the provided index is out of bounds + fn point(&'a self, i: usize) -> Option; +} + +impl<'a, T: CoordNum + Send + Sync + 'a> LineStringTrait<'a> for LineString { + type T = T; + type ItemType = Coord; + type Iter = Cloned>; + + fn points(&'a self) -> Self::Iter { + self.0.iter().cloned() + } + + fn num_points(&self) -> usize { + self.0.len() + } + + fn point(&'a self, i: usize) -> Option { + self.0.get(i).cloned() + } +} + +impl<'a, T: CoordNum + Send + Sync + 'a> LineStringTrait<'a> for &LineString { + type T = T; + type ItemType = Coord; + type Iter = Cloned>; + + fn points(&'a self) -> Self::Iter { + self.0.iter().cloned() + } + + fn num_points(&self) -> usize { + self.0.len() + } + + fn point(&'a self, i: usize) -> Option { + self.0.get(i).cloned() + } +} diff --git a/geo-types/src/traits/mod.rs b/geo-types/src/traits/mod.rs new file mode 100644 index 000000000..3e206abd6 --- /dev/null +++ b/geo-types/src/traits/mod.rs @@ -0,0 +1,18 @@ +pub use coord::CoordTrait; +pub use geometry::GeometryTrait; +pub use line_string::LineStringTrait; +pub use multi_line_string::MultiLineStringTrait; +pub use multi_point::MultiPointTrait; +pub use multi_polygon::MultiPolygonTrait; +pub use point::PointTrait; +pub use polygon::PolygonTrait; + +mod coord; +mod geometry; +// mod geometry_collection; +mod line_string; +mod multi_line_string; +mod multi_point; +mod multi_polygon; +mod point; +mod polygon; diff --git a/geo-types/src/traits/multi_line_string.rs b/geo-types/src/traits/multi_line_string.rs new file mode 100644 index 000000000..f1286d6da --- /dev/null +++ b/geo-types/src/traits/multi_line_string.rs @@ -0,0 +1,53 @@ +use super::line_string::LineStringTrait; +use crate::{CoordNum, LineString, MultiLineString}; +use std::iter::Cloned; +use std::slice::Iter; + +pub trait MultiLineStringTrait<'a>: Send + Sync { + type ItemType: 'a + LineStringTrait<'a>; + type Iter: Iterator; + + /// An iterator over the LineStrings in this MultiLineString + fn lines(&'a self) -> Self::Iter; + + /// The number of lines in this MultiLineString + fn num_lines(&'a self) -> usize; + + /// Access to a specified line in this MultiLineString + /// Will return None if the provided index is out of bounds + fn line(&'a self, i: usize) -> Option; +} + +impl<'a, T: CoordNum + Send + Sync + 'a> MultiLineStringTrait<'a> for MultiLineString { + type ItemType = LineString; + type Iter = Cloned>; + + fn lines(&'a self) -> Self::Iter { + self.0.iter().cloned() + } + + fn num_lines(&'a self) -> usize { + self.0.len() + } + + fn line(&'a self, i: usize) -> Option { + self.0.get(i).cloned() + } +} + +impl<'a, T: CoordNum + Send + Sync + 'a> MultiLineStringTrait<'a> for &MultiLineString { + type ItemType = LineString; + type Iter = Cloned>; + + fn lines(&'a self) -> Self::Iter { + self.0.iter().cloned() + } + + fn num_lines(&'a self) -> usize { + self.0.len() + } + + fn line(&'a self, i: usize) -> Option { + self.0.get(i).cloned() + } +} diff --git a/geo-types/src/traits/multi_point.rs b/geo-types/src/traits/multi_point.rs new file mode 100644 index 000000000..b0a9b5a46 --- /dev/null +++ b/geo-types/src/traits/multi_point.rs @@ -0,0 +1,53 @@ +use super::point::PointTrait; +use crate::{CoordNum, MultiPoint, Point}; +use std::iter::Cloned; +use std::slice::Iter; + +pub trait MultiPointTrait<'a>: Send + Sync { + type ItemType: 'a + PointTrait; + type Iter: Iterator; + + /// An iterator over the points in this MultiPoint + fn points(&'a self) -> Self::Iter; + + /// The number of points in this MultiPoint + fn num_points(&'a self) -> usize; + + /// Access to a specified point in this MultiPoint + /// Will return None if the provided index is out of bounds + fn point(&'a self, i: usize) -> Option; +} + +impl<'a, T: CoordNum + Send + Sync + 'a> MultiPointTrait<'a> for MultiPoint { + type ItemType = Point; + type Iter = Cloned>; + + fn points(&'a self) -> Self::Iter { + self.0.iter().cloned() + } + + fn num_points(&self) -> usize { + self.0.len() + } + + fn point(&'a self, i: usize) -> Option { + self.0.get(i).cloned() + } +} + +impl<'a, T: CoordNum + Send + Sync + 'a> MultiPointTrait<'a> for &MultiPoint { + type ItemType = Point; + type Iter = Cloned>; + + fn points(&'a self) -> Self::Iter { + self.0.iter().cloned() + } + + fn num_points(&self) -> usize { + self.0.len() + } + + fn point(&'a self, i: usize) -> Option { + self.0.get(i).cloned() + } +} diff --git a/geo-types/src/traits/multi_polygon.rs b/geo-types/src/traits/multi_polygon.rs new file mode 100644 index 000000000..e5aed09c5 --- /dev/null +++ b/geo-types/src/traits/multi_polygon.rs @@ -0,0 +1,53 @@ +use super::polygon::PolygonTrait; +use crate::{CoordNum, MultiPolygon, Polygon}; +use std::iter::Cloned; +use std::slice::Iter; + +pub trait MultiPolygonTrait<'a>: Send + Sync { + type ItemType: 'a + PolygonTrait<'a>; + type Iter: Iterator; + + /// An iterator over the Polygons in this MultiPolygon + fn polygons(&'a self) -> Self::Iter; + + /// The number of polygons in this MultiPolygon + fn num_polygons(&'a self) -> usize; + + /// Access to a specified polygon in this MultiPolygon + /// Will return None if the provided index is out of bounds + fn polygon(&'a self, i: usize) -> Option; +} + +impl<'a, T: CoordNum + Send + Sync + 'a> MultiPolygonTrait<'a> for MultiPolygon { + type ItemType = Polygon; + type Iter = Cloned>; + + fn polygons(&'a self) -> Self::Iter { + self.0.iter().cloned() + } + + fn num_polygons(&'a self) -> usize { + self.0.len() + } + + fn polygon(&'a self, i: usize) -> Option { + self.0.get(i).cloned() + } +} + +impl<'a, T: CoordNum + Send + Sync + 'a> MultiPolygonTrait<'a> for &MultiPolygon { + type ItemType = Polygon; + type Iter = Cloned>; + + fn polygons(&'a self) -> Self::Iter { + self.0.iter().cloned() + } + + fn num_polygons(&'a self) -> usize { + self.0.len() + } + + fn polygon(&'a self, i: usize) -> Option { + self.0.get(i).cloned() + } +} diff --git a/geo-types/src/traits/point.rs b/geo-types/src/traits/point.rs new file mode 100644 index 000000000..93b4d4d35 --- /dev/null +++ b/geo-types/src/traits/point.rs @@ -0,0 +1,78 @@ +use crate::{Coord, CoordNum, Point}; + +pub trait PointTrait: Send + Sync { + type T: CoordNum + Send + Sync; + + /// x component of this coord + fn x(&self) -> Self::T; + + /// y component of this coord + fn y(&self) -> Self::T; + + /// Returns a tuple that contains the x/horizontal & y/vertical component of the coord. + fn x_y(&self) -> (Self::T, Self::T); +} + +impl PointTrait for Point { + type T = T; + + fn x(&self) -> T { + self.0.x + } + + fn y(&self) -> T { + self.0.y + } + + fn x_y(&self) -> (T, T) { + (self.0.x, self.0.y) + } +} + +impl PointTrait for &Point { + type T = T; + + fn x(&self) -> T { + self.0.x + } + + fn y(&self) -> T { + self.0.y + } + + fn x_y(&self) -> (T, T) { + (self.0.x, self.0.y) + } +} + +impl PointTrait for Coord { + type T = T; + + fn x(&self) -> T { + self.x + } + + fn y(&self) -> T { + self.y + } + + fn x_y(&self) -> (T, T) { + (self.x, self.y) + } +} + +impl PointTrait for &Coord { + type T = T; + + fn x(&self) -> T { + self.x + } + + fn y(&self) -> T { + self.y + } + + fn x_y(&self) -> (T, T) { + (self.x, self.y) + } +} diff --git a/geo-types/src/traits/polygon.rs b/geo-types/src/traits/polygon.rs new file mode 100644 index 000000000..38918ff45 --- /dev/null +++ b/geo-types/src/traits/polygon.rs @@ -0,0 +1,64 @@ +use super::line_string::LineStringTrait; +use crate::{CoordNum, LineString, Polygon}; +use std::iter::Cloned; +use std::slice::Iter; + +pub trait PolygonTrait<'a>: Send + Sync { + type ItemType: 'a + LineStringTrait<'a>; + type Iter: Iterator; + + /// The exterior ring of the polygon + fn exterior(&'a self) -> Self::ItemType; + + /// An iterator of the interior rings of this Polygon + fn interiors(&'a self) -> Self::Iter; + + /// The number of interior rings in this Polygon + fn num_interiors(&'a self) -> usize; + + /// Access to a specified interior ring in this Polygon + /// Will return None if the provided index is out of bounds + fn interior(&'a self, i: usize) -> Option; +} + +impl<'a, T: CoordNum + Send + Sync + 'a> PolygonTrait<'a> for Polygon { + type ItemType = LineString; + type Iter = Cloned>; + + fn exterior(&'a self) -> Self::ItemType { + Polygon::exterior(self).clone() + } + + fn interiors(&'a self) -> Self::Iter { + Polygon::interiors(self).iter().cloned() + } + + fn num_interiors(&'a self) -> usize { + Polygon::interiors(self).len() + } + + fn interior(&'a self, i: usize) -> Option { + Polygon::interiors(self).get(i).cloned() + } +} + +impl<'a, T: CoordNum + Send + Sync + 'a> PolygonTrait<'a> for &Polygon { + type ItemType = LineString; + type Iter = Cloned>; + + fn exterior(&'a self) -> Self::ItemType { + Polygon::exterior(self).clone() + } + + fn interiors(&'a self) -> Self::Iter { + Polygon::interiors(self).iter().cloned() + } + + fn num_interiors(&'a self) -> usize { + Polygon::interiors(self).len() + } + + fn interior(&'a self, i: usize) -> Option { + Polygon::interiors(self).get(i).cloned() + } +} From edb6c6c067b3a2874d3c24b92bb974353e2e9daa Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Wed, 8 Feb 2023 23:10:55 -0500 Subject: [PATCH 02/11] Implement geometry collection trait --- geo-types/src/traits/geometry.rs | 22 +++++++++++++-------- geo-types/src/traits/geometry_collection.rs | 12 +++++------ geo-types/src/traits/mod.rs | 3 ++- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/geo-types/src/traits/geometry.rs b/geo-types/src/traits/geometry.rs index d5e72c078..c3cb6484e 100644 --- a/geo-types/src/traits/geometry.rs +++ b/geo-types/src/traits/geometry.rs @@ -1,12 +1,14 @@ use crate::{ - CoordNum, Geometry, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, + CoordNum, Geometry, GeometryCollection, LineString, MultiLineString, MultiPoint, MultiPolygon, + Point, Polygon, }; use super::{ - LineStringTrait, MultiLineStringTrait, MultiPointTrait, MultiPolygonTrait, PointTrait, - PolygonTrait, + GeometryCollectionTrait, LineStringTrait, MultiLineStringTrait, MultiPointTrait, + MultiPolygonTrait, PointTrait, PolygonTrait, }; +#[allow(clippy::type_complexity)] pub trait GeometryTrait<'a>: Send + Sync { type Point: 'a + PointTrait; type LineString: 'a + LineStringTrait<'a>; @@ -14,7 +16,7 @@ pub trait GeometryTrait<'a>: Send + Sync { type MultiPoint: 'a + MultiPointTrait<'a>; type MultiLineString: 'a + MultiLineStringTrait<'a>; type MultiPolygon: 'a + MultiPolygonTrait<'a>; - // type GeometryCollection: 'a + GeometryCollection<'a>; + type GeometryCollection: 'a + GeometryCollectionTrait<'a>; fn as_type( &'a self, ) -> GeometryType< @@ -25,11 +27,12 @@ pub trait GeometryTrait<'a>: Send + Sync { Self::MultiPoint, Self::MultiLineString, Self::MultiPolygon, - // Self::GeometryCollection, + Self::GeometryCollection, >; } -pub enum GeometryType<'a, P, L, Y, MP, ML, MY> +#[derive(Debug)] +pub enum GeometryType<'a, P, L, Y, MP, ML, MY, GC> where P: 'a + PointTrait, L: 'a + LineStringTrait<'a>, @@ -37,7 +40,7 @@ where MP: 'a + MultiPointTrait<'a>, ML: 'a + MultiLineStringTrait<'a>, MY: 'a + MultiPolygonTrait<'a>, - // GC: 'a + GeometryCollection<'a>, + GC: 'a + GeometryCollectionTrait<'a>, { Point(&'a P), LineString(&'a L), @@ -45,7 +48,7 @@ where MultiPoint(&'a MP), MultiLineString(&'a ML), MultiPolygon(&'a MY), - // GeometryCollection(&'a GC), + GeometryCollection(&'a GC), } impl<'a, T: CoordNum + Send + Sync + 'a> GeometryTrait<'a> for Geometry { @@ -55,6 +58,7 @@ impl<'a, T: CoordNum + Send + Sync + 'a> GeometryTrait<'a> for Geometry { type MultiPoint = MultiPoint; type MultiLineString = MultiLineString; type MultiPolygon = MultiPolygon; + type GeometryCollection = GeometryCollection; fn as_type( &'a self, @@ -67,6 +71,7 @@ impl<'a, T: CoordNum + Send + Sync + 'a> GeometryTrait<'a> for Geometry { as GeometryTrait>::MultiPoint, as GeometryTrait>::MultiLineString, as GeometryTrait>::MultiPolygon, + as GeometryTrait>::GeometryCollection, // Self::GeometryCollection, > { match self { @@ -76,6 +81,7 @@ impl<'a, T: CoordNum + Send + Sync + 'a> GeometryTrait<'a> for Geometry { Geometry::MultiPoint(p) => GeometryType::MultiPoint(p), Geometry::MultiLineString(p) => GeometryType::MultiLineString(p), Geometry::MultiPolygon(p) => GeometryType::MultiPolygon(p), + Geometry::GeometryCollection(p) => GeometryType::GeometryCollection(p), _ => todo!(), } } diff --git a/geo-types/src/traits/geometry_collection.rs b/geo-types/src/traits/geometry_collection.rs index f8bad21c2..f00456d2d 100644 --- a/geo-types/src/traits/geometry_collection.rs +++ b/geo-types/src/traits/geometry_collection.rs @@ -1,5 +1,5 @@ use super::GeometryTrait; -use crate::{CoordNum, Geometry, GeometryCollection, LineString}; +use crate::{CoordNum, Geometry, GeometryCollection}; use std::iter::Cloned; use std::slice::Iter; @@ -7,19 +7,19 @@ pub trait GeometryCollectionTrait<'a>: Send + Sync { type ItemType: 'a + GeometryTrait<'a>; type Iter: Iterator; - /// An iterator over the LineStrings in this GeometryCollection + /// An iterator over the geometries in this GeometryCollection fn geometries(&'a self) -> Self::Iter; - /// The number of lines in this GeometryCollection + /// The number of geometries in this GeometryCollection fn num_geometries(&'a self) -> usize; - /// Access to a specified line in this GeometryCollection + /// Access to a specified geometry in this GeometryCollection /// Will return None if the provided index is out of bounds fn geometry(&'a self, i: usize) -> Option; } impl<'a, T: CoordNum + Send + Sync + 'a> GeometryCollectionTrait<'a> for GeometryCollection { - type ItemType = Geometry; + type ItemType = Geometry; type Iter = Cloned>; fn geometries(&'a self) -> Self::Iter { @@ -36,7 +36,7 @@ impl<'a, T: CoordNum + Send + Sync + 'a> GeometryCollectionTrait<'a> for Geometr } impl<'a, T: CoordNum + Send + Sync + 'a> GeometryCollectionTrait<'a> for &GeometryCollection { - type ItemType = LineString; + type ItemType = Geometry; type Iter = Cloned>; fn geometries(&'a self) -> Self::Iter { diff --git a/geo-types/src/traits/mod.rs b/geo-types/src/traits/mod.rs index 3e206abd6..00b5d76f7 100644 --- a/geo-types/src/traits/mod.rs +++ b/geo-types/src/traits/mod.rs @@ -1,5 +1,6 @@ pub use coord::CoordTrait; pub use geometry::GeometryTrait; +pub use geometry_collection::GeometryCollectionTrait; pub use line_string::LineStringTrait; pub use multi_line_string::MultiLineStringTrait; pub use multi_point::MultiPointTrait; @@ -9,7 +10,7 @@ pub use polygon::PolygonTrait; mod coord; mod geometry; -// mod geometry_collection; +mod geometry_collection; mod line_string; mod multi_line_string; mod multi_point; From 9cdca40fdb7389bd9cb3e19bde6007f6ef9b0422 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Wed, 8 Feb 2023 23:47:16 -0500 Subject: [PATCH 03/11] remove comments --- geo-types/src/traits/geometry.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/geo-types/src/traits/geometry.rs b/geo-types/src/traits/geometry.rs index c3cb6484e..633b419ab 100644 --- a/geo-types/src/traits/geometry.rs +++ b/geo-types/src/traits/geometry.rs @@ -64,7 +64,6 @@ impl<'a, T: CoordNum + Send + Sync + 'a> GeometryTrait<'a> for Geometry { &'a self, ) -> GeometryType< 'a, - // Self::Point, as GeometryTrait>::Point, as GeometryTrait>::LineString, as GeometryTrait>::Polygon, @@ -72,7 +71,6 @@ impl<'a, T: CoordNum + Send + Sync + 'a> GeometryTrait<'a> for Geometry { as GeometryTrait>::MultiLineString, as GeometryTrait>::MultiPolygon, as GeometryTrait>::GeometryCollection, - // Self::GeometryCollection, > { match self { Geometry::Point(p) => GeometryType::Point(p), From bec4fdc2ef3d27f5e5d7302fd997d73bd5f4cbda Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Wed, 8 Feb 2023 23:55:34 -0500 Subject: [PATCH 04/11] simpler type --- geo-types/src/traits/geometry.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/geo-types/src/traits/geometry.rs b/geo-types/src/traits/geometry.rs index 633b419ab..96b2e133c 100644 --- a/geo-types/src/traits/geometry.rs +++ b/geo-types/src/traits/geometry.rs @@ -17,6 +17,7 @@ pub trait GeometryTrait<'a>: Send + Sync { type MultiLineString: 'a + MultiLineStringTrait<'a>; type MultiPolygon: 'a + MultiPolygonTrait<'a>; type GeometryCollection: 'a + GeometryCollectionTrait<'a>; + fn as_type( &'a self, ) -> GeometryType< @@ -64,13 +65,13 @@ impl<'a, T: CoordNum + Send + Sync + 'a> GeometryTrait<'a> for Geometry { &'a self, ) -> GeometryType< 'a, - as GeometryTrait>::Point, - as GeometryTrait>::LineString, - as GeometryTrait>::Polygon, - as GeometryTrait>::MultiPoint, - as GeometryTrait>::MultiLineString, - as GeometryTrait>::MultiPolygon, - as GeometryTrait>::GeometryCollection, + Point, + LineString, + Polygon, + MultiPoint, + MultiLineString, + MultiPolygon, + GeometryCollection, > { match self { Geometry::Point(p) => GeometryType::Point(p), From f63803e0460b64d6d82630fcf160bef1a4ec91f4 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Thu, 9 Feb 2023 00:12:59 -0500 Subject: [PATCH 05/11] small fixes --- geo-types/src/traits/line_string.rs | 3 --- geo-types/src/traits/mod.rs | 2 +- geo/src/traits.rs | 2 ++ 3 files changed, 3 insertions(+), 4 deletions(-) create mode 100644 geo/src/traits.rs diff --git a/geo-types/src/traits/line_string.rs b/geo-types/src/traits/line_string.rs index 06a0a4f4b..5d2292fae 100644 --- a/geo-types/src/traits/line_string.rs +++ b/geo-types/src/traits/line_string.rs @@ -6,7 +6,6 @@ use std::iter::Cloned; use std::slice::Iter; pub trait LineStringTrait<'a>: Send + Sync { - type T: CoordNum + Send + Sync; type ItemType: 'a + PointTrait; type Iter: Iterator; @@ -22,7 +21,6 @@ pub trait LineStringTrait<'a>: Send + Sync { } impl<'a, T: CoordNum + Send + Sync + 'a> LineStringTrait<'a> for LineString { - type T = T; type ItemType = Coord; type Iter = Cloned>; @@ -40,7 +38,6 @@ impl<'a, T: CoordNum + Send + Sync + 'a> LineStringTrait<'a> for LineString { } impl<'a, T: CoordNum + Send + Sync + 'a> LineStringTrait<'a> for &LineString { - type T = T; type ItemType = Coord; type Iter = Cloned>; diff --git a/geo-types/src/traits/mod.rs b/geo-types/src/traits/mod.rs index 00b5d76f7..ce4bbe22c 100644 --- a/geo-types/src/traits/mod.rs +++ b/geo-types/src/traits/mod.rs @@ -1,5 +1,5 @@ pub use coord::CoordTrait; -pub use geometry::GeometryTrait; +pub use geometry::{GeometryTrait, GeometryType}; pub use geometry_collection::GeometryCollectionTrait; pub use line_string::LineStringTrait; pub use multi_line_string::MultiLineStringTrait; diff --git a/geo/src/traits.rs b/geo/src/traits.rs new file mode 100644 index 000000000..2e474b646 --- /dev/null +++ b/geo/src/traits.rs @@ -0,0 +1,2 @@ +//! This module makes all trait types available +pub use geo_types::traits::*; From 2b04f25fc85622e7ae143061ec60a609a6199c14 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Thu, 20 Apr 2023 19:39:01 -0400 Subject: [PATCH 06/11] Initial geo-traits implementation --- Cargo.toml | 2 +- geo-traits/Cargo.toml | 19 +++++++++++++++++++ .../src/traits => geo-traits/src}/coord.rs | 2 +- .../src/traits => geo-traits/src}/geometry.rs | 2 +- .../src}/geometry_collection.rs | 2 +- .../traits/mod.rs => geo-traits/src/lib.rs | 0 .../traits => geo-traits/src}/line_string.rs | 3 +-- .../src}/multi_line_string.rs | 2 +- .../traits => geo-traits/src}/multi_point.rs | 2 +- .../src}/multi_polygon.rs | 2 +- .../src/traits => geo-traits/src}/point.rs | 2 +- .../src/traits => geo-traits/src}/polygon.rs | 2 +- geo-types/src/lib.rs | 3 --- 13 files changed, 29 insertions(+), 14 deletions(-) create mode 100644 geo-traits/Cargo.toml rename {geo-types/src/traits => geo-traits/src}/coord.rs (96%) rename {geo-types/src/traits => geo-traits/src}/geometry.rs (99%) rename {geo-types/src/traits => geo-traits/src}/geometry_collection.rs (96%) rename geo-types/src/traits/mod.rs => geo-traits/src/lib.rs (100%) rename {geo-types/src/traits => geo-traits/src}/line_string.rs (96%) rename {geo-types/src/traits => geo-traits/src}/multi_line_string.rs (96%) rename {geo-types/src/traits => geo-traits/src}/multi_point.rs (96%) rename {geo-types/src/traits => geo-traits/src}/multi_polygon.rs (96%) rename {geo-types/src/traits => geo-traits/src}/point.rs (96%) rename {geo-types/src/traits => geo-traits/src}/polygon.rs (97%) diff --git a/Cargo.toml b/Cargo.toml index 55ddae133..ad2a3e4a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["geo", "geo-types", "geo-postgis", "geo-test-fixtures", "jts-test-runner", "geo-bool-ops-benches"] +members = ["geo", "geo-types", "geo-traits", "geo-postgis", "geo-test-fixtures", "jts-test-runner", "geo-bool-ops-benches"] [patch.crates-io] diff --git a/geo-traits/Cargo.toml b/geo-traits/Cargo.toml new file mode 100644 index 000000000..d437cb1a0 --- /dev/null +++ b/geo-traits/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "geo-traits" +version = "0.1.0" +license = "MIT OR Apache-2.0" +repository = "https://github.com/georust/geo" +documentation = "https://docs.rs/geo-traits/" +readme = "../README.md" +keywords = ["gis", "geo", "geography", "geospatial"] +description = "Geospatial traits" +rust-version = "1.63" +edition = "2021" + +[features] + +[dependencies] +geo-types = "0.7.9" + +[dev-dependencies] +approx = ">= 0.4.0, < 0.6.0" diff --git a/geo-types/src/traits/coord.rs b/geo-traits/src/coord.rs similarity index 96% rename from geo-types/src/traits/coord.rs rename to geo-traits/src/coord.rs index 331c06ddf..4babcfab8 100644 --- a/geo-types/src/traits/coord.rs +++ b/geo-traits/src/coord.rs @@ -1,4 +1,4 @@ -use crate::{Coord, CoordNum, Point}; +use geo_types::{Coord, CoordNum, Point}; pub trait CoordTrait: Send + Sync { type T: CoordNum + Send + Sync; diff --git a/geo-types/src/traits/geometry.rs b/geo-traits/src/geometry.rs similarity index 99% rename from geo-types/src/traits/geometry.rs rename to geo-traits/src/geometry.rs index 96b2e133c..3fede9acb 100644 --- a/geo-types/src/traits/geometry.rs +++ b/geo-traits/src/geometry.rs @@ -1,4 +1,4 @@ -use crate::{ +use geo_types::{ CoordNum, Geometry, GeometryCollection, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, }; diff --git a/geo-types/src/traits/geometry_collection.rs b/geo-traits/src/geometry_collection.rs similarity index 96% rename from geo-types/src/traits/geometry_collection.rs rename to geo-traits/src/geometry_collection.rs index f00456d2d..214635519 100644 --- a/geo-types/src/traits/geometry_collection.rs +++ b/geo-traits/src/geometry_collection.rs @@ -1,5 +1,5 @@ use super::GeometryTrait; -use crate::{CoordNum, Geometry, GeometryCollection}; +use geo_types::{CoordNum, Geometry, GeometryCollection}; use std::iter::Cloned; use std::slice::Iter; diff --git a/geo-types/src/traits/mod.rs b/geo-traits/src/lib.rs similarity index 100% rename from geo-types/src/traits/mod.rs rename to geo-traits/src/lib.rs diff --git a/geo-types/src/traits/line_string.rs b/geo-traits/src/line_string.rs similarity index 96% rename from geo-types/src/traits/line_string.rs rename to geo-traits/src/line_string.rs index 5d2292fae..a6a57ca4e 100644 --- a/geo-types/src/traits/line_string.rs +++ b/geo-traits/src/line_string.rs @@ -1,5 +1,4 @@ -use crate::CoordNum; -use crate::{Coord, LineString}; +use geo_types::{Coord, CoordNum, LineString}; use super::point::PointTrait; use std::iter::Cloned; diff --git a/geo-types/src/traits/multi_line_string.rs b/geo-traits/src/multi_line_string.rs similarity index 96% rename from geo-types/src/traits/multi_line_string.rs rename to geo-traits/src/multi_line_string.rs index f1286d6da..44aa5004b 100644 --- a/geo-types/src/traits/multi_line_string.rs +++ b/geo-traits/src/multi_line_string.rs @@ -1,5 +1,5 @@ use super::line_string::LineStringTrait; -use crate::{CoordNum, LineString, MultiLineString}; +use geo_types::{CoordNum, LineString, MultiLineString}; use std::iter::Cloned; use std::slice::Iter; diff --git a/geo-types/src/traits/multi_point.rs b/geo-traits/src/multi_point.rs similarity index 96% rename from geo-types/src/traits/multi_point.rs rename to geo-traits/src/multi_point.rs index b0a9b5a46..bbc210748 100644 --- a/geo-types/src/traits/multi_point.rs +++ b/geo-traits/src/multi_point.rs @@ -1,5 +1,5 @@ use super::point::PointTrait; -use crate::{CoordNum, MultiPoint, Point}; +use geo_types::{CoordNum, MultiPoint, Point}; use std::iter::Cloned; use std::slice::Iter; diff --git a/geo-types/src/traits/multi_polygon.rs b/geo-traits/src/multi_polygon.rs similarity index 96% rename from geo-types/src/traits/multi_polygon.rs rename to geo-traits/src/multi_polygon.rs index e5aed09c5..043429b1e 100644 --- a/geo-types/src/traits/multi_polygon.rs +++ b/geo-traits/src/multi_polygon.rs @@ -1,5 +1,5 @@ use super::polygon::PolygonTrait; -use crate::{CoordNum, MultiPolygon, Polygon}; +use geo_types::{CoordNum, MultiPolygon, Polygon}; use std::iter::Cloned; use std::slice::Iter; diff --git a/geo-types/src/traits/point.rs b/geo-traits/src/point.rs similarity index 96% rename from geo-types/src/traits/point.rs rename to geo-traits/src/point.rs index 93b4d4d35..1f33ea843 100644 --- a/geo-types/src/traits/point.rs +++ b/geo-traits/src/point.rs @@ -1,4 +1,4 @@ -use crate::{Coord, CoordNum, Point}; +use geo_types::{Coord, CoordNum, Point}; pub trait PointTrait: Send + Sync { type T: CoordNum + Send + Sync; diff --git a/geo-types/src/traits/polygon.rs b/geo-traits/src/polygon.rs similarity index 97% rename from geo-types/src/traits/polygon.rs rename to geo-traits/src/polygon.rs index 38918ff45..0adb90883 100644 --- a/geo-types/src/traits/polygon.rs +++ b/geo-traits/src/polygon.rs @@ -1,5 +1,5 @@ use super::line_string::LineStringTrait; -use crate::{CoordNum, LineString, Polygon}; +use geo_types::{CoordNum, LineString, Polygon}; use std::iter::Cloned; use std::slice::Iter; diff --git a/geo-types/src/lib.rs b/geo-types/src/lib.rs index e0bf4d094..da37dc5fa 100644 --- a/geo-types/src/lib.rs +++ b/geo-types/src/lib.rs @@ -127,9 +127,6 @@ pub use geometry::line_string::PointsIter; #[allow(deprecated)] pub use geometry::rect::InvalidRectCoordinatesError; -pub mod traits; -// pub use traits::*; - mod error; pub use error::Error; From 6dcba5844ae6670a5678e483c4630b65fd156c6a Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Thu, 20 Apr 2023 19:41:04 -0400 Subject: [PATCH 07/11] remove traits import from geo --- geo/src/traits.rs | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 geo/src/traits.rs diff --git a/geo/src/traits.rs b/geo/src/traits.rs deleted file mode 100644 index 2e474b646..000000000 --- a/geo/src/traits.rs +++ /dev/null @@ -1,2 +0,0 @@ -//! This module makes all trait types available -pub use geo_types::traits::*; From 046704bb4b1a953f39fd048f87faecafb0fc79f4 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Fri, 21 Apr 2023 13:56:23 -0400 Subject: [PATCH 08/11] Address comments --- geo-traits/src/coord.rs | 20 +++----------------- geo-traits/src/line_string.rs | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/geo-traits/src/coord.rs b/geo-traits/src/coord.rs index 4babcfab8..2036ef9f9 100644 --- a/geo-traits/src/coord.rs +++ b/geo-traits/src/coord.rs @@ -10,7 +10,9 @@ pub trait CoordTrait: Send + Sync { fn y(&self) -> Self::T; /// Returns a tuple that contains the x/horizontal & y/vertical component of the coord. - fn x_y(&self) -> (Self::T, Self::T); + fn x_y(&self) -> (Self::T, Self::T) { + (self.x(), self.y()) + } } impl CoordTrait for Point { @@ -23,10 +25,6 @@ impl CoordTrait for Point { fn y(&self) -> T { self.0.y } - - fn x_y(&self) -> (T, T) { - (self.0.x, self.0.y) - } } impl CoordTrait for &Point { @@ -39,10 +37,6 @@ impl CoordTrait for &Point { fn y(&self) -> T { self.0.y } - - fn x_y(&self) -> (T, T) { - (self.0.x, self.0.y) - } } impl CoordTrait for Coord { @@ -55,10 +49,6 @@ impl CoordTrait for Coord { fn y(&self) -> T { self.y } - - fn x_y(&self) -> (T, T) { - (self.x, self.y) - } } impl CoordTrait for &Coord { @@ -71,8 +61,4 @@ impl CoordTrait for &Coord { fn y(&self) -> T { self.y } - - fn x_y(&self) -> (T, T) { - (self.x, self.y) - } } diff --git a/geo-traits/src/line_string.rs b/geo-traits/src/line_string.rs index a6a57ca4e..3d0052259 100644 --- a/geo-traits/src/line_string.rs +++ b/geo-traits/src/line_string.rs @@ -8,30 +8,30 @@ pub trait LineStringTrait<'a>: Send + Sync { type ItemType: 'a + PointTrait; type Iter: Iterator; - /// An iterator over the points in this LineString - fn points(&'a self) -> Self::Iter; + /// An iterator over the coords in this LineString + fn coords(&'a self) -> Self::Iter; - /// The number of points in this LineString - fn num_points(&'a self) -> usize; + /// The number of coords in this LineString + fn num_coords(&'a self) -> usize; /// Access to a specified point in this LineString /// Will return None if the provided index is out of bounds - fn point(&'a self, i: usize) -> Option; + fn coord(&'a self, i: usize) -> Option; } impl<'a, T: CoordNum + Send + Sync + 'a> LineStringTrait<'a> for LineString { type ItemType = Coord; type Iter = Cloned>; - fn points(&'a self) -> Self::Iter { + fn coords(&'a self) -> Self::Iter { self.0.iter().cloned() } - fn num_points(&self) -> usize { + fn num_coords(&self) -> usize { self.0.len() } - fn point(&'a self, i: usize) -> Option { + fn coord(&'a self, i: usize) -> Option { self.0.get(i).cloned() } } @@ -40,15 +40,15 @@ impl<'a, T: CoordNum + Send + Sync + 'a> LineStringTrait<'a> for &LineString type ItemType = Coord; type Iter = Cloned>; - fn points(&'a self) -> Self::Iter { + fn coords(&'a self) -> Self::Iter { self.0.iter().cloned() } - fn num_points(&self) -> usize { + fn num_coords(&self) -> usize { self.0.len() } - fn point(&'a self, i: usize) -> Option { + fn coord(&'a self, i: usize) -> Option { self.0.get(i).cloned() } } From cf3a51defc7b936ac10358cf8b07e782055c1c0a Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Fri, 21 Apr 2023 13:57:54 -0400 Subject: [PATCH 09/11] make linestring item a coord trait --- geo-traits/src/line_string.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/geo-traits/src/line_string.rs b/geo-traits/src/line_string.rs index 3d0052259..3f154d737 100644 --- a/geo-traits/src/line_string.rs +++ b/geo-traits/src/line_string.rs @@ -1,11 +1,11 @@ use geo_types::{Coord, CoordNum, LineString}; -use super::point::PointTrait; +use super::CoordTrait; use std::iter::Cloned; use std::slice::Iter; pub trait LineStringTrait<'a>: Send + Sync { - type ItemType: 'a + PointTrait; + type ItemType: 'a + CoordTrait; type Iter: Iterator; /// An iterator over the coords in this LineString From 64134054bb09d84a0567236edefd87b0a5124694 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Sat, 22 Apr 2023 13:29:58 -0400 Subject: [PATCH 10/11] Bump geo-traits msrv --- geo-traits/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geo-traits/Cargo.toml b/geo-traits/Cargo.toml index d437cb1a0..dad7e747b 100644 --- a/geo-traits/Cargo.toml +++ b/geo-traits/Cargo.toml @@ -7,7 +7,7 @@ documentation = "https://docs.rs/geo-traits/" readme = "../README.md" keywords = ["gis", "geo", "geography", "geospatial"] description = "Geospatial traits" -rust-version = "1.63" +rust-version = "1.65" edition = "2021" [features] From 10cdce0e16ea16d4a683d7f457e6b16f53078511 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Thu, 15 Jun 2023 20:57:08 -0400 Subject: [PATCH 11/11] Use `ExactSizeIterator` --- geo-traits/src/geometry_collection.rs | 2 +- geo-traits/src/line_string.rs | 2 +- geo-traits/src/multi_line_string.rs | 2 +- geo-traits/src/multi_point.rs | 2 +- geo-traits/src/multi_polygon.rs | 2 +- geo-traits/src/polygon.rs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/geo-traits/src/geometry_collection.rs b/geo-traits/src/geometry_collection.rs index 214635519..4343ad121 100644 --- a/geo-traits/src/geometry_collection.rs +++ b/geo-traits/src/geometry_collection.rs @@ -5,7 +5,7 @@ use std::slice::Iter; pub trait GeometryCollectionTrait<'a>: Send + Sync { type ItemType: 'a + GeometryTrait<'a>; - type Iter: Iterator; + type Iter: ExactSizeIterator; /// An iterator over the geometries in this GeometryCollection fn geometries(&'a self) -> Self::Iter; diff --git a/geo-traits/src/line_string.rs b/geo-traits/src/line_string.rs index 3f154d737..b4fa30bd3 100644 --- a/geo-traits/src/line_string.rs +++ b/geo-traits/src/line_string.rs @@ -6,7 +6,7 @@ use std::slice::Iter; pub trait LineStringTrait<'a>: Send + Sync { type ItemType: 'a + CoordTrait; - type Iter: Iterator; + type Iter: ExactSizeIterator; /// An iterator over the coords in this LineString fn coords(&'a self) -> Self::Iter; diff --git a/geo-traits/src/multi_line_string.rs b/geo-traits/src/multi_line_string.rs index 44aa5004b..27debbfe5 100644 --- a/geo-traits/src/multi_line_string.rs +++ b/geo-traits/src/multi_line_string.rs @@ -5,7 +5,7 @@ use std::slice::Iter; pub trait MultiLineStringTrait<'a>: Send + Sync { type ItemType: 'a + LineStringTrait<'a>; - type Iter: Iterator; + type Iter: ExactSizeIterator; /// An iterator over the LineStrings in this MultiLineString fn lines(&'a self) -> Self::Iter; diff --git a/geo-traits/src/multi_point.rs b/geo-traits/src/multi_point.rs index bbc210748..01fc858bc 100644 --- a/geo-traits/src/multi_point.rs +++ b/geo-traits/src/multi_point.rs @@ -5,7 +5,7 @@ use std::slice::Iter; pub trait MultiPointTrait<'a>: Send + Sync { type ItemType: 'a + PointTrait; - type Iter: Iterator; + type Iter: ExactSizeIterator; /// An iterator over the points in this MultiPoint fn points(&'a self) -> Self::Iter; diff --git a/geo-traits/src/multi_polygon.rs b/geo-traits/src/multi_polygon.rs index 043429b1e..4b2eeacfa 100644 --- a/geo-traits/src/multi_polygon.rs +++ b/geo-traits/src/multi_polygon.rs @@ -5,7 +5,7 @@ use std::slice::Iter; pub trait MultiPolygonTrait<'a>: Send + Sync { type ItemType: 'a + PolygonTrait<'a>; - type Iter: Iterator; + type Iter: ExactSizeIterator; /// An iterator over the Polygons in this MultiPolygon fn polygons(&'a self) -> Self::Iter; diff --git a/geo-traits/src/polygon.rs b/geo-traits/src/polygon.rs index 0adb90883..be8ad591b 100644 --- a/geo-traits/src/polygon.rs +++ b/geo-traits/src/polygon.rs @@ -5,7 +5,7 @@ use std::slice::Iter; pub trait PolygonTrait<'a>: Send + Sync { type ItemType: 'a + LineStringTrait<'a>; - type Iter: Iterator; + type Iter: ExactSizeIterator; /// The exterior ring of the polygon fn exterior(&'a self) -> Self::ItemType;