Skip to content

Commit

Permalink
Add Triangle and Rect to Geometry.
Browse files Browse the repository at this point in the history
  • Loading branch information
frewsxcv committed Mar 29, 2020
1 parent 3febc41 commit 3bee141
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 3 deletions.
16 changes: 15 additions & 1 deletion geo-types/src/geometry.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -36,6 +36,8 @@ where
MultiLineString(MultiLineString<T>),
MultiPolygon(MultiPolygon<T>),
GeometryCollection(GeometryCollection<T>),
Rect(Rect<T>),
Triangle(Triangle<T>),
}

impl<T: CoordinateType> From<Point<T>> for Geometry<T> {
Expand Down Expand Up @@ -74,6 +76,18 @@ impl<T: CoordinateType> From<MultiPolygon<T>> for Geometry<T> {
}
}

impl<T: CoordinateType> From<Rect<T>> for Geometry<T> {
fn from(x: Rect<T>) -> Geometry<T> {
Geometry::Rect(x)
}
}

impl<T: CoordinateType> From<Triangle<T>> for Geometry<T> {
fn from(x: Triangle<T>) -> Geometry<T> {
Geometry::Triangle(x)
}
}

impl<T: CoordinateType> Geometry<T> {
/// If this Geometry is a Point, then return that, else None.
///
Expand Down
2 changes: 1 addition & 1 deletion geo-types/src/triangle.rs
Original file line number Diff line number Diff line change
@@ -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<T: CoordinateType>(pub Coordinate<T>, pub Coordinate<T>, pub Coordinate<T>);

Expand Down
59 changes: 58 additions & 1 deletion geo/src/algorithm/map_coords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -416,6 +416,8 @@ impl<T: CoordinateType, NT: CoordinateType> MapCoords<T, NT> for Geometry<T> {
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)),
}
}
}
Expand All @@ -440,6 +442,8 @@ impl<T: CoordinateType, NT: CoordinateType> TryMapCoords<T, NT> for Geometry<T>
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)?)),
}
}
}
Expand All @@ -455,6 +459,8 @@ impl<T: CoordinateType> MapCoordsInplace<T> for Geometry<T> {
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),
}
}
}
Expand Down Expand Up @@ -545,6 +551,57 @@ impl<T: CoordinateType> MapCoordsInplace<T> for Rect<T> {
}
}

impl<T: CoordinateType, NT: CoordinateType> MapCoords<T, NT> for Triangle<T> {
type Output = Triangle<NT>;

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<T: CoordinateType, NT: CoordinateType> TryMapCoords<T, NT> for Triangle<T> {
type Output = Triangle<NT>;

fn try_map_coords(
&self,
func: impl Fn(&(T, T)) -> Result<(NT, NT), Box<dyn Error + Send + Sync>>,
) -> Result<Self::Output, Box<dyn Error + Send + Sync>> {
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<T: CoordinateType> MapCoordsInplace<T> for Triangle<T> {
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::*;
Expand Down
6 changes: 6 additions & 0 deletions geo/src/algorithm/to_postgis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ impl ToPostgis<ewkb::Geometry> for Geometry<f64> {
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))
}
}
}
}

0 comments on commit 3bee141

Please sign in to comment.