diff --git a/CHANGES.md b/CHANGES.md index fddf260..5430091 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,9 @@ ## Unreleased * Add new entries here +* Support `POINT EMPTY` in conversion to `geo_types`. + Converts to `MultiPoint([])`. + * ## 0.9.1 diff --git a/benches/parse.rs b/benches/parse.rs index 0389fba..4d8c634 100644 --- a/benches/parse.rs +++ b/benches/parse.rs @@ -8,14 +8,14 @@ fn criterion_benchmark(c: &mut criterion::Criterion) { c.bench_function("parse small", |bencher| { let s = include_str!("./small.wkt"); bencher.iter(|| { - let _ = wkt::Wkt::from_str(s).unwrap(); + let _ = wkt::Wkt::::from_str(s).unwrap(); }); }); c.bench_function("parse big", |bencher| { let s = include_str!("./big.wkt"); bencher.iter(|| { - let _ = wkt::Wkt::from_str(s).unwrap(); + let _ = wkt::Wkt::::from_str(s).unwrap(); }); }); } diff --git a/src/conversion.rs b/src/conversion.rs index 378ea0c..f77e566 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -288,7 +288,14 @@ where fn try_from(geometry: Geometry) -> Result { Ok(match geometry { - Geometry::Point(g) => geo_types::Geometry::Point(g.try_into()?), + Geometry::Point(g) => { + // Special case as `geo::Point` can't be empty + if g.0.is_some() { + geo_types::Point::try_from(g)?.into() + } else { + geo_types::MultiPoint(vec![]).into() + } + } Geometry::LineString(g) => geo_types::Geometry::LineString(g.into()), Geometry::Polygon(g) => geo_types::Geometry::Polygon(g.into()), Geometry::MultiLineString(g) => geo_types::Geometry::MultiLineString(g.into()), @@ -358,8 +365,8 @@ mod tests { #[test] fn convert_empty_point() { - let point = Point(None).as_item(); - let res: Result, Error> = point.try_into(); + let point = Point(None); + let res: Result, Error> = point.try_into(); assert!(res.is_err()); } diff --git a/src/deserialize.rs b/src/deserialize.rs index 960afc3..e69e622 100644 --- a/src/deserialize.rs +++ b/src/deserialize.rs @@ -160,15 +160,17 @@ where use serde::Deserialize; Wkt::deserialize(deserializer).and_then(|wkt: Wkt| { use std::convert::TryFrom; - geo_types::Point::try_from(wkt) - .map(|p| Some(p)) - .or_else(|e| { - if let crate::conversion::Error::PointConversionError = e { - // map a WKT: 'POINT EMPTY' to an `Option::None` - return Ok(None); + geo_types::Geometry::try_from(wkt) + .map_err(D::Error::custom) + .and_then(|geom| { + use geo_types::Geometry::*; + match geom { + Point(p) => Ok(Some(p)), + MultiPoint(mp) if mp.0.len() == 0 => Ok(None), + _ => geo_types::Point::try_from(geom) + .map(Some) + .map_err(D::Error::custom), } - - Err(D::Error::custom(e)) }) }) }