diff --git a/geo-types/src/geometry.rs b/geo-types/src/geometry.rs index 85b28bea4..4f4ac4abf 100644 --- a/geo-types/src/geometry.rs +++ b/geo-types/src/geometry.rs @@ -1,6 +1,6 @@ use crate::{ CoordinateType, GeometryCollection, Line, LineString, MultiLineString, MultiPoint, - MultiPolygon, Point, Polygon, + MultiPolygon, Point, Polygon, Rect, Triangle, }; use num_traits::Float; use std::convert::TryFrom; @@ -36,6 +36,8 @@ where MultiLineString(MultiLineString), MultiPolygon(MultiPolygon), GeometryCollection(GeometryCollection), + Rect(Rect), + Triangle(Triangle), } impl From> for Geometry { @@ -74,6 +76,18 @@ impl From> for Geometry { } } +impl From> for Geometry { + fn from(x: Rect) -> Geometry { + Geometry::Rect(x) + } +} + +impl From> for Geometry { + fn from(x: Triangle) -> Geometry { + Geometry::Triangle(x) + } +} + impl Geometry { /// If this Geometry is a Point, then return that, else None. /// diff --git a/geo-types/src/triangle.rs b/geo-types/src/triangle.rs index 3cd4f137f..e2efaa9e5 100644 --- a/geo-types/src/triangle.rs +++ b/geo-types/src/triangle.rs @@ -1,7 +1,7 @@ use crate::{polygon, Coordinate, CoordinateType, Line, Polygon}; /// A bounded 2D area whose three vertices are defined by `Coordinate`s. -#[derive(Copy, Clone, Debug, Hash)] +#[derive(Copy, Clone, Debug, Hash, PartialEq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Triangle(pub Coordinate, pub Coordinate, pub Coordinate); diff --git a/geo/src/algorithm/map_coords.rs b/geo/src/algorithm/map_coords.rs index d05b0c260..87b4e1929 100644 --- a/geo/src/algorithm/map_coords.rs +++ b/geo/src/algorithm/map_coords.rs @@ -36,7 +36,7 @@ use crate::{ Coordinate, CoordinateType, Geometry, GeometryCollection, Line, LineString, MultiLineString, - MultiPoint, MultiPolygon, Point, Polygon, Rect, + MultiPoint, MultiPolygon, Point, Polygon, Rect, Triangle }; use std::error::Error; @@ -416,6 +416,8 @@ impl MapCoords for Geometry { Geometry::MultiLineString(ref x) => Geometry::MultiLineString(x.map_coords(func)), Geometry::MultiPolygon(ref x) => Geometry::MultiPolygon(x.map_coords(func)), Geometry::GeometryCollection(ref x) => Geometry::GeometryCollection(x.map_coords(func)), + Geometry::Rect(ref x) => Geometry::Rect(x.map_coords(func)), + Geometry::Triangle(ref x) => Geometry::Triangle(x.map_coords(func)), } } } @@ -440,6 +442,8 @@ impl TryMapCoords for Geometry Geometry::GeometryCollection(ref x) => { Ok(Geometry::GeometryCollection(x.try_map_coords(func)?)) } + Geometry::Rect(ref x) => Ok(Geometry::Rect(x.try_map_coords(func)?)), + Geometry::Triangle(ref x) => Ok(Geometry::Triangle(x.try_map_coords(func)?)), } } } @@ -455,6 +459,8 @@ impl MapCoordsInplace for Geometry { Geometry::MultiLineString(ref mut x) => x.map_coords_inplace(func), Geometry::MultiPolygon(ref mut x) => x.map_coords_inplace(func), Geometry::GeometryCollection(ref mut x) => x.map_coords_inplace(func), + Geometry::Rect(ref mut x) => x.map_coords_inplace(func), + Geometry::Triangle(ref mut x) => x.map_coords_inplace(func), } } } @@ -545,6 +551,57 @@ impl MapCoordsInplace for Rect { } } +impl MapCoords for Triangle { + type Output = Triangle; + + fn map_coords(&self, func: impl Fn(&(T, T)) -> (NT, NT) + Copy) -> Self::Output { + let p1 = func(&self.0.x_y()); + let p2 = func(&self.1.x_y()); + let p3 = func(&self.2.x_y()); + + Triangle( + Coordinate { x: p1.0, y: p1.1 }, + Coordinate { x: p2.0, y: p2.1 }, + Coordinate { x: p3.0, y: p3.1 }, + ) + } +} + +impl TryMapCoords for Triangle { + type Output = Triangle; + + fn try_map_coords( + &self, + func: impl Fn(&(T, T)) -> Result<(NT, NT), Box>, + ) -> Result> { + let p1 = func(&self.0.x_y())?; + let p2 = func(&self.1.x_y())?; + let p3 = func(&self.2.x_y())?; + + Ok(Triangle( + Coordinate { x: p1.0, y: p1.1 }, + Coordinate { x: p2.0, y: p2.1 }, + Coordinate { x: p3.0, y: p3.1 }, + )) + } +} + +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()); + let p3 = func(&self.2.x_y()); + + let mut new_triangle = Triangle( + Coordinate { x: p1.0, y: p1.1 }, + Coordinate { x: p2.0, y: p2.1 }, + Coordinate { x: p3.0, y: p3.1 }, + ); + + ::std::mem::swap(self, &mut new_triangle); + } +} + #[cfg(test)] mod test { use super::*; diff --git a/geo/src/algorithm/to_postgis.rs b/geo/src/algorithm/to_postgis.rs index 9616f63a7..6e84f2e17 100644 --- a/geo/src/algorithm/to_postgis.rs +++ b/geo/src/algorithm/to_postgis.rs @@ -88,6 +88,12 @@ impl ToPostgis for Geometry { Geometry::GeometryCollection(ref p) => { ewkb::GeometryT::GeometryCollection(p.to_postgis_with_srid(srid)) } + Geometry::Rect(ref p) => { + ewkb::GeometryT::Polygon(p.to_polygon().to_postgis_with_srid(srid)) + } + Geometry::Triangle(ref p) => { + ewkb::GeometryT::Polygon(p.to_polygon().to_postgis_with_srid(srid)) + } } } }