diff --git a/geozero/src/geo_types/geo_types_writer.rs b/geozero/src/geo_types/geo_types_writer.rs index a0753937..3b0b3ecd 100644 --- a/geozero/src/geo_types/geo_types_writer.rs +++ b/geozero/src/geo_types/geo_types_writer.rs @@ -83,11 +83,12 @@ impl GeomProcessor for GeoWriter { Ok(()) } fn polygon_end(&mut self, tagged: bool, _idx: usize) -> Result<()> { - if self.line_strings.len() == 0 { - return Err(GeozeroError::Geometry("Missing LineString".to_string())); - } - let exterior = self.line_strings.remove(0); - let polygon = Polygon::new(exterior, mem::take(&mut self.line_strings)); + let polygon = if self.line_strings.len() == 0 { + Polygon::new(LineString(vec![]), vec![]) + } else { + let exterior = self.line_strings.remove(0); + Polygon::new(exterior, mem::take(&mut self.line_strings)) + }; if tagged { self.geom = polygon.into(); } else if let Geometry::MultiPolygon(mp) = &mut self.geom { diff --git a/geozero/src/wkt/wkt_reader.rs b/geozero/src/wkt/wkt_reader.rs index e7e1b006..10be4883 100644 --- a/geozero/src/wkt/wkt_reader.rs +++ b/geozero/src/wkt/wkt_reader.rs @@ -186,7 +186,7 @@ fn process_multi_polygon( processor.multipolygon_end(idx) } -#[cfg(test)] +#[cfg(all(test, feature = "with-geo"))] mod test { use super::*; use crate::geo_types::conversion::ToGeo; @@ -203,20 +203,6 @@ mod test { assert_eq!(expected, actual); } - #[test] - fn empty_point() { - let wkt = WktStr("POINT EMPTY"); - let actual = wkt.to_geo().unwrap_err(); - assert!(matches!(actual, GeozeroError::Geometry(_))); - } - - #[test] - fn empty_point_roundtrip() { - let wkt = WktStr("POINT EMPTY"); - let actual = wkt.to_wkt().unwrap(); - assert_eq!("POINT EMPTY", &actual); - } - #[test] fn multi_point() { // Both of these are failing @@ -321,6 +307,7 @@ mod test { } #[test] + #[cfg(feature = "with-geojson")] fn geometry_collection() { let wkt = WktStr( "GEOMETRYCOLLECTION (POINT (40 10), @@ -344,8 +331,8 @@ mod test { } #[test] - fn geometry_collection_with_empty_point() { - let str = "GEOMETRYCOLLECTION(POINT(40 10),LINESTRING(10 10,20 20,10 40),POINT EMPTY)"; + fn geometry_collection_roundtrip() { + let str = "GEOMETRYCOLLECTION(POINT(40 10),LINESTRING(10 10,20 20,10 40),POLYGON((40 40,20 45,45 30,40 40)))"; let wkt = WktStr(str); use crate::wkt::conversion::ToWkt; @@ -354,14 +341,75 @@ mod test { assert_eq!(str, &roundtripped); } - #[test] - fn geometry_collection_roundtrip() { - let str = "GEOMETRYCOLLECTION(POINT(40 10),LINESTRING(10 10,20 20,10 40),POLYGON((40 40,20 45,45 30,40 40)))"; - let wkt = WktStr(str); + mod empties { + use super::*; - use crate::wkt::conversion::ToWkt; - let roundtripped = wkt.to_wkt().unwrap(); + #[test] + fn empty_point() { + let wkt = WktStr("POINT EMPTY"); + let actual = wkt.to_geo().unwrap_err(); + assert!(matches!(actual, GeozeroError::Geometry(_))); + } - assert_eq!(str, &roundtripped); + #[test] + fn empty_point_roundtrip() { + let wkt = WktStr("POINT EMPTY"); + let actual = wkt.to_wkt().unwrap(); + assert_eq!("POINT EMPTY", &actual); + } + + #[test] + fn geometry_collection_with_empty_point() { + let str = "GEOMETRYCOLLECTION(POINT(40 10),LINESTRING(10 10,20 20,10 40),POINT EMPTY)"; + let wkt = WktStr(str); + + use crate::wkt::conversion::ToWkt; + let roundtripped = wkt.to_wkt().unwrap(); + + assert_eq!(str, &roundtripped); + } + + #[test] + fn empty_line_string() { + let wkt = WktStr("LINESTRING EMPTY"); + let actual = wkt.to_geo().unwrap(); + let expected: geo_types::Geometry = line_string![].into(); + assert_eq!(expected, actual); + } + + #[test] + fn empty_multi_line_string() { + let wkt = WktStr("MULTILINESTRING EMPTY"); + let actual = wkt.to_geo().unwrap(); + let expected: geo_types::Geometry = geo_types::MultiLineString(vec![]).into(); + assert_eq!(expected, actual); + } + + #[test] + fn empty_polygon() { + let wkt = WktStr("POLYGON EMPTY"); + let actual = wkt.to_geo().unwrap(); + let expected: geo_types::Geometry = polygon![].into(); + assert_eq!(expected, actual); + } + + #[test] + fn empty_multi_polygon() { + let wkt = WktStr("MULTIPOLYGON EMPTY"); + let actual = wkt.to_geo().unwrap(); + let expected: geo_types::Geometry = geo_types::MultiPolygon(vec![]).into(); + assert_eq!(expected, actual); + } + + #[test] + #[ignore = "geo::GeometryCollections is known to be broken https://github.com/georust/geozero/issues/11"] + fn empty_geometry_collection() { + let wkt = WktStr("GEOMETRYCOLLECTION EMPTY"); + let actual = wkt.to_geo().unwrap(); + + let expected = + geo_types::Geometry::GeometryCollection(geo_types::GeometryCollection(vec![])); + assert_eq!(expected, actual); + } } }