From 7219e42560078e8f1284214081c3a8310d4ec0c6 Mon Sep 17 00:00:00 2001 From: Patrick Hayes Date: Tue, 28 Feb 2023 09:29:34 -0800 Subject: [PATCH] Moving Position to use array_vec --- Cargo.toml | 1 + src/conversion/from_geo_types.rs | 3 +- src/conversion/to_geo_types.rs | 71 ++++++++++++++++---------------- src/feature.rs | 9 ++-- src/feature_collection.rs | 5 ++- src/feature_iterator.rs | 21 +++++----- src/feature_writer.rs | 9 ++-- src/geojson.rs | 5 ++- src/geometry.rs | 15 +++---- src/lib.rs | 3 +- src/ser.rs | 5 ++- src/util.rs | 5 ++- 12 files changed, 83 insertions(+), 69 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4e58392..42468bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ serde_json = "~1.0" geo-types = { version = "0.7", features = ["serde"], optional = true } thiserror = "1.0.20" log = "0.4.17" +tinyvec = { version = "1", features=["rustc_1_57", "serde"] } [dev-dependencies] num-traits = "0.2" diff --git a/src/conversion/from_geo_types.rs b/src/conversion/from_geo_types.rs index ec05d87..36d2577 100644 --- a/src/conversion/from_geo_types.rs +++ b/src/conversion/from_geo_types.rs @@ -1,4 +1,5 @@ use geo_types::{self, CoordFloat}; +use tinyvec::array_vec; use crate::{geometry, Feature, FeatureCollection}; @@ -186,7 +187,7 @@ where let x: f64 = point.x().to_f64().unwrap(); let y: f64 = point.y().to_f64().unwrap(); - vec![x, y] + array_vec![x, y] } fn create_line_string_type(line_string: &geo_types::LineString) -> LineStringType diff --git a/src/conversion/to_geo_types.rs b/src/conversion/to_geo_types.rs index 996a730..bc34c47 100644 --- a/src/conversion/to_geo_types.rs +++ b/src/conversion/to_geo_types.rs @@ -363,12 +363,13 @@ fn mismatch_geom_err(expected_type: &'static str, found: &geometry::Value) -> Er mod tests { use crate::{Geometry, Value}; use serde_json::json; + use tinyvec::array_vec; use std::convert::TryInto; #[test] fn geojson_point_conversion_test() { - let coords = vec![100.0, 0.2]; + let coords = array_vec![100.0, 0.2]; let geojson_point = Value::Point(coords.clone()); let geo_point: geo_types::Point = geojson_point.try_into().unwrap(); @@ -378,8 +379,8 @@ mod tests { #[test] fn geojson_multi_point_conversion_test() { - let coord1 = vec![100.0, 0.2]; - let coord2 = vec![101.0, 1.0]; + let coord1 = array_vec![100.0, 0.2]; + let coord2 = array_vec![101.0, 1.0]; let geojson_multi_point = Value::MultiPoint(vec![coord1.clone(), coord2.clone()]); let geo_multi_point: geo_types::MultiPoint = geojson_multi_point.try_into().unwrap(); @@ -391,8 +392,8 @@ mod tests { #[test] fn geojson_line_string_conversion_test() { - let coord1 = vec![100.0, 0.2]; - let coord2 = vec![101.0, 1.0]; + let coord1 = array_vec![100.0, 0.2]; + let coord2 = array_vec![101.0, 1.0]; let geojson_line_string = Value::LineString(vec![coord1.clone(), coord2.clone()]); let geo_line_string: geo_types::LineString = geojson_line_string.try_into().unwrap(); @@ -404,9 +405,9 @@ mod tests { #[test] fn geojson_multi_line_string_conversion_test() { - let coord1 = vec![100.0, 0.2]; - let coord2 = vec![101.0, 1.0]; - let coord3 = vec![102.0, 0.8]; + let coord1 = array_vec![100.0, 0.2]; + let coord2 = array_vec![101.0, 1.0]; + let coord3 = array_vec![102.0, 0.8]; let geojson_multi_line_string = Value::MultiLineString(vec![ vec![coord1.clone(), coord2.clone()], vec![coord2.clone(), coord3.clone()], @@ -429,12 +430,12 @@ mod tests { #[test] fn geojson_polygon_conversion_test() { - let coord1 = vec![100.0, 0.0]; - let coord2 = vec![101.0, 1.0]; - let coord3 = vec![101.0, 1.0]; - let coord4 = vec![104.0, 0.2]; - let coord5 = vec![100.9, 0.2]; - let coord6 = vec![100.9, 0.7]; + let coord1 = array_vec![100.0, 0.0]; + let coord2 = array_vec![101.0, 1.0]; + let coord3 = array_vec![101.0, 1.0]; + let coord4 = array_vec![104.0, 0.2]; + let coord5 = array_vec![100.9, 0.2]; + let coord6 = array_vec![100.9, 0.7]; let geojson_multi_line_string_type1 = vec![ vec![ @@ -484,9 +485,9 @@ mod tests { #[test] fn geojson_polygon_without_interiors_conversion_test() { - let coord1 = vec![100.0, 0.0]; - let coord2 = vec![101.0, 1.0]; - let coord3 = vec![101.0, 1.0]; + let coord1 = array_vec![100.0, 0.0]; + let coord2 = array_vec![101.0, 1.0]; + let coord3 = array_vec![101.0, 1.0]; let geojson_multi_line_string_type1 = vec![vec![ coord1.clone(), @@ -512,12 +513,12 @@ mod tests { #[test] fn geojson_multi_polygon_conversion_test() { - let coord1 = vec![100.0, 0.0]; - let coord2 = vec![101.0, 1.0]; - let coord3 = vec![101.0, 1.0]; - let coord4 = vec![104.0, 0.2]; - let coord5 = vec![100.9, 0.2]; - let coord6 = vec![100.9, 0.7]; + let coord1 = array_vec![100.0, 0.0]; + let coord2 = array_vec![101.0, 1.0]; + let coord3 = array_vec![101.0, 1.0]; + let coord4 = array_vec![104.0, 0.2]; + let coord5 = array_vec![100.9, 0.2]; + let coord6 = array_vec![100.9, 0.7]; let geojson_line_string_type1 = vec![ coord1.clone(), @@ -562,11 +563,11 @@ mod tests { #[test] fn geojson_geometry_collection_conversion_test() { - let coord1 = vec![100.0, 0.0]; - let coord2 = vec![100.0, 1.0]; - let coord3 = vec![101.0, 1.0]; - let coord4 = vec![102.0, 0.0]; - let coord5 = vec![101.0, 0.0]; + let coord1 = array_vec![100.0, 0.0]; + let coord2 = array_vec![100.0, 1.0]; + let coord3 = array_vec![101.0, 1.0]; + let coord4 = array_vec![102.0, 0.0]; + let coord5 = array_vec![101.0, 0.0]; let geojson_multi_point = Value::MultiPoint(vec![coord1.clone(), coord2.clone()]); let geojson_multi_line_string = Value::MultiLineString(vec![ @@ -602,7 +603,7 @@ mod tests { #[test] fn geojson_geometry_conversion() { - let coords = vec![100.0, 0.2]; + let coords = array_vec![100.0, 0.2]; let geojson_geometry = Geometry::from(Value::Point(coords.clone())); let geo_geometry: geo_types::Geometry = geojson_geometry .try_into() @@ -615,8 +616,8 @@ mod tests { #[test] fn geojson_mismatch_geometry_conversion_test() { - let coord1 = vec![100.0, 0.2]; - let coord2 = vec![101.0, 1.0]; + let coord1 = array_vec![100.0, 0.2]; + let coord2 = array_vec![101.0, 1.0]; let geojson_line_string = Value::LineString(vec![coord1.clone(), coord2.clone()]); use std::convert::TryFrom; let error = geo_types::Point::::try_from(geojson_line_string).unwrap_err(); @@ -678,10 +679,10 @@ mod tests { #[test] fn borrowed_value_conversions_test() -> crate::Result<()> { - let coord1 = vec![100.0, 0.2]; - let coord2 = vec![101.0, 1.0]; - let coord3 = vec![102.0, 0.8]; - let coord4 = vec![104.0, 0.2]; + let coord1 = array_vec![100.0, 0.2]; + let coord2 = array_vec![101.0, 1.0]; + let coord3 = array_vec![102.0, 0.8]; + let coord4 = array_vec![104.0, 0.2]; let geojson_point = Value::Point(coord1.clone()); let _: geo_types::Point = (&geojson_point).try_into()?; diff --git a/src/feature.rs b/src/feature.rs index 9e82e32..083f5c4 100644 --- a/src/feature.rs +++ b/src/feature.rs @@ -225,6 +225,7 @@ mod tests { use crate::JsonObject; use crate::{feature, Error, Feature, GeoJson, Geometry, Value}; use serde_json::json; + use tinyvec::array_vec; use std::str::FromStr; @@ -252,7 +253,7 @@ mod tests { } fn value() -> Value { - Value::Point(vec![1.1, 2.1]) + Value::Point(array_vec![1.1, 2.1]) } fn geometry() -> Geometry { @@ -347,7 +348,7 @@ mod tests { 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]), + value: Value::Point(array_vec![1.1, 2.1]), bbox: None, foreign_members: None, }), @@ -373,7 +374,7 @@ mod tests { 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]), + value: Value::Point(array_vec![1.1, 2.1]), bbox: None, foreign_members: None, }), @@ -424,7 +425,7 @@ mod tests { ); let feature = crate::Feature { geometry: Some(Geometry { - value: Value::Point(vec![1.1, 2.1]), + value: Value::Point(array_vec![1.1, 2.1]), bbox: None, foreign_members: None, }), diff --git a/src/feature_collection.rs b/src/feature_collection.rs index ba2c83f..7ddd990 100644 --- a/src/feature_collection.rs +++ b/src/feature_collection.rs @@ -255,6 +255,7 @@ impl FromIterator for FeatureCollection { mod tests { use crate::{Error, Feature, FeatureCollection, Value}; use serde_json::json; + use tinyvec::array_vec; use std::str::FromStr; @@ -262,13 +263,13 @@ mod tests { fn test_fc_from_iterator() { let features: Vec = vec![ { - let mut feat: Feature = Value::Point(vec![0., 0., 0.]).into(); + let mut feat: Feature = Value::Point(array_vec![0., 0., 0.]).into(); feat.bbox = Some(vec![-1., -1., -1., 1., 1., 1.]); feat }, { let mut feat: Feature = - Value::MultiPoint(vec![vec![10., 10., 10.], vec![11., 11., 11.]]).into(); + Value::MultiPoint(vec![array_vec![10., 10., 10.], array_vec![11., 11., 11.]]).into(); feat.bbox = Some(vec![10., 10., 10., 11., 11., 11.]); feat }, diff --git a/src/feature_iterator.rs b/src/feature_iterator.rs index 9155067..1730597 100644 --- a/src/feature_iterator.rs +++ b/src/feature_iterator.rs @@ -130,6 +130,7 @@ where mod tests { use super::*; use crate::{Geometry, Value}; + use tinyvec::array_vec; use std::io::BufReader; @@ -187,7 +188,7 @@ mod tests { assert_eq!( Geometry { bbox: None, - value: Value::Point(vec![102.0, 0.5]), + value: Value::Point(array_vec![102.0, 0.5]), foreign_members: None, }, fi.next().unwrap().unwrap().geometry.unwrap() @@ -196,10 +197,10 @@ mod tests { Geometry { bbox: None, value: Value::LineString(vec![ - vec![102.0, 0.0], - vec![103.0, 1.0], - vec![104.0, 0.0], - vec![105.0, 1.0] + array_vec![102.0, 0.0], + array_vec![103.0, 1.0], + array_vec![104.0, 0.0], + array_vec![105.0, 1.0] ]), foreign_members: None, }, @@ -209,11 +210,11 @@ mod tests { Geometry { bbox: None, value: Value::Polygon(vec![vec![ - vec![100.0, 0.0], - vec![101.0, 0.0], - vec![101.0, 1.0], - vec![100.0, 1.0], - vec![100.0, 0.0] + array_vec![100.0, 0.0], + array_vec![101.0, 0.0], + array_vec![101.0, 1.0], + array_vec![100.0, 1.0], + array_vec![100.0, 0.0] ]]), foreign_members: None, }, diff --git a/src/feature_writer.rs b/src/feature_writer.rs index a48c578..0d9db01 100644 --- a/src/feature_writer.rs +++ b/src/feature_writer.rs @@ -229,6 +229,7 @@ mod tests { use crate::JsonValue; use serde_json::json; + use tinyvec::array_vec; // an example struct that we want to serialize #[derive(Serialize)] @@ -284,7 +285,7 @@ mod tests { Feature { bbox: None, - geometry: Some(crate::Geometry::from(crate::Value::Point(vec![1.1, 1.2]))), + geometry: Some(crate::Geometry::from(crate::Value::Point(array_vec![1.1, 1.2]))), id: None, properties: Some(props), foreign_members: None, @@ -298,7 +299,7 @@ mod tests { Feature { bbox: None, - geometry: Some(crate::Geometry::from(crate::Value::Point(vec![2.1, 2.2]))), + geometry: Some(crate::Geometry::from(crate::Value::Point(array_vec![2.1, 2.2]))), id: None, properties: Some(props), foreign_members: None, @@ -340,12 +341,12 @@ mod tests { { let mut writer = FeatureWriter::from_writer(&mut buffer); let record_1 = MyRecord { - geometry: crate::Geometry::from(crate::Value::Point(vec![1.1, 1.2])), + geometry: crate::Geometry::from(crate::Value::Point(array_vec![1.1, 1.2])), name: "Mishka".to_string(), age: 12, }; let record_2 = MyRecord { - geometry: crate::Geometry::from(crate::Value::Point(vec![2.1, 2.2])), + geometry: crate::Geometry::from(crate::Value::Point(array_vec![2.1, 2.2])), name: "Jane".to_string(), age: 22, }; diff --git a/src/geojson.rs b/src/geojson.rs index 301c0de..15a540d 100644 --- a/src/geojson.rs +++ b/src/geojson.rs @@ -396,6 +396,7 @@ mod tests { use serde_json::json; use std::convert::TryInto; use std::str::FromStr; + use tinyvec::array_vec; #[test] fn test_geojson_from_reader() { @@ -443,7 +444,7 @@ mod tests { geojson, GeoJson::Feature(Feature { bbox: None, - geometry: Some(Geometry::new(Value::Point(vec![102.0, 0.5]))), + geometry: Some(Geometry::new(Value::Point(array_vec![102.0, 0.5]))), id: None, properties: None, foreign_members: None, @@ -468,7 +469,7 @@ mod tests { geojson, GeoJson::Feature(Feature { bbox: None, - geometry: Some(Geometry::new(Value::Point(vec![102.0, 0.5]))), + geometry: Some(Geometry::new(Value::Point(array_vec![102.0, 0.5]))), id: None, properties: None, foreign_members: None, diff --git a/src/geometry.rs b/src/geometry.rs index 6d134ed..ccabb20 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -364,6 +364,7 @@ mod tests { use crate::{Error, GeoJson, Geometry, JsonObject, Value}; use serde_json::json; use std::str::FromStr; + use tinyvec::array_vec; fn encode(geometry: &Geometry) -> String { serde_json::to_string(&geometry).unwrap() @@ -376,7 +377,7 @@ mod tests { 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]), + value: Value::Point(array_vec![1.1, 2.1]), bbox: None, foreign_members: None, }; @@ -410,7 +411,7 @@ mod tests { assert_eq!( geometry, Geometry { - value: Value::Point(vec![0.0, 0.1]), + value: Value::Point(array_vec![0.0, 0.1]), bbox: None, foreign_members: None, } @@ -419,7 +420,7 @@ 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 v = Value::LineString(vec![array_vec![0.0, 0.1], array_vec![0.1, 0.2], array_vec![0.2, 0.3]]); let geometry = Geometry::new(v); assert_eq!( "{\"coordinates\":[[0.0,0.1],[0.1,0.2],[0.2,0.3]],\"type\":\"LineString\"}", @@ -429,7 +430,7 @@ mod tests { #[test] fn test_value_display() { - let v = Value::LineString(vec![vec![0.0, 0.1], vec![0.1, 0.2], vec![0.2, 0.3]]); + let v = Value::LineString(vec![array_vec![0.0, 0.1], array_vec![0.1, 0.2], array_vec![0.2, 0.3]]); assert_eq!( "{\"coordinates\":[[0.0,0.1],[0.1,0.2],[0.2,0.3]],\"type\":\"LineString\"}", v.to_string() @@ -446,7 +447,7 @@ mod tests { serde_json::to_value(true).unwrap(), ); let geometry = Geometry { - value: Value::Point(vec![1.1, 2.1]), + value: Value::Point(array_vec![1.1, 2.1]), bbox: None, foreign_members: Some(foreign_members), }; @@ -470,12 +471,12 @@ mod tests { value: Value::GeometryCollection(vec![ Geometry { bbox: None, - value: Value::Point(vec![100.0, 0.0]), + value: Value::Point(array_vec![100.0, 0.0]), foreign_members: None, }, Geometry { bbox: None, - value: Value::LineString(vec![vec![101.0, 0.0], vec![102.0, 1.0]]), + value: Value::LineString(vec![array_vec![101.0, 0.0], array_vec![102.0, 1.0]]), foreign_members: None, }, ]), diff --git a/src/lib.rs b/src/lib.rs index 045faa0..8458939 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -424,7 +424,7 @@ pub type Bbox = Vec; /// Positions /// /// [GeoJSON Format Specification ยง 3.1.1](https://tools.ietf.org/html/rfc7946#section-3.1.1) -pub type Position = Vec; +pub type Position = ArrayVec<[f64; 4]>; pub type PointType = Position; pub type LineStringType = Vec; @@ -468,6 +468,7 @@ pub use feature_writer::FeatureWriter; #[cfg(feature = "geo-types")] pub use conversion::quick_collection; +use tinyvec::ArrayVec; /// Feature Objects /// diff --git a/src/ser.rs b/src/ser.rs index 1a17e5f..80b48d5 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -365,6 +365,7 @@ mod tests { use crate::JsonValue; use serde_json::json; + use tinyvec::array_vec; use std::str::FromStr; @@ -377,7 +378,7 @@ mod tests { } let my_feature = { - let geometry = crate::Geometry::new(crate::Value::Point(vec![0.0, 1.0])); + let geometry = crate::Geometry::new(crate::Value::Point(array_vec![0.0, 1.0])); let name = "burbs".to_string(); MyStruct { geometry, name } }; @@ -409,7 +410,7 @@ mod tests { #[test] fn with_some_geom() { let my_feature = { - let geometry = Some(crate::Geometry::new(crate::Value::Point(vec![0.0, 1.0]))); + let geometry = Some(crate::Geometry::new(crate::Value::Point(array_vec![0.0, 1.0]))); let name = "burbs".to_string(); MyStruct { geometry, name } }; diff --git a/src/util.rs b/src/util.rs index d8b5652..d0842c2 100644 --- a/src/util.rs +++ b/src/util.rs @@ -210,7 +210,10 @@ pub fn get_features(object: &mut JsonObject) -> Result> { fn json_to_position(json: &JsonValue) -> Result { let coords_array = expect_array(json)?; - let mut coords = Vec::with_capacity(coords_array.len()); + + // TODO: Check to make sure there are not more than 4 coordinates. + + let mut coords = Position::default(); for position in coords_array { coords.push(expect_f64(position)?); }