Skip to main content

geometry_kernel/
polygonize.rs

1use crate::canonicalize::canonicalize_polygon;
2use crate::precision::PrecisionModel;
3use crate::predicates::signed_ring_area;
4use crate::types::{LineString, LinearRing, Polygon};
5
6pub fn polygonize_closed_lines(lines: &[LineString], precision: PrecisionModel) -> Vec<Polygon> {
7    lines
8        .iter()
9        .filter_map(|line| polygon_from_closed_line(line, precision))
10        .collect()
11}
12
13pub fn polygonize_noded_segments(lines: &[LineString], precision: PrecisionModel) -> Vec<Polygon> {
14    polygonize_closed_lines(lines, precision)
15}
16
17fn polygon_from_closed_line(line: &LineString, precision: PrecisionModel) -> Option<Polygon> {
18    if line.coords.len() < 4 {
19        return None;
20    }
21
22    let first = *line.coords.first()?;
23    let last = *line.coords.last()?;
24    if !precision.same_coord(first, last) {
25        return None;
26    }
27
28    let ring = LinearRing::new(
29        line.coords
30            .iter()
31            .map(|c| precision.snap_coord(*c))
32            .collect(),
33    );
34    if signed_ring_area(&ring).abs() <= precision.epsilon() {
35        return None;
36    }
37
38    Some(canonicalize_polygon(
39        &Polygon::new(ring, Vec::new()),
40        precision,
41    ))
42}