From eacfaa4c7e8e494cbb6e94983f72522207b8eca4 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Fri, 24 Jul 2020 10:44:58 -0400 Subject: [PATCH] - --- README.md | 2 +- src/conversion/from_geo_types.rs | 190 +++++++++++++++---------------- src/conversion/mod.rs | 28 ++--- src/conversion/to_geo_types.rs | 32 +++--- src/feature.rs | 56 ++++----- src/feature_collection.rs | 2 - src/geojson.rs | 36 +++--- src/geometry.rs | 56 +++++---- src/lib.rs | 18 ++- src/position.rs | 3 +- src/util.rs | 2 +- tests/roundtrip.rs | 4 +- 12 files changed, 210 insertions(+), 219 deletions(-) diff --git a/README.md b/README.md index cf089e77..d7a12900 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ use geojson::{Feature, GeoJson, Geometry, Value}; use serde_json::{Map, to_value}; let geometry = Geometry::new( - Value::Point(vec![-120.66029,35.2812]) + ValueBase::Point(vec![-120.66029,35.2812]) ); let mut properties = Map::new(); diff --git a/src/conversion/from_geo_types.rs b/src/conversion/from_geo_types.rs index bfefc319..47690538 100644 --- a/src/conversion/from_geo_types.rs +++ b/src/conversion/from_geo_types.rs @@ -6,19 +6,19 @@ use num_traits::Float; use std::convert::From; #[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))] -impl<'a, T> From<&'a geo_types::Point> for geometry::Value +impl<'a, T, P: Position> From<&'a geo_types::Point> for geometry::ValueBase

where T: Float, { fn from(point: &geo_types::Point) -> Self { let coords = create_point_type(point); - geometry::Value::Point(coords) + geometry::ValueBase::Point(coords) } } #[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))] -impl<'a, T> From<&'a geo_types::MultiPoint> for geometry::Value +impl<'a, T, P: Position> From<&'a geo_types::MultiPoint> for geometry::ValueBase

where T: Float, { @@ -29,60 +29,60 @@ where .map(|point| create_point_type(point)) .collect(); - geometry::Value::MultiPoint(coords) + geometry::ValueBase::MultiPoint(coords) } } #[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))] -impl<'a, T> From<&'a geo_types::LineString> for geometry::Value +impl<'a, T, P: Position> From<&'a geo_types::LineString> for geometry::ValueBase

where T: Float, { fn from(line_string: &geo_types::LineString) -> Self { let coords = create_line_string_type(line_string); - geometry::Value::LineString(coords) + geometry::ValueBase::LineString(coords) } } #[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))] -impl<'a, T> From<&'a geo_types::MultiLineString> for geometry::Value +impl<'a, T, P: Position> From<&'a geo_types::MultiLineString> for geometry::ValueBase

where T: Float, { fn from(multi_line_string: &geo_types::MultiLineString) -> Self { let coords = create_multi_line_string_type(multi_line_string); - geometry::Value::MultiLineString(coords) + geometry::ValueBase::MultiLineString(coords) } } #[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))] -impl<'a, T> From<&'a geo_types::Polygon> for geometry::Value +impl<'a, T, P: Position> From<&'a geo_types::Polygon> for geometry::ValueBase

where T: Float, { fn from(polygon: &geo_types::Polygon) -> Self { let coords = create_polygon_type(polygon); - geometry::Value::Polygon(coords) + geometry::ValueBase::Polygon(coords) } } #[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))] -impl<'a, T> From<&'a geo_types::MultiPolygon> for geometry::Value +impl<'a, T, P: Position> From<&'a geo_types::MultiPolygon> for geometry::ValueBase

where T: Float, { fn from(multi_polygon: &geo_types::MultiPolygon) -> Self { let coords = create_multi_polygon_type(multi_polygon); - geometry::Value::MultiPolygon(coords) + geometry::ValueBase::MultiPolygon(coords) } } #[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))] -impl<'a, T> From<&'a geo_types::GeometryCollection> for geometry::Value +impl<'a, T, P: Position> From<&'a geo_types::GeometryCollection> for geometry::ValueBase

where T: Float, { @@ -90,29 +90,29 @@ where let coords = geometry_collection .0 .iter() - .map(|geometry| geometry::Geometry::new(geometry::Value::from(geometry))) + .map(|geometry| geometry::GeometryBase::new(geometry::ValueBase::from(geometry))) .collect(); - geometry::Value::GeometryCollection(coords) + geometry::ValueBase::GeometryCollection(coords) } } #[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))] -impl<'a, T> From<&'a geo_types::Geometry> for geometry::Value +impl<'a, T, P: Position> From<&'a geo_types::Geometry> for geometry::ValueBase

