Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document Polygon struct parameters #68

Merged
4 commits merged into from
Oct 16, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions src/algorithm/area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub trait Area<T> where T: Float
/// let p = |x, y| Point(Coordinate { x: x, y: y });
/// let v = Vec::new();
/// let linestring = LineString(vec![p(0., 0.), p(5., 0.), p(5., 6.), p(0., 6.), p(0., 0.)]);
/// let poly = Polygon(linestring, v);
/// let poly = Polygon::new(linestring, v);
/// assert_eq!(poly.area(), 30.);
/// ```
fn area(&self) -> T;
Expand All @@ -36,8 +36,8 @@ impl<T> Area<T> for Polygon<T>
where T: Float
{
fn area(&self) -> T {
self.1.iter().fold(get_linestring_area(&self.0),
|total, next| total - get_linestring_area(next))
self.interiors.iter().fold(get_linestring_area(&self.exterior),
|total, next| total - get_linestring_area(next))
}
}

Expand All @@ -64,20 +64,20 @@ mod test {
// Area of the polygon
#[test]
fn area_empty_polygon_test() {
let poly = Polygon::<f64>(LineString(Vec::new()), Vec::new());
let poly = Polygon::<f64>::new(LineString(Vec::new()), Vec::new());
assert_eq!(poly.area(), 0.);
}

#[test]
fn area_one_point_polygon_test() {
let poly = Polygon(LineString(vec![Point::new(1., 0.)]), Vec::new());
let poly = Polygon::new(LineString(vec![Point::new(1., 0.)]), Vec::new());
assert_eq!(poly.area(), 0.);
}
#[test]
fn area_polygon_test() {
let p = |x, y| Point(Coordinate { x: x, y: y });
let linestring = LineString(vec![p(0., 0.), p(5., 0.), p(5., 6.), p(0., 6.), p(0., 0.)]);
let poly = Polygon(linestring, Vec::new());
let poly = Polygon::new(linestring, Vec::new());
assert_eq!(poly.area(), 30.);
}
#[test]
Expand All @@ -91,18 +91,21 @@ mod test {
let outer = LineString(vec![p(0., 0.), p(10., 0.), p(10., 10.), p(0., 10.), p(0., 0.)]);
let inner0 = LineString(vec![p(1., 1.), p(2., 1.), p(2., 2.), p(1., 2.), p(1., 1.)]);
let inner1 = LineString(vec![p(5., 5.), p(6., 5.), p(6., 6.), p(5., 6.), p(5., 5.)]);
let poly = Polygon(outer, vec![inner0, inner1]);
let poly = Polygon::new(outer, vec![inner0, inner1]);
assert_eq!(poly.area(), 98.);
}
#[test]
fn area_multipolygon_test() {
let p = |x, y| Point(Coordinate { x: x, y: y });
let poly0 = Polygon(LineString(vec![p(0., 0.), p(10., 0.), p(10., 10.), p(0., 10.), p(0., 0.)]),
Vec::new());
let poly1 = Polygon(LineString(vec![p(1., 1.), p(2., 1.), p(2., 2.), p(1., 2.), p(1., 1.)]),
Vec::new());
let poly2 = Polygon(LineString(vec![p(5., 5.), p(6., 5.), p(6., 6.), p(5., 6.), p(5., 5.)]),
Vec::new());
let poly0 = Polygon::new(LineString(vec![p(0., 0.), p(10., 0.), p(10., 10.), p(0., 10.),
p(0., 0.)]),
Vec::new());
let poly1 = Polygon::new(LineString(vec![p(1., 1.), p(2., 1.), p(2., 2.), p(1., 2.),
p(1., 1.)]),
Vec::new());
let poly2 = Polygon::new(LineString(vec![p(5., 5.), p(6., 5.), p(6., 6.), p(5., 6.),
p(5., 5.)]),
Vec::new());
let mpoly = MultiPolygon(vec![poly0, poly1, poly2]);
assert_eq!(mpoly.area(), 102.);
}
Expand Down
12 changes: 6 additions & 6 deletions src/algorithm/boundingbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ impl<T> BoundingBox<T> for Polygon<T>
/// Return the BoundingBox for a Polygon
///
fn bbox(&self) -> Option<Bbox<T>> {
let line = &self.0;
let line = &self.exterior;
get_bbox(&line.0)
}
}
Expand All @@ -106,7 +106,7 @@ impl<T> BoundingBox<T> for MultiPolygon<T>
/// Return the BoundingBox for a MultiPolygon
///
fn bbox(&self) -> Option<Bbox<T>> {
get_bbox(self.0.iter().flat_map(|poly| (poly.0).0.iter()))
get_bbox(self.0.iter().flat_map(|poly| (poly.exterior).0.iter()))
}
}

