diff --git a/Cargo.toml b/Cargo.toml index d27db94a..e19f221c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,6 +63,10 @@ name = "gdal" test = false required-features = ["gdal"] +[[bench]] +name = "from_geo" +harness = false + [[bench]] name = "geos_buffer" harness = false diff --git a/benches/from_geo.rs b/benches/from_geo.rs new file mode 100644 index 00000000..41c3faf1 --- /dev/null +++ b/benches/from_geo.rs @@ -0,0 +1,34 @@ +use geo::polygon; + +use criterion::{criterion_group, criterion_main, Criterion}; +use geoarrow::array::{MutablePolygonArray, PolygonArray}; + +fn create_data() -> Vec { + // An L shape + // https://github.com/georust/geo/blob/7cb7d0ffa6bf1544c5ca9922bd06100c36f815d7/README.md?plain=1#L40 + let poly = polygon![ + (x: 0.0, y: 0.0), + (x: 4.0, y: 0.0), + (x: 4.0, y: 1.0), + (x: 1.0, y: 1.0), + (x: 1.0, y: 4.0), + (x: 0.0, y: 4.0), + (x: 0.0, y: 0.0), + ]; + let v = vec![poly; 1000]; + v +} + +pub fn criterion_benchmark(c: &mut Criterion) { + let data = create_data(); + + c.bench_function("convert Vec to PolygonArray", |b| { + b.iter(|| { + let mut_arr = MutablePolygonArray::::from_polygons(&data, Default::default()); + let _arr: PolygonArray = mut_arr.into(); + }) + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/src/geo_traits/geometry.rs b/src/geo_traits/geometry.rs index 16a7aef7..b86bdd69 100644 --- a/src/geo_traits/geometry.rs +++ b/src/geo_traits/geometry.rs @@ -110,3 +110,41 @@ impl<'a, T: CoordNum + 'a> GeometryTrait for Geometry { } } } + +impl<'a, T: CoordNum + 'a> GeometryTrait for &'a Geometry { + type T = T; + type Point<'b> = Point where Self: 'b; + type LineString<'b> = LineString where Self: 'b; + type Polygon<'b> = Polygon where Self: 'b; + type MultiPoint<'b> = MultiPoint where Self: 'b; + type MultiLineString<'b> = MultiLineString where Self: 'b; + type MultiPolygon<'b> = MultiPolygon where Self: 'b; + type GeometryCollection<'b> = GeometryCollection where Self: 'b; + type Rect<'b> = Rect where Self: 'b; + + fn as_type( + &self, + ) -> GeometryType< + '_, + Point, + LineString, + Polygon, + MultiPoint, + MultiLineString, + MultiPolygon, + GeometryCollection, + Rect, + > { + match self { + Geometry::Point(p) => GeometryType::Point(p), + Geometry::LineString(p) => GeometryType::LineString(p), + Geometry::Polygon(p) => GeometryType::Polygon(p), + Geometry::MultiPoint(p) => GeometryType::MultiPoint(p), + Geometry::MultiLineString(p) => GeometryType::MultiLineString(p), + Geometry::MultiPolygon(p) => GeometryType::MultiPolygon(p), + Geometry::GeometryCollection(p) => GeometryType::GeometryCollection(p), + Geometry::Rect(p) => GeometryType::Rect(p), + _ => todo!(), + } + } +} diff --git a/src/geo_traits/geometry_collection.rs b/src/geo_traits/geometry_collection.rs index 77c39cce..1c724c8f 100644 --- a/src/geo_traits/geometry_collection.rs +++ b/src/geo_traits/geometry_collection.rs @@ -1,6 +1,5 @@ use super::GeometryTrait; use geo::{CoordNum, Geometry, GeometryCollection}; -use std::iter::Cloned; use std::slice::Iter; pub trait GeometryCollectionTrait { @@ -25,14 +24,14 @@ pub trait GeometryCollectionTrait { impl GeometryCollectionTrait for GeometryCollection { type T = T; - type ItemType<'a> = Geometry + type ItemType<'a> = &'a Geometry where Self: 'a; - type Iter<'a> = Cloned>> + type Iter<'a> = Iter<'a, Geometry> where T: 'a; fn geometries(&self) -> Self::Iter<'_> { - self.0.iter().cloned() + self.0.iter() } fn num_geometries(&self) -> usize { @@ -40,19 +39,19 @@ impl GeometryCollectionTrait for GeometryCollection { } fn geometry(&self, i: usize) -> Option> { - self.0.get(i).cloned() + self.0.get(i) } } impl<'a, T: CoordNum> GeometryCollectionTrait for &'a GeometryCollection { type T = T; - type ItemType<'b> = Geometry where + type ItemType<'b> = &'a Geometry where Self: 'b; - type Iter<'b> = Cloned>> where + type Iter<'b> = Iter<'a, Geometry> where Self: 'b; fn geometries(&self) -> Self::Iter<'_> { - self.0.iter().cloned() + self.0.iter() } fn num_geometries(&self) -> usize { @@ -60,6 +59,6 @@ impl<'a, T: CoordNum> GeometryCollectionTrait for &'a GeometryCollection { } fn geometry(&self, i: usize) -> Option> { - self.0.get(i).cloned() + self.0.get(i) } } diff --git a/src/geo_traits/line_string.rs b/src/geo_traits/line_string.rs index b3328da9..6ea897a6 100644 --- a/src/geo_traits/line_string.rs +++ b/src/geo_traits/line_string.rs @@ -1,6 +1,5 @@ use super::CoordTrait; use geo::{Coord, CoordNum, LineString}; -use std::iter::Cloned; use std::slice::Iter; pub trait LineStringTrait { @@ -25,12 +24,11 @@ pub trait LineStringTrait { impl LineStringTrait for LineString { type T = T; - type ItemType<'a> = Coord where Self: 'a; - type Iter<'a> = Cloned>> where T: 'a; + type ItemType<'a> = &'a Coord where Self: 'a; + type Iter<'a> = Iter<'a, Coord> where T: 'a; fn coords(&self) -> Self::Iter<'_> { - // TODO: remove cloned - self.0.iter().cloned() + self.0.iter() } fn num_coords(&self) -> usize { @@ -38,17 +36,17 @@ impl LineStringTrait for LineString { } fn coord(&self, i: usize) -> Option> { - self.0.get(i).cloned() + self.0.get(i) } } impl<'a, T: CoordNum> LineStringTrait for &'a LineString { type T = T; - type ItemType<'b> = Coord where Self: 'b; - type Iter<'b> = Cloned>> where Self: 'b; + type ItemType<'b> = &'a Coord where Self: 'b; + type Iter<'b> = Iter<'a, Coord> where Self: 'b; fn coords(&self) -> Self::Iter<'_> { - self.0.iter().cloned() + self.0.iter() } fn num_coords(&self) -> usize { @@ -56,6 +54,6 @@ impl<'a, T: CoordNum> LineStringTrait for &'a LineString { } fn coord(&self, i: usize) -> Option> { - self.0.get(i).cloned() + self.0.get(i) } } diff --git a/src/geo_traits/multi_line_string.rs b/src/geo_traits/multi_line_string.rs index 032ec68c..f6e6c249 100644 --- a/src/geo_traits/multi_line_string.rs +++ b/src/geo_traits/multi_line_string.rs @@ -1,6 +1,5 @@ use super::line_string::LineStringTrait; use geo::{CoordNum, LineString, MultiLineString}; -use std::iter::Cloned; use std::slice::Iter; pub trait MultiLineStringTrait { @@ -25,11 +24,11 @@ pub trait MultiLineStringTrait { impl MultiLineStringTrait for MultiLineString { type T = T; - type ItemType<'a> = LineString where Self: 'a; - type Iter<'a> = Cloned>> where T: 'a; + type ItemType<'a> = &'a LineString where Self: 'a; + type Iter<'a> = Iter<'a, LineString> where T: 'a; fn lines(&self) -> Self::Iter<'_> { - self.0.iter().cloned() + self.0.iter() } fn num_lines(&self) -> usize { @@ -37,17 +36,17 @@ impl MultiLineStringTrait for MultiLineString { } fn line(&self, i: usize) -> Option> { - self.0.get(i).cloned() + self.0.get(i) } } impl<'a, T: CoordNum> MultiLineStringTrait for &'a MultiLineString { type T = T; - type ItemType<'b> = LineString where Self: 'b; - type Iter<'b> = Cloned>> where Self: 'b; + type ItemType<'b> = &'a LineString where Self: 'b; + type Iter<'b> = Iter<'a, LineString> where Self: 'b; fn lines(&self) -> Self::Iter<'_> { - self.0.iter().cloned() + self.0.iter() } fn num_lines(&self) -> usize { @@ -55,6 +54,6 @@ impl<'a, T: CoordNum> MultiLineStringTrait for &'a MultiLineString { } fn line(&self, i: usize) -> Option> { - self.0.get(i).cloned() + self.0.get(i) } } diff --git a/src/geo_traits/multi_point.rs b/src/geo_traits/multi_point.rs index 427cf74f..7b0ce568 100644 --- a/src/geo_traits/multi_point.rs +++ b/src/geo_traits/multi_point.rs @@ -1,6 +1,5 @@ use super::point::PointTrait; use geo::{CoordNum, MultiPoint, Point}; -use std::iter::Cloned; use std::slice::Iter; pub trait MultiPointTrait { @@ -25,11 +24,11 @@ pub trait MultiPointTrait { impl MultiPointTrait for MultiPoint { type T = T; - type ItemType<'a> = Point where Self: 'a; - type Iter<'a> = Cloned>> where T: 'a; + type ItemType<'a> = &'a Point where Self: 'a; + type Iter<'a> = Iter<'a, Point> where T: 'a; fn points(&self) -> Self::Iter<'_> { - self.0.iter().cloned() + self.0.iter() } fn num_points(&self) -> usize { @@ -37,17 +36,17 @@ impl MultiPointTrait for MultiPoint { } fn point(&self, i: usize) -> Option> { - self.0.get(i).cloned() + self.0.get(i) } } impl<'a, T: CoordNum> MultiPointTrait for &'a MultiPoint { type T = T; - type ItemType<'b> = Point where Self: 'b; - type Iter<'b> = Cloned>> where Self: 'b; + type ItemType<'b> = &'a Point where Self: 'b; + type Iter<'b> = Iter<'a, Point> where Self: 'b; fn points(&self) -> Self::Iter<'_> { - self.0.iter().cloned() + self.0.iter() } fn num_points(&self) -> usize { @@ -55,6 +54,6 @@ impl<'a, T: CoordNum> MultiPointTrait for &'a MultiPoint { } fn point(&self, i: usize) -> Option> { - self.0.get(i).cloned() + self.0.get(i) } } diff --git a/src/geo_traits/multi_polygon.rs b/src/geo_traits/multi_polygon.rs index 6cc3df7e..cd94b2b7 100644 --- a/src/geo_traits/multi_polygon.rs +++ b/src/geo_traits/multi_polygon.rs @@ -1,6 +1,5 @@ use super::polygon::PolygonTrait; use geo::{CoordNum, MultiPolygon, Polygon}; -use std::iter::Cloned; use std::slice::Iter; pub trait MultiPolygonTrait { @@ -25,11 +24,11 @@ pub trait MultiPolygonTrait { impl MultiPolygonTrait for MultiPolygon { type T = T; - type ItemType<'a> = Polygon where Self: 'a; - type Iter<'a> = Cloned>> where T: 'a; + type ItemType<'a> = &'a Polygon where Self: 'a; + type Iter<'a> = Iter<'a, Polygon> where T: 'a; fn polygons(&self) -> Self::Iter<'_> { - self.0.iter().cloned() + self.0.iter() } fn num_polygons(&self) -> usize { @@ -37,17 +36,17 @@ impl MultiPolygonTrait for MultiPolygon { } fn polygon(&self, i: usize) -> Option> { - self.0.get(i).cloned() + self.0.get(i) } } impl<'a, T: CoordNum> MultiPolygonTrait for &'a MultiPolygon { type T = T; - type ItemType<'b> = Polygon where Self: 'b; - type Iter<'b> = Cloned>> where Self: 'b; + type ItemType<'b> = &'a Polygon where Self: 'b; + type Iter<'b> = Iter<'a, Polygon> where Self: 'b; fn polygons(&self) -> Self::Iter<'_> { - self.0.iter().cloned() + self.0.iter() } fn num_polygons(&self) -> usize { @@ -55,6 +54,6 @@ impl<'a, T: CoordNum> MultiPolygonTrait for &'a MultiPolygon { } fn polygon(&self, i: usize) -> Option> { - self.0.get(i).cloned() + self.0.get(i) } } diff --git a/src/geo_traits/polygon.rs b/src/geo_traits/polygon.rs index 310c5092..bac4b60e 100644 --- a/src/geo_traits/polygon.rs +++ b/src/geo_traits/polygon.rs @@ -1,6 +1,5 @@ use super::line_string::LineStringTrait; use geo::{CoordNum, LineString, Polygon}; -use std::iter::Cloned; use std::slice::Iter; pub trait PolygonTrait { @@ -28,16 +27,16 @@ pub trait PolygonTrait { impl PolygonTrait for Polygon { type T = T; - type ItemType<'a> = LineString where Self: 'a; - type Iter<'a> = Cloned>> where T: 'a; + type ItemType<'a> = &'a LineString where Self: 'a; + type Iter<'a> = Iter<'a, LineString> where T: 'a; fn exterior(&self) -> Option> { // geo-types doesn't really have a way to describe an empty polygon - Some(Polygon::exterior(self).clone()) + Some(Polygon::exterior(self)) } fn interiors(&self) -> Self::Iter<'_> { - Polygon::interiors(self).iter().cloned() + Polygon::interiors(self).iter() } fn num_interiors(&self) -> usize { @@ -45,23 +44,23 @@ impl PolygonTrait for Polygon { } fn interior(&self, i: usize) -> Option> { - Polygon::interiors(self).get(i).cloned() + Polygon::interiors(self).get(i) } } impl<'a, T: CoordNum> PolygonTrait for &'a Polygon { type T = T; - type ItemType<'b> = LineString where + type ItemType<'b> = &'a LineString where Self: 'b; - type Iter<'b> = Cloned>> where + type Iter<'b> = Iter<'a, LineString> where Self: 'b; fn exterior(&self) -> Option> { - Some(Polygon::exterior(self).clone()) + Some(Polygon::exterior(self)) } fn interiors(&self) -> Self::Iter<'_> { - Polygon::interiors(self).iter().cloned() + Polygon::interiors(self).iter() } fn num_interiors(&self) -> usize { @@ -69,6 +68,6 @@ impl<'a, T: CoordNum> PolygonTrait for &'a Polygon { } fn interior(&self, i: usize) -> Option> { - Polygon::interiors(self).get(i).cloned() + Polygon::interiors(self).get(i) } }