where T: Float, { fn from(geometry: &'a geo_types::Geometry) -> Self { match *geometry { - geo_types::Geometry::Point(ref point) => geometry::Value::from(point), - geo_types::Geometry::MultiPoint(ref multi_point) => geometry::Value::from(multi_point), - geo_types::Geometry::LineString(ref line_string) => geometry::Value::from(line_string), + geo_types::Geometry::Point(ref point) => geometry::ValueBase::from(point), + geo_types::Geometry::MultiPoint(ref multi_point) => geometry::ValueBase::from(multi_point), + geo_types::Geometry::LineString(ref line_string) => geometry::ValueBase::from(line_string), geo_types::Geometry::MultiLineString(ref multi_line_string) => { - geometry::Value::from(multi_line_string) + geometry::ValueBase::from(multi_line_string) } - geo_types::Geometry::Polygon(ref polygon) => geometry::Value::from(polygon), + geo_types::Geometry::Polygon(ref polygon) => geometry::ValueBase::from(polygon), geo_types::Geometry::MultiPolygon(ref multi_polygon) => { - geometry::Value::from(multi_polygon) + geometry::ValueBase::from(multi_polygon) } _ => panic!("GeometryCollection not allowed"), } @@ -185,7 +185,7 @@ where #[cfg(test)] mod tests { - use crate::{Geometry, Value}; + use crate::{GeometryBase, ValueBase}; use geo_types; use geo_types::{ GeometryCollection, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, @@ -195,22 +195,22 @@ mod tests { fn geo_point_conversion_test() { // Test with f32 coordinates let geo_point = Point::new(40.02f32, 116.34f32); - let geojson_point = Value::from(&geo_point); + let geojson_point = ValueBase::<(f64, f64)>::from(&geo_point); - if let Value::Point(c) = geojson_point { - assert_almost_eq!(geo_point.x(), c[0] as f32, 1e-6); - assert_almost_eq!(geo_point.y(), c[1] as f32, 1e-6); + if let ValueBase::Point(c) = geojson_point { + assert_almost_eq!(geo_point.x(), c.0 as f32, 1e-6); + assert_almost_eq!(geo_point.y(), c.1 as f32, 1e-6); } else { panic!("Not valid geometry {:?}", geojson_point); } // Test with f64 coordinates. let geo_point = Point::new(40.02f64, 116.34f64); - let geojson_point = Value::from(&geo_point); + let geojson_point = ValueBase::<(f64, f64)>::from(&geo_point); - if let Value::Point(c) = geojson_point { - assert_almost_eq!(geo_point.x(), c[0], 1e-6); - assert_almost_eq!(geo_point.y(), c[1], 1e-6); + if let ValueBase::Point(c) = geojson_point { + assert_almost_eq!(geo_point.x(), c.0, 1e-6); + assert_almost_eq!(geo_point.y(), c.1, 1e-6); } else { panic!("Not valid geometry {:?}", geojson_point); } @@ -222,13 +222,13 @@ mod tests { let p2 = Point::new(13.02f64, 24.34f64); let geo_multi_point = MultiPoint(vec![p1, p2]); - let geojson_multi_point = Value::from(&geo_multi_point); + let geojson_multi_point = ValueBase::<(f64, f64)>::from(&geo_multi_point); - if let Value::MultiPoint(c) = geojson_multi_point { - assert_almost_eq!(p1.x(), c[0][0], 1e-6); - assert_almost_eq!(p1.y(), c[0][1], 1e-6); - assert_almost_eq!(p2.x(), c[1][0], 1e-6); - assert_almost_eq!(p2.y(), c[1][1], 1e-6); + if let ValueBase::MultiPoint(c) = geojson_multi_point { + assert_almost_eq!(p1.x(), c[0].0, 1e-6); + assert_almost_eq!(p1.y(), c[0].1, 1e-6); + assert_almost_eq!(p2.x(), c[1].0, 1e-6); + assert_almost_eq!(p2.y(), c[1].1, 1e-6); } else { panic!("Not valid geometry {:?}", geojson_multi_point); } @@ -240,13 +240,13 @@ mod tests { let p2 = Point::new(13.02f64, 24.34f64); let geo_line_string = LineString::from(vec![p1, p2]); - let geojson_line_point = Value::from(&geo_line_string); + let geojson_line_point = ValueBase::<(f64, f64)>::from(&geo_line_string); - if let Value::LineString(c) = geojson_line_point { - assert_almost_eq!(p1.x(), c[0][0], 1e-6); - assert_almost_eq!(p1.y(), c[0][1], 1e-6); - assert_almost_eq!(p2.x(), c[1][0], 1e-6); - assert_almost_eq!(p2.y(), c[1][1], 1e-6); + if let ValueBase::LineString(c) = geojson_line_point { + assert_almost_eq!(p1.x(), c[0].0, 1e-6); + assert_almost_eq!(p1.y(), c[0].1, 1e-6); + assert_almost_eq!(p2.x(), c[1].0, 1e-6); + assert_almost_eq!(p2.y(), c[1].1, 1e-6); } else { panic!("Not valid geometry {:?}", geojson_line_point); } @@ -263,17 +263,17 @@ mod tests { let geo_line_string2 = LineString::from(vec![p3, p4]); let geo_multi_line_string = MultiLineString(vec![geo_line_string1, geo_line_string2]); - let geojson_multi_line_point = Value::from(&geo_multi_line_string); - - if let Value::MultiLineString(c) = geojson_multi_line_point { - assert_almost_eq!(p1.x(), c[0][0][0], 1e-6); - assert_almost_eq!(p1.y(), c[0][0][1], 1e-6); - assert_almost_eq!(p2.x(), c[0][1][0], 1e-6); - assert_almost_eq!(p2.y(), c[0][1][1], 1e-6); - assert_almost_eq!(p3.x(), c[1][0][0], 1e-6); - assert_almost_eq!(p3.y(), c[1][0][1], 1e-6); - assert_almost_eq!(p4.x(), c[1][1][0], 1e-6); - assert_almost_eq!(p4.y(), c[1][1][1], 1e-6); + let geojson_multi_line_point = ValueBase::<(f64, f64)>::from(&geo_multi_line_string); + + if let ValueBase::MultiLineString(c) = geojson_multi_line_point { + assert_almost_eq!(p1.x(), c[0][0].0, 1e-6); + assert_almost_eq!(p1.y(), c[0][0].1, 1e-6); + assert_almost_eq!(p2.x(), c[0][1].0, 1e-6); + assert_almost_eq!(p2.y(), c[0][1].1, 1e-6); + assert_almost_eq!(p3.x(), c[1][0].0, 1e-6); + assert_almost_eq!(p3.y(), c[1][0].1, 1e-6); + assert_almost_eq!(p4.x(), c[1][1].0, 1e-6); + assert_almost_eq!(p4.y(), c[1][1].1, 1e-6); } else { panic!("Not valid geometry {:?}", geojson_multi_line_point); } @@ -292,21 +292,21 @@ mod tests { let geo_line_string2 = LineString::from(vec![p4, p5, p6, p4]); let geo_polygon = Polygon::new(geo_line_string1, vec![geo_line_string2]); - let geojson_polygon = Value::from(&geo_polygon); - - if let Value::Polygon(c) = geojson_polygon { - assert_almost_eq!(p1.x(), c[0][0][0], 1e-6); - assert_almost_eq!(p1.y(), c[0][0][1], 1e-6); - assert_almost_eq!(p2.x(), c[0][1][0], 1e-6); - assert_almost_eq!(p2.y(), c[0][1][1], 1e-6); - assert_almost_eq!(p3.x(), c[0][2][0], 1e-6); - assert_almost_eq!(p3.y(), c[0][2][1], 1e-6); - assert_almost_eq!(p4.x(), c[1][0][0], 1e-6); - assert_almost_eq!(p4.y(), c[1][0][1], 1e-6); - assert_almost_eq!(p5.x(), c[1][1][0], 1e-6); - assert_almost_eq!(p5.y(), c[1][1][1], 1e-6); - assert_almost_eq!(p6.x(), c[1][2][0], 1e-6); - assert_almost_eq!(p6.y(), c[1][2][1], 1e-6); + let geojson_polygon = ValueBase::<(f64, f64)>::from(&geo_polygon); + + if let ValueBase::Polygon(c) = geojson_polygon { + assert_almost_eq!(p1.x(), c[0][0].0, 1e-6); + assert_almost_eq!(p1.y(), c[0][0].1, 1e-6); + assert_almost_eq!(p2.x(), c[0][1].0, 1e-6); + assert_almost_eq!(p2.y(), c[0][1].1, 1e-6); + assert_almost_eq!(p3.x(), c[0][2].0, 1e-6); + assert_almost_eq!(p3.y(), c[0][2].1, 1e-6); + assert_almost_eq!(p4.x(), c[1][0].0, 1e-6); + assert_almost_eq!(p4.y(), c[1][0].1, 1e-6); + assert_almost_eq!(p5.x(), c[1][1].0, 1e-6); + assert_almost_eq!(p5.y(), c[1][1].1, 1e-6); + assert_almost_eq!(p6.x(), c[1][2].0, 1e-6); + assert_almost_eq!(p6.y(), c[1][2].1, 1e-6); } else { panic!("Not valid geometry {:?}", geojson_polygon); } @@ -327,21 +327,21 @@ mod tests { let geo_polygon1 = Polygon::new(geo_line_string1, vec![]); let geo_polygon2 = Polygon::new(geo_line_string2, vec![]); let geo_multi_polygon = MultiPolygon(vec![geo_polygon1, geo_polygon2]); - let geojson_multi_polygon = Value::from(&geo_multi_polygon); - - if let Value::MultiPolygon(c) = geojson_multi_polygon { - assert_almost_eq!(p1.x(), c[0][0][0][0], 1e-6); - assert_almost_eq!(p1.y(), c[0][0][0][1], 1e-6); - assert_almost_eq!(p2.x(), c[0][0][1][0], 1e-6); - assert_almost_eq!(p2.y(), c[0][0][1][1], 1e-6); - assert_almost_eq!(p3.x(), c[0][0][2][0], 1e-6); - assert_almost_eq!(p3.y(), c[0][0][2][1], 1e-6); - assert_almost_eq!(p4.x(), c[1][0][0][0], 1e-6); - assert_almost_eq!(p4.y(), c[1][0][0][1], 1e-6); - assert_almost_eq!(p5.x(), c[1][0][1][0], 1e-6); - assert_almost_eq!(p5.y(), c[1][0][1][1], 1e-6); - assert_almost_eq!(p6.x(), c[1][0][2][0], 1e-6); - assert_almost_eq!(p6.y(), c[1][0][2][1], 1e-6); + let geojson_multi_polygon = ValueBase::<(f64, f64)>::from(&geo_multi_polygon); + + if let ValueBase::MultiPolygon(c) = geojson_multi_polygon { + assert_almost_eq!(p1.x(), c[0][0][0].0, 1e-6); + assert_almost_eq!(p1.y(), c[0][0][0].1, 1e-6); + assert_almost_eq!(p2.x(), c[0][0][1].0, 1e-6); + assert_almost_eq!(p2.y(), c[0][0][1].1, 1e-6); + assert_almost_eq!(p3.x(), c[0][0][2].0, 1e-6); + assert_almost_eq!(p3.y(), c[0][0][2].1, 1e-6); + assert_almost_eq!(p4.x(), c[1][0][0].0, 1e-6); + assert_almost_eq!(p4.y(), c[1][0][0].1, 1e-6); + assert_almost_eq!(p5.x(), c[1][0][1].0, 1e-6); + assert_almost_eq!(p5.y(), c[1][0][1].1, 1e-6); + assert_almost_eq!(p6.x(), c[1][0][2].0, 1e-6); + assert_almost_eq!(p6.y(), c[1][0][2].1, 1e-6); } else { panic!("Not valid geometry {:?}", geojson_multi_polygon); } @@ -369,17 +369,17 @@ mod tests { geo_types::Geometry::MultiPolygon(geo_multi_polygon), ]); - let geojson_geometry_collection = Value::from(&geo_geometry_collection); - - if let Value::GeometryCollection(geometries) = geojson_geometry_collection { - let geometry_type = |geometry: &Geometry| match geometry.value { - Value::Point(..) => "Point", - Value::MultiPoint(..) => "MultiPoint", - Value::LineString(..) => "LineString", - Value::MultiLineString(..) => "MultiLineString", - Value::Polygon(..) => "Polygon", - Value::MultiPolygon(..) => "MultiPolygon", - Value::GeometryCollection(..) => "GeometryCollection", + let geojson_geometry_collection = ValueBase::<(f64, f64)>::from(&geo_geometry_collection); + + if let ValueBase::GeometryCollection(geometries) = geojson_geometry_collection { + let geometry_type = |geometry: &GeometryBase<(f64, f64)>| match geometry.value { + ValueBase::Point(..) => "Point", + ValueBase::MultiPoint(..) => "MultiPoint", + ValueBase::LineString(..) => "LineString", + ValueBase::MultiLineString(..) => "MultiLineString", + ValueBase::Polygon(..) => "Polygon", + ValueBase::MultiPolygon(..) => "MultiPolygon", + ValueBase::GeometryCollection(..) => "GeometryCollection", }; assert_eq!(3, geometries.len()); diff --git a/src/conversion/mod.rs b/src/conversion/mod.rs index 24fb2993..291039e9 100644 --- a/src/conversion/mod.rs +++ b/src/conversion/mod.rs @@ -18,12 +18,12 @@ use crate::geo_types::{ MultiLineString as GtMultiLineString, MultiPoint as GtMultiPoint, MultiPolygon as GtMultiPolygon, Point as GtPoint, Polygon as GtPolygon, }; -use crate::geojson::GeoJson; -use crate::geojson::GeoJsonBase::{Feature, FeatureCollection, Geometry}; +use crate::Position; +use crate::geojson::GeoJsonBase::{self, Feature, FeatureCollection, Geometry}; -use crate::geometry::Geometry as GjGeometry; +use crate::geometry::GeometryBase as GjGeometry; use crate::Error as GJError; -use crate::Value; +use crate::ValueBase; use num_traits::Float; use std::convert::TryInto; @@ -74,7 +74,7 @@ pub(crate) mod from_geo_types; pub(crate) mod to_geo_types; // Process top-level `GeoJSON` items, returning a geo_types::GeometryCollection or an Error -fn process_geojson(gj: &GeoJson) -> Result, GJError> +fn process_geojson(gj: &GeoJsonBase

) -> Result, GJError> where T: Float, { @@ -100,26 +100,26 @@ where } // Process GeoJson Geometry objects, returning their geo_types equivalents, or an error -fn process_geometry(geometry: &GjGeometry) -> Result, GJError> +fn process_geometry(geometry: &GjGeometry

) -> Result, GJError> where T: Float, { match &geometry.value { - Value::Point(_) => Ok(TryInto::>::try_into(geometry.value.clone())?.into()), - Value::MultiPoint(_) => { + ValueBase::Point(_) => Ok(TryInto::>::try_into(geometry.value.clone())?.into()), + ValueBase::MultiPoint(_) => { Ok(TryInto::>::try_into(geometry.value.clone())?.into()) } - Value::LineString(_) => { + ValueBase::LineString(_) => { Ok(TryInto::>::try_into(geometry.value.clone())?.into()) } - Value::MultiLineString(_) => { + ValueBase::MultiLineString(_) => { Ok(TryInto::>::try_into(geometry.value.clone())?.into()) } - Value::Polygon(_) => Ok(TryInto::>::try_into(geometry.value.clone())?.into()), - Value::MultiPolygon(_) => { + ValueBase::Polygon(_) => Ok(TryInto::>::try_into(geometry.value.clone())?.into()), + ValueBase::MultiPolygon(_) => { Ok(TryInto::>::try_into(geometry.value.clone())?.into()) } - Value::GeometryCollection(gc) => { + ValueBase::GeometryCollection(gc) => { let gc = GtGeometry::GeometryCollection(GeometryCollection( gc.iter() .map(|geom| process_geometry(&geom)) @@ -164,7 +164,7 @@ where /// let mut collection: GeometryCollection = quick_collection(&geojson).unwrap(); /// ``` #[cfg_attr(docsrs, doc(cfg(feature = "geo-types")))] -pub fn quick_collection(gj: &GeoJson) -> Result, GJError> +pub fn quick_collection(gj: &GeoJsonBase

) -> Result, GJError> where T: Float, { diff --git a/src/conversion/to_geo_types.rs b/src/conversion/to_geo_types.rs index 8902fb3c..79cd3985 100644 --- a/src/conversion/to_geo_types.rs +++ b/src/conversion/to_geo_types.rs @@ -255,7 +255,7 @@ where #[cfg(test)] mod tests { - use crate::{Geometry, Value}; + use crate::{GeometryBase, ValueBase}; use geo_types; use std::convert::TryInto; @@ -263,7 +263,7 @@ mod tests { #[test] fn geojson_point_conversion_test() { let coords = vec![100.0, 0.2]; - let geojson_point = Value::Point(coords.clone()); + let geojson_point = ValueBase::Point(coords.clone()); let geo_point: geo_types::Point = geojson_point.try_into().unwrap(); assert_almost_eq!(geo_point.x(), coords[0], 1e-6); @@ -274,7 +274,7 @@ mod tests { fn geojson_multi_point_conversion_test() { let coord1 = vec![100.0, 0.2]; let coord2 = vec![101.0, 1.0]; - let geojson_multi_point = Value::MultiPoint(vec![coord1.clone(), coord2.clone()]); + let geojson_multi_point = ValueBase::MultiPoint(vec![coord1.clone(), coord2.clone()]); let geo_multi_point: geo_types::MultiPoint = geojson_multi_point.try_into().unwrap(); assert_almost_eq!(geo_multi_point.0[0].x(), coord1[0], 1e-6); @@ -287,7 +287,7 @@ mod tests { fn geojson_line_string_conversion_test() { let coord1 = vec![100.0, 0.2]; let coord2 = vec![101.0, 1.0]; - let geojson_line_string = Value::LineString(vec![coord1.clone(), coord2.clone()]); + let geojson_line_string = ValueBase::LineString(vec![coord1.clone(), coord2.clone()]); let geo_line_string: geo_types::LineString = geojson_line_string.try_into().unwrap(); assert_almost_eq!(geo_line_string.0[0].x, coord1[0], 1e-6); @@ -301,7 +301,7 @@ mod tests { let coord1 = vec![100.0, 0.2]; let coord2 = vec![101.0, 1.0]; let coord3 = vec![102.0, 0.8]; - let geojson_multi_line_string = Value::MultiLineString(vec![ + let geojson_multi_line_string = ValueBase::MultiLineString(vec![ vec![coord1.clone(), coord2.clone()], vec![coord2.clone(), coord3.clone()], ]); @@ -344,7 +344,7 @@ mod tests { coord4.clone(), ], ]; - let geojson_polygon = Value::Polygon(geojson_multi_line_string_type1); + let geojson_polygon = ValueBase::Polygon(geojson_multi_line_string_type1); let geo_polygon: geo_types::Polygon = geojson_polygon.try_into().unwrap(); let ref geo_line_string1 = geo_polygon.exterior(); @@ -370,7 +370,7 @@ mod tests { #[test] fn geojson_empty_polygon_conversion_test() { - let geojson_polygon = Value::Polygon(vec![]); + let geojson_polygon = ValueBase::<(f64, f64)>::Polygon(vec![]); let geo_polygon: geo_types::Polygon = geojson_polygon.try_into().unwrap(); assert!(geo_polygon.exterior().0.is_empty()); @@ -388,7 +388,7 @@ mod tests { coord3.clone(), coord1.clone(), ]]; - let geojson_polygon = Value::Polygon(geojson_multi_line_string_type1); + let geojson_polygon = ValueBase::Polygon(geojson_multi_line_string_type1); let geo_polygon: geo_types::Polygon = geojson_polygon.try_into().unwrap(); let ref geo_line_string1 = geo_polygon.exterior(); @@ -426,7 +426,7 @@ mod tests { coord6.clone(), coord4.clone(), ]; - let geojson_multi_polygon = Value::MultiPolygon(vec![ + let geojson_multi_polygon = ValueBase::MultiPolygon(vec![ vec![geojson_line_string_type1], vec![geojson_line_string_type2], ]); @@ -462,12 +462,12 @@ mod tests { let coord4 = vec![102.0, 0.0]; let coord5 = vec![101.0, 0.0]; - let geojson_multi_point = Value::MultiPoint(vec![coord1.clone(), coord2.clone()]); - let geojson_multi_line_string = Value::MultiLineString(vec![ + let geojson_multi_point = ValueBase::MultiPoint(vec![coord1.clone(), coord2.clone()]); + let geojson_multi_line_string = ValueBase::MultiLineString(vec![ vec![coord1.clone(), coord2.clone()], vec![coord2.clone(), coord3.clone()], ]); - let geojson_multi_polygon = Value::MultiPolygon(vec![ + let geojson_multi_polygon = ValueBase::MultiPolygon(vec![ vec![vec![ coord3.clone(), coord4.clone(), @@ -482,10 +482,10 @@ mod tests { ]], ]); - let geojson_geometry_collection = Value::GeometryCollection(vec![ - Geometry::new(geojson_multi_point), - Geometry::new(geojson_multi_line_string), - Geometry::new(geojson_multi_polygon), + let geojson_geometry_collection = ValueBase::GeometryCollection(vec![ + GeometryBase::new(geojson_multi_point), + GeometryBase::new(geojson_multi_line_string), + GeometryBase::new(geojson_multi_polygon), ]); let geo_geometry_collection: geo_types::GeometryCollection = diff --git a/src/feature.rs b/src/feature.rs index 6e25a531..06ccd97c 100644 --- a/src/feature.rs +++ b/src/feature.rs @@ -136,7 +136,7 @@ impl Serialize for Id { #[cfg(test)] mod tests { - use crate::{feature, Error, Feature, GeoJson, Geometry, Value}; + use crate::{feature, Error, FeatureBase, GeoJsonBase, GeometryBase, ValueBase}; fn feature_json_str() -> &'static str { "{\"geometry\":{\"coordinates\":[1.1,2.1],\"type\":\"Point\"},\"properties\":{},\"type\":\ @@ -147,10 +147,10 @@ mod tests { Some(crate::json::JsonObject::new()) } - fn feature() -> Feature { - crate::Feature { - geometry: Some(Geometry { - value: Value::Point(vec![1.1, 2.1]), + fn feature() -> FeatureBase<(f64, f64)> { + FeatureBase { + geometry: Some(GeometryBase { + value: ValueBase::Point((1.1f64, 2.1f64)), bbox: None, foreign_members: None, }), @@ -161,11 +161,11 @@ mod tests { } } - fn encode(feature: &Feature) -> String { + fn encode(feature: &FeatureBase<(f64, f64)>) -> String { serde_json::to_string(&feature).unwrap() } - fn decode(json_string: String) -> GeoJson { + fn decode(json_string: String) -> GeoJsonBase<(f64, f64)> { json_string.parse().unwrap() } @@ -179,7 +179,7 @@ mod tests { // Test decoding let decoded_feature = match decode(json_string) { - GeoJson::Feature(f) => f, + GeoJsonBase::Feature(f) => f, _ => unreachable!(), }; assert_eq!(decoded_feature, feature); @@ -200,12 +200,12 @@ mod tests { }); assert!(json_value.is_object()); - let feature: Feature = json_value.try_into().unwrap(); + let feature: FeatureBase<(f64, f64)> = json_value.try_into().unwrap(); assert_eq!( feature, - Feature { + FeatureBase { bbox: None, - geometry: Some(Geometry::new(Value::Point(vec![102.0, 0.5]))), + geometry: Some(GeometryBase::new(ValueBase::Point((102.0, 0.5)))), id: None, properties: None, foreign_members: None, @@ -227,9 +227,9 @@ mod tests { "properties":{}, "type":"Feature" }"#; - let geojson = geojson_str.parse::().unwrap(); + let geojson = geojson_str.parse::>().unwrap(); let feature = match geojson { - GeoJson::Feature(feature) => feature, + GeoJsonBase::Feature(feature) => feature, _ => unimplemented!(), }; assert!(feature.geometry.is_none()); @@ -238,7 +238,7 @@ mod tests { #[test] fn feature_json_invalid_geometry() { let geojson_str = r#"{"geometry":3.14,"properties":{},"type":"Feature"}"#; - match geojson_str.parse::().unwrap_err() { + match geojson_str.parse::>().unwrap_err() { Error::FeatureInvalidGeometryValue => (), _ => unreachable!(), } @@ -247,9 +247,9 @@ mod tests { #[test] fn encode_decode_feature_with_id_number() { let feature_json_str = "{\"geometry\":{\"coordinates\":[1.1,2.1],\"type\":\"Point\"},\"id\":0,\"properties\":{},\"type\":\"Feature\"}"; - let feature = crate::Feature { - geometry: Some(Geometry { - value: Value::Point(vec![1.1, 2.1]), + let feature = FeatureBase { + geometry: Some(GeometryBase { + value: ValueBase::Point((1.1, 2.1)), bbox: None, foreign_members: None, }), @@ -264,7 +264,7 @@ mod tests { // Test decode let decoded_feature = match decode(feature_json_str.into()) { - GeoJson::Feature(f) => f, + GeoJsonBase::Feature(f) => f, _ => unreachable!(), }; assert_eq!(decoded_feature, feature); @@ -273,9 +273,9 @@ mod tests { #[test] fn encode_decode_feature_with_id_string() { let feature_json_str = "{\"geometry\":{\"coordinates\":[1.1,2.1],\"type\":\"Point\"},\"id\":\"foo\",\"properties\":{},\"type\":\"Feature\"}"; - let feature = crate::Feature { - geometry: Some(Geometry { - value: Value::Point(vec![1.1, 2.1]), + let feature = FeatureBase { + geometry: Some(GeometryBase { + value: ValueBase::Point((1.1, 2.1)), bbox: None, foreign_members: None, }), @@ -290,7 +290,7 @@ mod tests { // Test decode let decoded_feature = match decode(feature_json_str.into()) { - GeoJson::Feature(f) => f, + GeoJsonBase::Feature(f) => f, _ => unreachable!(), }; assert_eq!(decoded_feature, feature); @@ -300,7 +300,7 @@ mod tests { fn decode_feature_with_invalid_id_type_object() { let feature_json_str = "{\"geometry\":{\"coordinates\":[1.1,2.1],\"type\":\"Point\"},\"id\":{},\"properties\":{},\"type\":\"Feature\"}"; assert_eq!( - feature_json_str.parse::(), + feature_json_str.parse::>(), Err(Error::FeatureInvalidIdentifierType), ) } @@ -309,7 +309,7 @@ mod tests { fn decode_feature_with_invalid_id_type_null() { let feature_json_str = "{\"geometry\":{\"coordinates\":[1.1,2.1],\"type\":\"Point\"},\"id\":null,\"properties\":{},\"type\":\"Feature\"}"; assert_eq!( - feature_json_str.parse::(), + feature_json_str.parse::>(), Err(Error::FeatureInvalidIdentifierType), ) } @@ -324,9 +324,9 @@ mod tests { String::from("other_member"), serde_json::to_value("some_value").unwrap(), ); - let feature = crate::Feature { - geometry: Some(Geometry { - value: Value::Point(vec![1.1, 2.1]), + let feature = FeatureBase { + geometry: Some(GeometryBase { + value: ValueBase::Point((1.1, 2.1)), bbox: None, foreign_members: None, }), @@ -341,7 +341,7 @@ mod tests { // Test decode let decoded_feature = match decode(feature_json_str.into()) { - GeoJson::Feature(f) => f, + GeoJsonBase::Feature(f) => f, _ => unreachable!(), }; assert_eq!(decoded_feature, feature); diff --git a/src/feature_collection.rs b/src/feature_collection.rs index f8a3ab1c..95db654b 100644 --- a/src/feature_collection.rs +++ b/src/feature_collection.rs @@ -59,8 +59,6 @@ pub struct FeatureCollectionBase { pub foreign_members: Option, } -pub type FeatureCollection = FeatureCollectionBase>; - impl<'a, P: Position> From<&'a FeatureCollectionBase

> for JsonObject { fn from(fc: &'a FeatureCollectionBase

) -> JsonObject { let mut map = JsonObject::new(); diff --git a/src/geojson.rs b/src/geojson.rs index ed2b3fd9..cf622e38 100644 --- a/src/geojson.rs +++ b/src/geojson.rs @@ -15,7 +15,7 @@ use crate::json::{self, Deserialize, Deserializer, JsonObject, JsonValue, Serialize, Serializer}; use crate::serde; use crate::{ - Error, Feature, FeatureBase, FeatureCollection, FeatureCollectionBase, Geometry, GeometryBase, + Error, FeatureBase, FeatureCollectionBase, GeometryBase, Position, }; use std::convert::TryFrom; @@ -32,8 +32,6 @@ pub enum GeoJsonBase { FeatureCollection(FeatureCollectionBase), } -pub type GeoJson = GeoJsonBase>; - impl<'a, P: Position> From<&'a GeoJsonBase

> for JsonObject { fn from(geojson: &'a GeoJsonBase

) -> JsonObject { match *geojson { @@ -79,7 +77,7 @@ impl GeoJsonBase

{ } } -impl GeoJson { +impl GeoJsonBase

{ /// Converts a JSON Value into a GeoJson object. /// /// # Example @@ -105,7 +103,7 @@ impl GeoJson { /// geojson, /// GeoJson::Feature(Feature { /// bbox: None, - /// geometry: Some(Geometry::new(Value::Point(vec![102.0, 0.5]))), + /// geometry: Some(Geometry::new(ValueBase::Point(vec![102.0, 0.5]))), /// id: None, /// properties: None, /// foreign_members: None, @@ -117,7 +115,7 @@ impl GeoJson { } } -impl TryFrom for GeoJson { +impl TryFrom for GeoJsonBase

{ type Error = Error; fn try_from(object: JsonObject) -> Result { @@ -127,16 +125,16 @@ impl TryFrom for GeoJson { }; let type_ = type_.ok_or(Error::GeoJsonUnknownType)?; match type_ { - Type::Feature => Feature::try_from(object).map(GeoJson::Feature), + Type::Feature => FeatureBase::try_from(object).map(GeoJsonBase::Feature), Type::FeatureCollection => { - FeatureCollection::try_from(object).map(GeoJson::FeatureCollection) + FeatureCollectionBase::try_from(object).map(GeoJsonBase::FeatureCollection) } - _ => Geometry::try_from(object).map(GeoJson::Geometry), + _ => GeometryBase::try_from(object).map(GeoJsonBase::Geometry), } } } -impl TryFrom for GeoJson { +impl TryFrom for GeoJsonBase

{ type Error = Error; fn try_from(value: JsonValue) -> Result { @@ -178,7 +176,7 @@ impl Type { } } -impl Serialize for GeoJson { +impl Serialize for GeoJsonBase

{ fn serialize(&self, serializer: S) -> Result where S: Serializer, @@ -225,7 +223,7 @@ fn json_value_into_json_object(json_value: json::JsonValue) -> Option fmt::Display for GeoJsonBase

{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ::serde_json::to_string(self) .map_err(|_| fmt::Error) @@ -233,7 +231,7 @@ impl fmt::Display for GeoJson { } } -impl fmt::Display for Feature { +impl fmt::Display for FeatureBase

{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ::serde_json::to_string(self) .map_err(|_| fmt::Error) @@ -241,7 +239,7 @@ impl fmt::Display for Feature { } } -impl fmt::Display for Geometry { +impl fmt::Display for GeometryBase

{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ::serde_json::to_string(self) .map_err(|_| fmt::Error) @@ -249,7 +247,7 @@ impl fmt::Display for Geometry { } } -impl fmt::Display for FeatureCollection { +impl fmt::Display for FeatureCollectionBase

{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ::serde_json::to_string(self) .map_err(|_| fmt::Error) @@ -259,7 +257,7 @@ impl fmt::Display for FeatureCollection { #[cfg(test)] mod tests { - use crate::{Feature, GeoJson, Geometry, Value}; + use crate::{FeatureBase, GeoJsonBase, GeometryBase, ValueBase}; use serde_json::json; use std::convert::TryInto; @@ -276,13 +274,13 @@ mod tests { assert!(json_value.is_object()); - let geojson: GeoJson = json_value.try_into().unwrap(); + let geojson: GeoJsonBase<(f64, f64)> = json_value.try_into().unwrap(); assert_eq!( geojson, - GeoJson::Feature(Feature { + GeoJsonBase::Feature(FeatureBase { bbox: None, - geometry: Some(Geometry::new(Value::Point(vec![102.0, 0.5]))), + geometry: Some(GeometryBase::new(ValueBase::Point((102.0, 0.5)))), id: None, properties: None, foreign_members: None, diff --git a/src/geometry.rs b/src/geometry.rs index 59998f56..a60591a3 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -30,8 +30,8 @@ use crate::{util, Bbox, Error, Position}; /// # fn test() { /// let point = geo_types::Point::new(2., 9.); /// assert_eq!( -/// geojson::Value::from(&point), -/// geojson::Value::Point(vec![2., 9.]), +/// geojson::ValueBase::from(&point), +/// geojson::ValueBase::Point(vec![2., 9.]), /// ); /// # } /// # #[cfg(not(feature = "geo-types"))] @@ -76,8 +76,6 @@ pub enum ValueBase { GeometryCollection(Vec>), } -pub type Value = ValueBase>; - impl<'a, P: Position> From<&'a ValueBase

> for JsonValue { fn from(value: &'a ValueBase

) -> JsonValue { match *value { @@ -114,7 +112,7 @@ impl Serialize for ValueBase

{ /// use geojson::{Geometry, Value}; /// /// let geometry = Geometry::new( -/// Value::Point(vec![7.428959, 1.513394]), +/// ValueBase::Point(vec![7.428959, 1.513394]), /// ); /// ``` /// @@ -125,7 +123,7 @@ impl Serialize for ValueBase

{ /// use serde_json; /// /// let geometry = Geometry::new( -/// Value::Point(vec![7.428959, 1.513394]), +/// ValueBase::Point(vec![7.428959, 1.513394]), /// ); /// /// let geojson_string = geometry.to_string(); @@ -150,7 +148,7 @@ impl Serialize for ValueBase

{ /// /// assert_eq!( /// Geometry::new( -/// Value::Point(vec![7.428959, 1.513394]), +/// ValueBase::Point(vec![7.428959, 1.513394]), /// ), /// geometry, /// ); @@ -168,8 +166,6 @@ pub struct GeometryBase { pub foreign_members: Option, } -pub type Geometry = GeometryBase>; - impl GeometryBase

{ /// Returns a new `Geometry` with the specified `value`. `bbox` and `foreign_members` will be /// set to `None`. @@ -291,20 +287,20 @@ impl<'de, Pos: Position> Deserialize<'de> for GeometryBase { mod tests { use crate::json::JsonObject; - use crate::{GeoJson, Geometry, Value}; + use crate::{GeoJsonBase, GeometryBase, ValueBase, Position}; - fn encode(geometry: &Geometry) -> String { + fn encode(geometry: &GeometryBase

) -> String { serde_json::to_string(&geometry).unwrap() } - fn decode(json_string: String) -> GeoJson { + fn decode(json_string: String) -> GeoJsonBase

{ json_string.parse().unwrap() } #[test] fn encode_decode_geometry() { let geometry_json_str = "{\"coordinates\":[1.1,2.1],\"type\":\"Point\"}"; - let geometry = Geometry { - value: Value::Point(vec![1.1, 2.1]), + let geometry = GeometryBase { + value: ValueBase::Point((1.1f64, 2.1)), bbox: None, foreign_members: None, }; @@ -315,7 +311,7 @@ mod tests { // Test decode let decoded_geometry = match decode(json_string) { - GeoJson::Geometry(g) => g, + GeoJsonBase::Geometry(g) => g, _ => unreachable!(), }; assert_eq!(decoded_geometry, geometry); @@ -334,11 +330,11 @@ mod tests { }); assert!(json_value.is_object()); - let geometry: Geometry = json_value.try_into().unwrap(); + let geometry: GeometryBase<(f64, f64)> = json_value.try_into().unwrap(); assert_eq!( geometry, - Geometry { - value: Value::Point(vec![0.0, 0.1]), + GeometryBase { + value: ValueBase::Point((0.0f64, 0.1f64)), bbox: None, foreign_members: None, } @@ -347,8 +343,8 @@ mod tests { #[test] fn test_geometry_display() { - let v = Value::LineString(vec![vec![0.0, 0.1], vec![0.1, 0.2], vec![0.2, 0.3]]); - let geometry = Geometry::new(v); + let v = ValueBase::LineString(vec![vec![0.0, 0.1], vec![0.1, 0.2], vec![0.2, 0.3]]); + let geometry = GeometryBase::new(v); assert_eq!( "{\"coordinates\":[[0.0,0.1],[0.1,0.2],[0.2,0.3]],\"type\":\"LineString\"}", geometry.to_string() @@ -364,8 +360,8 @@ mod tests { String::from("other_member"), serde_json::to_value(true).unwrap(), ); - let geometry = Geometry { - value: Value::Point(vec![1.1, 2.1]), + let geometry = GeometryBase { + value: ValueBase::Point(vec![1.1, 2.1]), bbox: None, foreign_members: Some(foreign_members), }; @@ -376,7 +372,7 @@ mod tests { // Test decode let decoded_geometry = match decode(geometry_json_str.into()) { - GeoJson::Geometry(g) => g, + GeoJsonBase::Geometry(g) => g, _ => unreachable!(), }; assert_eq!(decoded_geometry, geometry); @@ -384,17 +380,17 @@ mod tests { #[test] fn encode_decode_geometry_collection() { - let geometry_collection = Geometry { + let geometry_collection = GeometryBase { bbox: None, - value: Value::GeometryCollection(vec![ - Geometry { + value: ValueBase::GeometryCollection(vec![ + GeometryBase { bbox: None, - value: Value::Point(vec![100.0, 0.0]), + value: ValueBase::Point(vec![100.0, 0.0]), foreign_members: None, }, - Geometry { + GeometryBase { bbox: None, - value: Value::LineString(vec![vec![101.0, 0.0], vec![102.0, 1.0]]), + value: ValueBase::LineString(vec![vec![101.0, 0.0], vec![102.0, 1.0]]), foreign_members: None, }, ]), @@ -408,7 +404,7 @@ mod tests { // Test decode let decoded_geometry = match decode(geometry_collection_string.into()) { - GeoJson::Geometry(g) => g, + GeoJsonBase::Geometry(g) => g, _ => unreachable!(), }; assert_eq!(decoded_geometry, geometry_collection); diff --git a/src/lib.rs b/src/lib.rs index f6ad31fc..7093a6ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -106,7 +106,7 @@ //! # let properties = properties(); //! //! let geometry = Geometry::new( -//! Value::Point(vec![-120.66029,35.2812]) +//! ValueBase::Point(vec![-120.66029,35.2812]) //! ); //! //! let geojson = GeoJson::Feature(Feature { @@ -155,9 +155,9 @@ //! /// Process GeoJSON geometries //! fn match_geometry(geom: &Geometry) { //! match geom.value { -//! Value::Polygon(_) => println!("Matched a Polygon"), -//! Value::MultiPolygon(_) => println!("Matched a MultiPolygon"), -//! Value::GeometryCollection(ref gc) => { +//! ValueBase::Polygon(_) => println!("Matched a Polygon"), +//! ValueBase::MultiPolygon(_) => println!("Matched a MultiPolygon"), +//! ValueBase::GeometryCollection(ref gc) => { //! println!("Matched a GeometryCollection"); //! // GeometryCollections contain other Geometry types, and can nest //! // we deal with this by recursively processing each geometry @@ -229,7 +229,7 @@ //! //! ``` //! # #[cfg(feature = "geo-types")] -//! use geojson::{GeoJson, quick_collection}; +//! use geojson::{GeoJsonBase, quick_collection}; //! # #[cfg(feature = "geo-types")] //! use geo_types::GeometryCollection; //! # #[cfg(feature = "geo-types")] @@ -283,15 +283,15 @@ mod position; pub use position::Position; mod geojson; -pub use crate::geojson::{GeoJson, GeoJsonBase}; +pub use crate::geojson::GeoJsonBase; mod geometry; -pub use crate::geometry::{Geometry, GeometryBase, Value, ValueBase}; +pub use crate::geometry::{GeometryBase, ValueBase}; pub mod feature; mod feature_collection; -pub use crate::feature_collection::{FeatureCollection, FeatureCollectionBase}; +pub use crate::feature_collection::FeatureCollectionBase; #[cfg(feature = "geo-types")] mod conversion; @@ -326,8 +326,6 @@ pub struct FeatureBase { pub foreign_members: Option, } -pub type Feature = FeatureBase>; - /// Error when reading a GeoJSON object from a str or Object #[derive(Debug, PartialEq, Eq)] pub enum Error { diff --git a/src/position.rs b/src/position.rs index 30cc6ac5..499aa9f6 100644 --- a/src/position.rs +++ b/src/position.rs @@ -1,10 +1,11 @@ use crate::json::JsonValue; use crate::{util, Error}; +use std::fmt::Debug; /// Positions /// /// [GeoJSON Format Specification ยง 3.1.1](https://tools.ietf.org/html/rfc7946#section-3.1.1) -pub trait Position: Sized + serde::Serialize { +pub trait Position: Sized + Clone + Debug + serde::Serialize { fn from_json_value(json: &JsonValue) -> Result; fn from_x_y(x: f64, y: f64) -> Self; fn x(&self) -> f64; diff --git a/src/util.rs b/src/util.rs index fa261f96..9a77531e 100644 --- a/src/util.rs +++ b/src/util.rs @@ -104,7 +104,7 @@ pub fn get_properties(object: &mut JsonObject) -> Result, Err /// Retrieve a single Position from the value of the "coordinates" key /// -/// Used by Value::Point +/// Used by ValueBase::Point pub fn get_coords_one_pos(object: &mut JsonObject) -> Result { let coords_json = get_coords_value(object)?; Position::from_json_value(&coords_json) diff --git a/tests/roundtrip.rs b/tests/roundtrip.rs index 32c9f1f0..184e9560 100644 --- a/tests/roundtrip.rs +++ b/tests/roundtrip.rs @@ -1,6 +1,6 @@ #[cfg(test)] mod roundtrip_tests { - use geojson::GeoJson; + use geojson::GeoJsonBase; use serde_json; use std::fs::File; use std::io::prelude::*; @@ -53,7 +53,7 @@ mod roundtrip_tests { let _ = file.read_to_string(&mut file_contents); // Read and parse the geojson from the file's contents - let geojson = file_contents.parse::().expect("unable to parse"); + let geojson = file_contents.parse::>().expect("unable to parse"); // Now that we've successfully decoded the geojson, re-encode it and compare to the // original to make sure nothing was lost.