paleolimbot commented on code in PR #498:
URL: https://github.com/apache/sedona-db/pull/498#discussion_r2676761676


##########
rust/sedona-functions/src/st_geomfromwkt.rs:
##########
@@ -147,8 +149,132 @@ fn invoke_scalar(wkt_bytes: &str, builder: &mut 
BinaryBuilder) -> Result<()> {
     .map_err(|err| DataFusionError::Internal(format!("WKB write error: 
{err}")))
 }
 
+/// ST_GeomFromEWKT() UDF implementation
+///
+/// An implementation of EWKT reading using GeoRust's wkt crate.
+pub fn st_geomfromewkt_udf() -> SedonaScalarUDF {
+    let doc = Documentation::builder(
+        DOC_SECTION_OTHER,
+        "Construct a Geometry from EWKT",
+        "ST_GeomFromEWKT (Ewkt: String)",
+    )
+    .with_argument(
+        "EWKT",
+        "string: Extended well-known text representation of the geometry",
+    )
+    .with_sql_example("SELECT ST_GeomFromEWKT('SRID=4326;POINT(40.7128 
-74.0060)')")
+    .build();
+
+    SedonaScalarUDF::new(
+        "st_geomfromewkt",
+        vec![Arc::new(STGeoFromEWKT {})],
+        Volatility::Immutable,
+        Some(doc),
+    )
+}
+
+#[derive(Debug)]
+struct STGeoFromEWKT {}
+
+impl SedonaScalarKernel for STGeoFromEWKT {
+    fn return_type(&self, args: &[SedonaType]) -> Result<Option<SedonaType>> {
+        let matcher = ArgMatcher::new(
+            vec![ArgMatcher::is_string()],
+            SedonaType::new_item_crs(&WKB_GEOMETRY)?,
+        );
+        matcher.match_args(args)
+    }
+
+    fn invoke_batch(
+        &self,
+        arg_types: &[SedonaType],
+        args: &[ColumnarValue],
+    ) -> Result<ColumnarValue> {
+        let executor = WkbExecutor::new(arg_types, args);
+        let arg_array = args[0]
+            .cast_to(&DataType::Utf8View, None)?
+            .to_array(executor.num_iterations())?;
+
+        let mut geom_builder = BinaryBuilder::with_capacity(
+            executor.num_iterations(),
+            WKB_MIN_PROBABLE_BYTES * executor.num_iterations(),
+        );
+        let mut srid_builder = 
StringViewBuilder::with_capacity(executor.num_iterations());
+
+        for item in as_string_view_array(&arg_array)? {
+            if let Some(ewkt_bytes) = item {
+                match ewkt_bytes.split_once(";") {
+                    Some((maybe_srid, wkt_bytes)) => {
+                        let srid = parse_maybe_srid(maybe_srid);
+                        invoke_scalar_with_srid(
+                            wkt_bytes,
+                            srid,
+                            &mut geom_builder,
+                            &mut srid_builder,
+                        )?;
+                    }
+                    None => {
+                        invoke_scalar_with_srid(
+                            ewkt_bytes,
+                            None,
+                            &mut geom_builder,
+                            &mut srid_builder,
+                        )?;
+                    }
+                }
+                geom_builder.append_value(vec![]);
+            } else {
+                geom_builder.append_null();
+                srid_builder.append_null();
+            }
+        }
+
+        let new_geom_array = geom_builder.finish();
+        let item_result = executor.finish(Arc::new(new_geom_array))?;
+
+        let new_srid_array = srid_builder.finish();
+        let crs_value = if matches!(&item_result, ColumnarValue::Scalar(_)) {
+            ColumnarValue::Scalar(ScalarValue::try_from_array(&new_srid_array, 
0)?)
+        } else {
+            ColumnarValue::Array(Arc::new(new_srid_array))
+        };
+
+        make_item_crs(&WKB_GEOMETRY, item_result, &crs_value, None)
+    }
+}
+
+fn parse_maybe_srid(maybe_srid: &str) -> Option<String> {
+    if !maybe_srid.starts_with("SRID=") {
+        return None;
+    }
+    let srid_str = &maybe_srid[5..];
+    let auth_code = match srid_str.parse::<u32>() {
+        Ok(0) => return None,
+        Ok(4326) => "OGC:CRS84".to_string(),
+        Ok(srid) => format!("EPSG:{srid}"),
+        Err(_) => return None,
+    };
+
+    // TODO: the CRS should be validated
+    // validate_crs(&auth_code, maybe_engine)?;

Review Comment:
   ```suggestion
       // CRS could be validated here
       // https://github.com/apache/sedona-db/issues/501
   ```



-- 
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