geometry_kernel/
polygonize.rs1use 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}