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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! `is_empty(&g)` — true iff `num_points(g) == 0`.
//!
//! Mirrors `boost::geometry::is_empty` from
//! `boost/geometry/algorithms/is_empty.hpp`. Boost's contract is
//! exactly `num_points(g) == 0`
//! (`boost/geometry/test/algorithms/is_empty.cpp:74`:
//! `BOOST_CHECK_EQUAL(detected, bg::num_points(geometry) == 0)`), so
//! this leans on [`crate::num_points::num_points`] rather
//! than re-walking the kind hierarchy. Singletons (`Point` / `Box` /
//! `Segment`) always return `false` because they carry an implicit
//! point set.
use crate::num_points::{NumPointsStrategy, NumPointsStrategyForKind, num_points};
use geometry_trait::Geometry;
/// True iff `g` has no points.
///
/// Mirrors `boost::geometry::is_empty(g)` from
/// `boost/geometry/algorithms/is_empty.hpp`.
#[inline]
#[must_use]
pub fn is_empty<G>(g: &G) -> bool
where
G: Geometry,
G::Kind: NumPointsStrategyForKind,
<G::Kind as NumPointsStrategyForKind>::S: NumPointsStrategy<G>,
{
num_points(g) == 0
}
#[cfg(test)]
mod tests {
//! Reference values from
//! `geometry/test/algorithms/is_empty.cpp`.
use super::is_empty;
use geometry_cs::Cartesian;
use geometry_model::{Box, Linestring, MultiPoint, Point2D, Polygon, Segment, linestring};
type Pt = Point2D<f64, Cartesian>;
/// `is_empty.cpp:110-111` — points are never empty.
#[test]
fn point_is_never_empty() {
assert!(!is_empty(&Pt::new(0.0, 0.0)));
assert!(!is_empty(&Pt::new(1.0, 1.0)));
}
/// `is_empty.cpp:116` — a zero-length segment still has two points.
#[test]
fn segment_zero_length_is_not_empty() {
let s = Segment::new(Pt::new(0.0, 0.0), Pt::new(0.0, 0.0));
assert!(!is_empty(&s));
}
/// `is_empty.cpp:122` — a box is never empty.
#[test]
fn box_is_never_empty() {
let b = Box::from_corners(Pt::new(0.0, 0.0), Pt::new(1.0, 1.0));
assert!(!is_empty(&b));
}
/// `is_empty.cpp:134` — `LINESTRING()` (no points) is empty.
#[test]
fn empty_linestring_is_empty() {
let ls: Linestring<Pt> = Linestring::new();
assert!(is_empty(&ls));
}
/// `is_empty.cpp:135` — a non-empty linestring is not empty.
#[test]
fn nonempty_linestring_is_not_empty() {
let ls: Linestring<Pt> = linestring![(0.0, 0.0), (1.0, 1.0)];
assert!(!is_empty(&ls));
}
/// `is_empty.cpp:145` — `MULTIPOINT()` is empty.
#[test]
fn empty_multi_point_is_empty() {
let mp: MultiPoint<Pt> = MultiPoint(Vec::new());
assert!(is_empty(&mp));
}
/// `is_empty.cpp:226` — a polygon with an empty outer ring is empty.
#[test]
fn polygon_with_zero_point_outer_is_empty() {
let pg: Polygon<Pt> = Polygon::default();
assert!(is_empty(&pg));
}
}