1mod interior_point_area;
7mod interior_point_line;
8mod interior_point_point;
9
10#[cfg(feature = "wasm")]
11mod wasm;
12
13use geo_types::{Coord, Geometry};
14
15use interior_point_area::interior_point_area;
16use interior_point_line::interior_point_line;
17use interior_point_point::interior_point_point;
18
19pub fn interior_point(geometry: &Geometry<f64>) -> Option<Coord<f64>> {
30 let dim = dimension_non_empty(geometry);
31 if dim < 0 {
32 return None;
33 }
34
35 match dim {
36 2 => interior_point_area(geometry),
37 1 => interior_point_line(geometry),
38 _ => interior_point_point(geometry),
39 }
40}
41
42fn dimension_non_empty(geometry: &Geometry<f64>) -> i32 {
45 if is_geometry_empty(geometry) {
46 return -1;
47 }
48
49 match geometry {
50 Geometry::Point(_) | Geometry::MultiPoint(_) => 0,
51 Geometry::LineString(_) | Geometry::MultiLineString(_) => 1,
52 Geometry::Polygon(_) | Geometry::MultiPolygon(_) => 2,
53 Geometry::GeometryCollection(gc) => {
54 gc.0.iter().map(dimension_non_empty).max().unwrap_or(-1)
55 }
56 _ => -1,
57 }
58}
59
60fn is_geometry_empty(geometry: &Geometry<f64>) -> bool {
62 match geometry {
63 Geometry::Point(_) => false, Geometry::MultiPoint(mp) => mp.0.is_empty(),
65 Geometry::LineString(ls) => ls.0.is_empty(),
66 Geometry::MultiLineString(mls) => {
67 mls.0.is_empty() || mls.0.iter().all(|ls| ls.0.is_empty())
68 }
69 Geometry::Polygon(p) => p.exterior().0.is_empty(),
70 Geometry::MultiPolygon(mp) => {
71 mp.0.is_empty() || mp.0.iter().all(|p| p.exterior().0.is_empty())
72 }
73 Geometry::GeometryCollection(gc) => gc.0.is_empty() || gc.0.iter().all(is_geometry_empty),
74 _ => true,
75 }
76}