1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use types::Polygon;
pub trait Area {
fn area(&self) -> f64;
}
impl Area for Polygon {
fn area(&self) -> f64 {
let linestring = &self.0;
if linestring.0.is_empty() || linestring.0.len() == 1 {
return 0.;
}
let mut tmp = 0.;
for (p1, p2) in linestring.0.iter().zip(linestring.0[1..].iter()) {
tmp += p1.lng() * p2.lat() - p2.lng() * p1.lat();
}
tmp / 2.
}
}
#[cfg(test)]
mod test {
use types::{Coordinate, Point, LineString, Polygon};
use algorithm::area::Area;
#[test]
fn area_empty_polygon_test() {
let poly = Polygon(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());
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());
assert_eq!(poly.area(), 30.);
}
}