Kontinuation commented on code in PR #194:
URL: https://github.com/apache/sedona-db/pull/194#discussion_r2413850967


##########
rust/sedona-geo-traits-ext/src/line_string.rs:
##########
@@ -0,0 +1,198 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// Extend LineStringTrait traits for the `geo-traits` crate
+
+use geo_traits::{GeometryTrait, LineStringTrait, UnimplementedLineString};
+use geo_types::{Coord, CoordNum, Line, LineString, Triangle};
+
+use crate::{CoordTraitExt, GeoTraitExtWithTypeTag, LineStringTag};
+
+/// Additional convenience methods for [`LineStringTrait`] implementers that 
mirror `geo-types`.
+pub trait LineStringTraitExt:
+    LineStringTrait + GeoTraitExtWithTypeTag<Tag = LineStringTag>
+where
+    <Self as GeometryTrait>::T: CoordNum,
+{
+    type CoordTypeExt<'a>: 'a + CoordTraitExt<T = <Self as GeometryTrait>::T>
+    where
+        Self: 'a;
+
+    /// Returns the coordinate at the provided index.
+    fn coord_ext(&self, i: usize) -> Option<Self::CoordTypeExt<'_>>;
+
+    /// Returns a coordinate by index without bounds checking.
+    ///
+    /// # Safety
+    /// The caller must ensure that `i` is a valid index less than the number 
of coordinates.
+    /// Otherwise, this function may cause undefined behavior.
+    unsafe fn coord_unchecked_ext(&self, i: usize) -> Self::CoordTypeExt<'_>;
+
+    /// Returns an iterator over all coordinates as extension trait instances.
+    fn coords_ext(&self) -> impl Iterator<Item = Self::CoordTypeExt<'_>>;
+
+    /// Returns a coordinate by index without bounds checking.
+    ///
+    /// # Safety
+    /// The caller must ensure that `i` is a valid index less than the number 
of coordinates.
+    /// Otherwise, this function may cause undefined behavior.
+    #[inline]
+    unsafe fn geo_coord_unchecked(&self, i: usize) -> Coord<Self::T> {
+        self.coord_unchecked_ext(i).geo_coord()
+    }
+
+    /// Return an iterator yielding one [`Line`] for each line segment
+    /// in the [`LineString`][`geo_types::LineString`].
+    #[inline]
+    fn lines(&'_ self) -> impl ExactSizeIterator<Item = Line<<Self as 
GeometryTrait>::T>> + '_ {
+        let num_coords = self.num_coords();
+        (0..num_coords.saturating_sub(1)).map(|i| unsafe {
+            let coord1 = self.coord_unchecked_ext(i);
+            let coord2 = self.coord_unchecked_ext(i + 1);
+            Line::new(coord1.geo_coord(), coord2.geo_coord())
+        })
+    }
+
+    /// Return an iterator yielding one [`Line`] for each line segment in the 
[`LineString`][`geo_types::LineString`],
+    /// starting from the **end** point of the LineString, working towards the 
start.
+    ///
+    /// Note: This is like [`Self::lines`], but the sequence **and** the 
orientation of
+    /// segments are reversed.
+    #[inline]
+    fn rev_lines(&'_ self) -> impl ExactSizeIterator<Item = Line<<Self as 
GeometryTrait>::T>> + '_ {
+        let num_coords = self.num_coords();
+        (num_coords - 1..0).map(|i| unsafe {
+            let coord1 = self.coord_unchecked_ext(i);
+            let coord2 = self.coord_unchecked_ext(i - 1);
+            Line::new(coord2.geo_coord(), coord1.geo_coord())
+        })
+    }
+
+    /// An iterator which yields the coordinates of a 
[`LineString`][`geo_types::LineString`] as [Triangle]s
+    #[inline]
+    fn triangles(
+        &'_ self,
+    ) -> impl ExactSizeIterator<Item = Triangle<<Self as GeometryTrait>::T>> + 
'_ {
+        let num_coords = self.num_coords();
+        (0..num_coords - 2).map(|i| unsafe {
+            let coord1 = self.coord_unchecked_ext(i);
+            let coord2 = self.coord_unchecked_ext(i + 1);
+            let coord3 = self.coord_unchecked_ext(i + 2);
+            Triangle::new(coord1.geo_coord(), coord2.geo_coord(), 
coord3.geo_coord())
+        })
+    }
+
+    /// Returns an iterator yielding the coordinates of this line string as 
[`geo_types::Coord`] values.
+    #[inline]
+    fn coord_iter(&self) -> impl Iterator<Item = Coord<<Self as 
GeometryTrait>::T>> {
+        self.coords_ext().map(|c| c.geo_coord())
+    }
+
+    #[inline]
+    /// Returns true when the line string is closed (its first and last 
coordinates are equal).
+    fn is_closed(&self) -> bool {
+        match (self.coords_ext().next(), self.coords_ext().last()) {

Review Comment:
   Reimplemented this using `geo_coord_unchecked`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to