This is an automated email from the ASF dual-hosted git repository.

kontinuation pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/sedona-db.git


The following commit(s) were added to refs/heads/main by this push:
     new d8ed001b chore(rust/sedona-geometry): Add wkb_rect and clean up tests 
defining their own rect_wkb functions (#572)
d8ed001b is described below

commit d8ed001b6de5ddd4684d241b4def58264bd37af0
Author: Kristin Cowalcijk <[email protected]>
AuthorDate: Wed Feb 4 15:30:36 2026 +0800

    chore(rust/sedona-geometry): Add wkb_rect and clean up tests defining their 
own rect_wkb functions (#572)
    
    This is a follow up of 
https://github.com/apache/sedona-db/pull/563#discussion_r2754825987. Rect WKBs 
are useful in various places so we'd better define a utility function for 
creating them.
---
 rust/sedona-geometry/src/wkb_factory.rs            | 49 ++++++++++++++++++++++
 .../src/partitioning/stream_repartitioner.rs       | 26 +-----------
 .../src/probe/partitioned_stream_provider.rs       | 24 +----------
 3 files changed, 53 insertions(+), 46 deletions(-)

diff --git a/rust/sedona-geometry/src/wkb_factory.rs 
b/rust/sedona-geometry/src/wkb_factory.rs
index 9db1d29d..297fa901 100644
--- a/rust/sedona-geometry/src/wkb_factory.rs
+++ b/rust/sedona-geometry/src/wkb_factory.rs
@@ -180,6 +180,38 @@ pub fn wkb_polygon<I: ExactSizeIterator<Item = (f64, 
f64)>>(
     Ok(out_wkb)
 }
 
+/// Create WKB representing a rectangle
+///
+/// Returns WKB for a polygon with a single closed ring describing
+/// the rectangle bounds.
+/// This function always writes little endian coordinates.
+pub fn wkb_rect(
+    min_x: f64,
+    min_y: f64,
+    max_x: f64,
+    max_y: f64,
+) -> Result<Vec<u8>, SedonaGeometryError> {
+    if min_x > max_x {
+        return Err(SedonaGeometryError::Invalid(
+            "min_x must be <= max_x".to_string(),
+        ));
+    }
+    if min_y > max_y {
+        return Err(SedonaGeometryError::Invalid(
+            "min_y must be <= max_y".to_string(),
+        ));
+    }
+
+    let coords = [
+        (min_x, min_y),
+        (max_x, min_y),
+        (max_x, max_y),
+        (min_x, max_y),
+        (min_x, min_y),
+    ];
+    wkb_polygon(coords.into_iter())
+}
+
 /// Write WKB representing a POLYGON into a buffer
 ///
 /// This can be used to build Binary arrays, as the arrow-rs BinaryBuilder
@@ -721,6 +753,23 @@ mod test {
         );
     }
 
+    #[test]
+    fn test_wkb_rect() {
+        let wkb = wkb_rect(0.0, 0.0, 2.0, 1.0).unwrap();
+        check_bytes(&wkb, "POLYGON((0 0,2 0,2 1,0 1,0 0))");
+
+        let invalid_cases = [
+            (2.0, 0.0, 1.0, 1.0),
+            (0.0, 2.0, 1.0, 1.0),
+            (2.0, 2.0, 1.0, 1.0),
+            (1.0, 2.0, 0.0, 1.0),
+        ];
+
+        for (min_x, min_y, max_x, max_y) in invalid_cases {
+            assert!(wkb_rect(min_x, min_y, max_x, max_y).is_err());
+        }
+    }
+
     #[test]
     fn test_wkb_polygon_header() {
         let mut wkb = Vec::new();
diff --git a/rust/sedona-spatial-join/src/partitioning/stream_repartitioner.rs 
b/rust/sedona-spatial-join/src/partitioning/stream_repartitioner.rs
index 8d98d8f1..0a326cce 100644
--- a/rust/sedona-spatial-join/src/partitioning/stream_repartitioner.rs
+++ b/rust/sedona-spatial-join/src/partitioning/stream_repartitioner.rs
@@ -758,7 +758,7 @@ mod tests {
     use datafusion_physical_plan::metrics::ExecutionPlanMetricsSet;
     use sedona_geometry::bounding_box::BoundingBox;
     use sedona_geometry::interval::IntervalTrait;
-    use sedona_geometry::wkb_factory::wkb_point;
+    use sedona_geometry::wkb_factory::{wkb_point, wkb_rect};
     use sedona_schema::datatypes::WKB_GEOMETRY;
 
     use crate::{
@@ -792,28 +792,6 @@ mod tests {
         })
     }
 
-    fn rect_wkb(min_x: f64, min_y: f64, max_x: f64, max_y: f64) -> Vec<u8> {
-        assert!(min_x <= max_x, "min_x must be <= max_x");
-        assert!(min_y <= max_y, "min_y must be <= max_y");
-        let mut buf = Vec::with_capacity(1 + 4 + 4 + 4 + 5 * 16);
-        buf.push(1u8); // little endian
-        buf.extend_from_slice(&3u32.to_le_bytes()); // polygon type
-        buf.extend_from_slice(&1u32.to_le_bytes()); // single ring
-        buf.extend_from_slice(&5u32.to_le_bytes()); // five coordinates 
(closed ring)
-        let coords = [
-            (min_x, min_y),
-            (max_x, min_y),
-            (max_x, max_y),
-            (min_x, max_y),
-            (min_x, min_y),
-        ];
-        for (x, y) in coords {
-            buf.extend_from_slice(&x.to_le_bytes());
-            buf.extend_from_slice(&y.to_le_bytes());
-        }
-        buf
-    }
-
     fn read_ids(file: &RefCountedTempFile) -> Result<Vec<i32>> {
         let mut reader = EvaluatedBatchSpillReader::try_new(file)?;
         let mut ids = Vec::new();
@@ -938,7 +916,7 @@ mod tests {
 
     #[tokio::test]
     async fn repartition_multi_and_none() -> Result<()> {
-        let wkbs = vec![Some(rect_wkb(25.0, 0.0, 75.0, 20.0)), None];
+        let wkbs = vec![Some(wkb_rect(25.0, 0.0, 75.0, 20.0).unwrap()), None];
         let batch = sample_batch(&[0, 1], wkbs)?;
         let schema = batch.schema();
         let stream: SendableEvaluatedBatchStream =
diff --git a/rust/sedona-spatial-join/src/probe/partitioned_stream_provider.rs 
b/rust/sedona-spatial-join/src/probe/partitioned_stream_provider.rs
index 1a23379c..14c45b31 100644
--- a/rust/sedona-spatial-join/src/probe/partitioned_stream_provider.rs
+++ b/rust/sedona-spatial-join/src/probe/partitioned_stream_provider.rs
@@ -344,7 +344,7 @@ mod tests {
     use datafusion_physical_plan::metrics::ExecutionPlanMetricsSet;
     use futures::TryStreamExt;
     use sedona_geometry::bounding_box::BoundingBox;
-    use sedona_geometry::wkb_factory::wkb_point;
+    use sedona_geometry::wkb_factory::{wkb_point, wkb_rect};
     use sedona_schema::datatypes::WKB_GEOMETRY;
     use std::sync::Arc;
 
@@ -365,26 +365,6 @@ mod tests {
         Ok(EvaluatedBatch { batch, geom_array })
     }
 
-    fn rect_wkb(min_x: f64, min_y: f64, max_x: f64, max_y: f64) -> Vec<u8> {
-        let mut buf = Vec::with_capacity(1 + 4 + 4 + 4 + 5 * 16);
-        buf.push(1u8);
-        buf.extend_from_slice(&3u32.to_le_bytes());
-        buf.extend_from_slice(&1u32.to_le_bytes());
-        buf.extend_from_slice(&5u32.to_le_bytes());
-        let coords = [
-            (min_x, min_y),
-            (max_x, min_y),
-            (max_x, max_y),
-            (min_x, max_y),
-            (min_x, min_y),
-        ];
-        for (x, y) in coords {
-            buf.extend_from_slice(&x.to_le_bytes());
-            buf.extend_from_slice(&y.to_le_bytes());
-        }
-        buf
-    }
-
     fn ids_from_batches(batches: &[EvaluatedBatch]) -> Vec<Vec<i32>> {
         batches
             .iter()
@@ -485,7 +465,7 @@ mod tests {
     #[tokio::test]
     async fn multi_partition_stream_consumed_multiple_times() -> Result<()> {
         let partitioner = sample_partitioner()?;
-        let batch = sample_batch(&[0], vec![Some(rect_wkb(25.0, 0.0, 75.0, 
20.0))])?;
+        let batch = sample_batch(&[0], vec![Some(wkb_rect(25.0, 0.0, 75.0, 
20.0).unwrap())])?;
         let probe_stream = create_probe_stream(vec![batch], Some(partitioner));
 
         let first_pass = 
probe_stream.stream_for(SpatialPartition::Regular(0))?;

Reply via email to