Expand Down Expand Up @@ -162,15 +162,15 @@ mod test {
let p = |x, y| Point(Coordinate { x: x, y: y });
let linestring = LineString(vec![p(0., 0.), p(5., 0.), p(5., 6.), p(0., 6.), p(0., 0.)]);
let line_bbox = linestring.bbox().unwrap();
let poly = Polygon(linestring, Vec::new());
let poly = Polygon::new(linestring, Vec::new());
assert_eq!(line_bbox, poly.bbox().unwrap());
}
#[test]
fn multipolygon_test(){
let p = |x, y| Point(Coordinate { x: x, y: y });
let mpoly = MultiPolygon(vec![Polygon(LineString(vec![p(0., 0.), p(50., 0.), p(0., -70.), p(0., 0.)]), Vec::new()),
Polygon(LineString(vec![p(0., 0.), p(5., 0.), p(0., 80.), p(0., 0.)]), Vec::new()),
Polygon(LineString(vec![p(0., 0.), p(-60., 0.), p(0., 6.), p(0., 0.)]), Vec::new()),
let mpoly = MultiPolygon(vec![Polygon::new(LineString(vec![p(0., 0.), p(50., 0.), p(0., -70.), p(0., 0.)]), Vec::new()),
Polygon::new(LineString(vec![p(0., 0.), p(5., 0.), p(0., 80.), p(0., 0.)]), Vec::new()),
Polygon::new(LineString(vec![p(0., 0.), p(-60., 0.), p(0., 6.), p(0., 0.)]), Vec::new()),
]);
let bbox = Bbox{xmin: -60., ymax: 80., xmax: 50., ymin: -70.};
assert_eq!(bbox, mpoly.bbox().unwrap());
Expand Down
14 changes: 7 additions & 7 deletions src/algorithm/centroid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl<T> Centroid<T> for Polygon<T>
///
fn centroid(&self) -> Option<Point<T>> {
// TODO: consideration of inner polygons;
let linestring = &self.0;
let linestring = &self.exterior;
let vect = &linestring.0;
if vect.is_empty() {
return None;
Expand Down Expand Up @@ -156,23 +156,23 @@ mod test {
let v1 = Vec::new();
let v2 = Vec::new();
let linestring = LineString::<f64>(v1);
let poly = Polygon(linestring, v2);
let poly = Polygon::new(linestring, v2);
assert!(poly.centroid().is_none());
}
#[test]
fn polygon_one_point_test() {
let p = Point(Coordinate { x: 2., y: 1. });
let v = Vec::new();
let linestring = LineString(vec![p]);
let poly = Polygon(linestring, v);
let poly = Polygon::new(linestring, v);
assert_eq!(poly.centroid(), Some(p));
}
#[test]
fn polygon_test() {
let p = |x, y| Point(Coordinate { x: x, y: y });
let v = Vec::new();
let linestring = LineString(vec![p(0., 0.), p(2., 0.), p(2., 2.), p(0., 2.), p(0., 0.)]);
let poly = Polygon(linestring, v);
let poly = Polygon::new(linestring, v);
assert_eq!(poly.centroid(), Some(p(1., 1.)));
}
/// Tests: Centroid of MultiPolygon
Expand All @@ -184,16 +184,16 @@ mod test {
fn multipolygon_one_polygon_test() {
let p = |x, y| Point(Coordinate { x: x, y: y });
let linestring = LineString(vec![p(0., 0.), p(2., 0.), p(2., 2.), p(0., 2.), p(0., 0.)]);
let poly = Polygon(linestring, Vec::new());
let poly = Polygon::new(linestring, Vec::new());
assert_eq!(MultiPolygon(vec![poly]).centroid(), Some(p(1., 1.)));
}
#[test]
fn multipolygon_two_polygons_test() {
let p = |x, y| Point(Coordinate { x: x, y: y });
let linestring = LineString(vec![p(2., 1.), p(5., 1.), p(5., 3.), p(2., 3.), p(2., 1.)]);
let poly1 = Polygon(linestring, Vec::new());
let poly1 = Polygon::new(linestring, Vec::new());
let linestring = LineString(vec![p(7., 1.), p(8., 1.), p(8., 2.), p(7., 2.), p(7., 1.)]);
let poly2 = Polygon(linestring, Vec::new());
let poly2 = Polygon::new(linestring, Vec::new());
let dist = MultiPolygon(vec![poly1, poly2]).centroid().unwrap().distance(&p(4.07142857142857, 1.92857142857143));
assert!(dist < COORD_PRECISION);
}
Expand Down
49 changes: 22 additions & 27 deletions src/algorithm/contains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub trait Contains<Rhs = Self> {
/// let p = |x, y| Point(Coordinate { x: x, y: y });
/// let v = Vec::new();
/// let linestring = LineString(vec![p(0., 0.), p(2., 0.), p(2., 2.), p(0., 2.), p(0., 0.)]);
/// let poly = Polygon(linestring.clone(), v);
/// let poly = Polygon::new(linestring.clone(), v);
///
/// //Point in Point
/// assert!(p(2., 0.).contains(&p(2., 0.)));
Expand Down Expand Up @@ -123,10 +123,10 @@ impl<T> Contains<Point<T>> for Polygon<T>
where T: Float
{
fn contains(&self, p: &Point<T>) -> bool {
match get_position(p, &self.0) {
match get_position(p, &self.exterior) {
PositionPoint::OnBoundary => false,
PositionPoint::Outside => false,
_ => self.1.iter().all(|ls| get_position(p, ls) == PositionPoint::Outside),
_ => self.interiors.iter().all(|ls| get_position(p, ls) == PositionPoint::Outside),
}
}
}
Expand Down Expand Up @@ -188,26 +188,26 @@ mod test {
#[test]
fn empty_polygon_test() {
let linestring = LineString(Vec::new());
let poly = Polygon(linestring, Vec::new());
let poly = Polygon::new(linestring, Vec::new());
assert!(!poly.contains(&Point::new(2., 1.)));
}
#[test]
fn polygon_with_one_point_test() {
let linestring = LineString(vec![Point::new(2., 1.)]);
let poly = Polygon(linestring, Vec::new());
let poly = Polygon::new(linestring, Vec::new());
assert!(!poly.contains(&Point::new(3., 1.)));
}
#[test]
fn polygon_with_one_point_is_vertex_test() {
let linestring = LineString(vec![Point::new(2., 1.)]);
let poly = Polygon(linestring, Vec::new());
let poly = Polygon::new(linestring, Vec::new());
assert!(!poly.contains(&Point::new(2., 1.)));
}
#[test]
fn polygon_with_point_on_boundary_test() {
let p = |x, y| Point(Coordinate { x: x, y: y });
let linestring = LineString(vec![p(0., 0.), p(2., 0.), p(2., 2.), p(0., 2.), p(0., 0.)]);
let poly = Polygon(linestring, Vec::new());
let poly = Polygon::new(linestring, Vec::new());
assert!(!poly.contains(&p(1., 0.)));
assert!(!poly.contains(&p(2., 1.)));
assert!(!poly.contains(&p(1., 2.)));
Expand All @@ -217,14 +217,14 @@ mod test {
fn point_in_polygon_test() {
let p = |x, y| Point(Coordinate { x: x, y: y });
let linestring = LineString(vec![p(0., 0.), p(2., 0.), p(2., 2.), p(0., 2.), p(0., 0.)]);
let poly = Polygon(linestring, Vec::new());
let poly = Polygon::new(linestring, Vec::new());
assert!(poly.contains(&p(1., 1.)));
}
#[test]
fn point_out_polygon_test() {
let p = |x, y| Point(Coordinate { x: x, y: y });
let linestring = LineString(vec![p(0., 0.), p(2., 0.), p(2., 2.), p(0., 2.), p(0., 0.)]);
let poly = Polygon(linestring, Vec::new());
let poly = Polygon::new(linestring, Vec::new());
assert!(!poly.contains(&p(2.1, 1.)));
assert!(!poly.contains(&p(1., 2.1)));
assert!(!poly.contains(&p(2.1, 2.1)));
Expand All @@ -238,7 +238,7 @@ mod test {
p(1.5, 1.5),
p(0.0, 1.5),
p(0.0, 0.0)]);
let poly = Polygon(linestring, vec![inner_linestring]);
let poly = Polygon::new(linestring, vec![inner_linestring]);
assert!(poly.contains(&p(0.25, 0.25)));
assert!(!poly.contains(&p(1., 1.)));
assert!(!poly.contains(&p(1.5, 1.5)));
Expand All @@ -253,12 +253,10 @@ mod test {
#[test]
fn empty_multipolygon_two_polygons_test() {
let p = |x, y| Point(Coordinate { x: x, y: y });
let poly1 = Polygon(LineString(vec![p(0., 0.), p(1., 0.), p(1., 1.), p(0., 1.),
p(0., 0.)]),
Vec::new());
let poly2 = Polygon(LineString(vec![p(2., 0.), p(3., 0.), p(3., 1.), p(2., 1.),
p(2., 0.)]),
Vec::new());
let poly1 = Polygon::new(LineString(vec![p(0., 0.), p(1., 0.), p(1., 1.), p(0., 1.), p(0., 0.)]),
Vec::new());
let poly2 = Polygon::new(LineString(vec![p(2., 0.), p(3., 0.), p(3., 1.), p(2., 1.), p(2., 0.)]),
Vec::new());
let multipoly = MultiPolygon(vec![poly1, poly2]);
assert!(multipoly.contains(&Point::new(0.5, 0.5)));
assert!(multipoly.contains(&Point::new(2.5, 0.5)));
Expand All @@ -267,12 +265,10 @@ mod test {
#[test]
fn empty_multipolygon_two_polygons_and_inner_test() {
let p = |x, y| Point(Coordinate { x: x, y: y });
let poly1 = Polygon(LineString(vec![p(0., 0.), p(5., 0.), p(5., 6.), p(0., 6.),
p(0., 0.)]),
vec![LineString(vec![p(1., 1.), p(4., 1.), p(4., 4.), p(1., 1.)])]);
let poly2 = Polygon(LineString(vec![p(9., 0.), p(14., 0.), p(14., 4.), p(9., 4.),
p(9., 0.)]),
Vec::new());
let poly1 = Polygon::new(LineString(vec![p(0., 0.), p(5., 0.), p(5., 6.), p(0., 6.), p(0., 0.)]),
vec![LineString(vec![p(1., 1.), p(4., 1.), p(4., 4.), p(1., 1.)])]);
let poly2 = Polygon::new(LineString(vec![p(9., 0.), p(14., 0.), p(14., 4.), p(9., 4.), p(9., 0.)]),
Vec::new());

let multipoly = MultiPolygon(vec![poly1, poly2]);
assert!(multipoly.contains(&Point::new(3., 5.)));
Expand All @@ -285,7 +281,7 @@ mod test {
fn linestring_in_polygon_with_linestring_is_boundary_test() {
let p = |x, y| Point(Coordinate { x: x, y: y });
let linestring = LineString(vec![p(0., 0.), p(2., 0.), p(2., 2.), p(0., 2.), p(0., 0.)]);
let poly = Polygon(linestring.clone(), Vec::new());
let poly = Polygon::new(linestring.clone(), Vec::new());
assert!(!poly.contains(&linestring.clone()));
assert!(!poly.contains(&LineString(vec![p(0., 0.), p(2., 0.)])));
assert!(!poly.contains(&LineString(vec![p(2., 0.), p(2., 2.)])));
Expand All @@ -295,17 +291,16 @@ mod test {
fn linestring_outside_polygon_test() {
let p = |x, y| Point(Coordinate { x: x, y: y });
let linestring = LineString(vec![p(0., 0.), p(2., 0.), p(2., 2.), p(0., 2.), p(0., 0.)]);
let poly = Polygon(linestring, Vec::new());
let poly = Polygon::new(linestring, Vec::new());
assert!(!poly.contains(&LineString(vec![p(1., 1.), p(3., 0.)])));
assert!(!poly.contains(&LineString(vec![p(3., 0.), p(5., 2.)])));
}
#[test]
fn linestring_in_inner_polygon_test() {
let p = |x, y| Point(Coordinate { x: x, y: y });

let poly = Polygon(LineString(vec![p(0., 0.), p(5., 0.), p(5., 6.), p(0., 6.), p(0., 0.)]),
vec![LineString(vec![p(1., 1.), p(4., 1.), p(4., 4.), p(1., 4.),
p(1., 1.)])]);
let poly = Polygon::new(LineString(vec![p(0., 0.), p(5., 0.), p(5., 6.), p(0., 6.), p(0., 0.)]),
vec![LineString(vec![p(1., 1.), p(4., 1.), p(4., 4.), p(1., 4.), p(1., 1.)])]);
assert!(!poly.contains(&LineString(vec![p(2., 2.), p(3., 3.)])));
assert!(!poly.contains(&LineString(vec![p(2., 2.), p(2., 5.)])));
assert!(!poly.contains(&LineString(vec![p(3., 0.5), p(3., 5.)])));
Expand Down
16 changes: 8 additions & 8 deletions src/algorithm/distance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub trait Distance<T, Rhs = Self> {
/// (5., 1.)
/// ];
/// let ls = LineString(points.iter().map(|e| Point::new(e.0, e.1)).collect());
/// let poly = Polygon(ls, vec![]);
/// let poly = Polygon::new(ls, vec![]);
/// // A Random point outside the polygon
/// let p = Point::new(2.5, 0.5);
/// let dist = p.distance(&poly);
Expand Down Expand Up @@ -130,7 +130,7 @@ impl<T> Distance<T, Polygon<T>> for Point<T>
{
fn distance(&self, polygon: &Polygon<T>) -> T {
// get exterior ring
let exterior = &polygon.0;
let exterior = &polygon.exterior;
// exterior ring as a LineString
let ext_ring = &exterior.0;
// No need to continue if the polygon contains the point, or is zero-length
Expand All @@ -140,7 +140,7 @@ impl<T> Distance<T, Polygon<T>> for Point<T>
// minimum priority queue
let mut dist_queue: BinaryHeap<Mindist<T>> = BinaryHeap::new();
// we've got interior rings
for ring in &polygon.1 {
for ring in &polygon.interiors {
dist_queue.push(Mindist { distance: self.distance(ring) })
}
for chunk in ext_ring.windows(2) {
Expand Down Expand Up @@ -206,7 +206,7 @@ mod test {
let points = vec![(5., 1.), (4., 2.), (4., 3.), (5., 4.), (6., 4.), (7., 3.), (7., 2.),
(6., 1.), (5., 1.)];
let ls = LineString(points.iter().map(|e| Point::new(e.0, e.1)).collect());
let poly = Polygon(ls, vec![]);
let poly = Polygon::new(ls, vec![]);
// A Random point outside the octagon
let p = Point::new(2.5, 0.5);
let dist = p.distance(&poly);
Expand All @@ -219,7 +219,7 @@ mod test {
let points = vec![(5., 1.), (4., 2.), (4., 3.), (5., 4.), (6., 4.), (7., 3.), (7., 2.),
(6., 1.), (5., 1.)];
let ls = LineString(points.iter().map(|e| Point::new(e.0, e.1)).collect());
let poly = Polygon(ls, vec![]);
let poly = Polygon::new(ls, vec![]);
// A Random point inside the octagon
let p = Point::new(5.5, 2.1);
let dist = p.distance(&poly);
Expand All @@ -232,7 +232,7 @@ mod test {
let points = vec![(5., 1.), (4., 2.), (4., 3.), (5., 4.), (6., 4.), (7., 3.), (7., 2.),
(6., 1.), (5., 1.)];
let ls = LineString(points.iter().map(|e| Point::new(e.0, e.1)).collect());
let poly = Polygon(ls, vec![]);
let poly = Polygon::new(ls, vec![]);
// A point on the octagon
let p = Point::new(5.0, 1.0);
let dist = p.distance(&poly);
Expand All @@ -244,7 +244,7 @@ mod test {
// an empty Polygon
let points = vec![];
let ls = LineString(points);
let poly = Polygon(ls, vec![]);
let poly = Polygon::new(ls, vec![]);
// A point on the octagon
let p = Point::new(2.5, 0.5);
let dist = p.distance(&poly);
Expand Down Expand Up @@ -274,7 +274,7 @@ mod test {
];
let ls_ext = LineString(ext_points.iter().map(|e| Point::new(e.0, e.1)).collect());
let ls_int = LineString(int_points.iter().map(|e| Point::new(e.0, e.1)).collect());
let poly = Polygon(ls_ext, vec![ls_int]);
let poly = Polygon::new(ls_ext, vec![ls_int]);
// A point inside the cutout triangle
let p = Point::new(3.5, 2.5);
let dist = p.distance(&poly);
Expand Down
Loading