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

jiayu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sedona.git


The following commit(s) were added to refs/heads/master by this push:
     new c7642009 [SEDONA-200] Add ST_CoordDim to Sedona (#889)
c7642009 is described below

commit c7642009719f1c1fad7b8d8ad6d435f999594efc
Author: Furqaanahmed Khan <[email protected]>
AuthorDate: Wed Jul 12 01:55:17 2023 -0400

    [SEDONA-200] Add ST_CoordDim to Sedona (#889)
---
 .../java/org/apache/sedona/common/Functions.java   |  1 +
 .../sedona/core/spatialOperator/JoinQuery.java     |  4 +--
 docs/api/flink/Function.md                         | 26 ++++++++++++++++++
 docs/api/sql/Function.md                           | 24 ++++++++++++++++
 .../main/java/org/apache/sedona/flink/Catalog.java |  1 +
 .../apache/sedona/flink/expressions/Functions.java | 10 +++++++
 .../java/org/apache/sedona/flink/FunctionTest.java | 17 ++++++++++++
 python/sedona/sql/st_functions.py                  | 12 ++++++++
 python/tests/sql/test_dataframe_api.py             |  1 +
 python/tests/sql/test_function.py                  |  6 ++++
 .../scala/org/apache/sedona/sql/UDF/Catalog.scala  |  1 +
 .../sql/sedona_sql/expressions/Functions.scala     | 13 +++++++++
 .../sql/sedona_sql/expressions/st_functions.scala  |  4 +++
 .../apache/sedona/sql/dataFrameAPITestScala.scala  | 32 ++++++++++++++++++++++
 .../org/apache/sedona/sql/functionTestScala.scala  | 22 +++++++++++++++
 15 files changed, 172 insertions(+), 2 deletions(-)

diff --git a/common/src/main/java/org/apache/sedona/common/Functions.java 
b/common/src/main/java/org/apache/sedona/common/Functions.java
index 501741df..666a9f5e 100644
--- a/common/src/main/java/org/apache/sedona/common/Functions.java
+++ b/common/src/main/java/org/apache/sedona/common/Functions.java
@@ -1055,4 +1055,5 @@ public class Functions {
     public static Double hausdorffDistance(Geometry g1, Geometry g2) throws 
Exception{
         return GeomUtils.getHausdorffDistance(g1, g2, -1);
     }
+
 }
diff --git 
a/core/src/main/java/org/apache/sedona/core/spatialOperator/JoinQuery.java 
b/core/src/main/java/org/apache/sedona/core/spatialOperator/JoinQuery.java
index bec77f9d..1088b809 100644
--- a/core/src/main/java/org/apache/sedona/core/spatialOperator/JoinQuery.java
+++ b/core/src/main/java/org/apache/sedona/core/spatialOperator/JoinQuery.java
@@ -22,12 +22,13 @@ package org.apache.sedona.core.spatialOperator;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.log4j.LogManager;
 import org.apache.log4j.Logger;
+import org.apache.sedona.common.geometryObjects.Circle;
 import org.apache.sedona.common.utils.GeomUtils;
 import org.apache.sedona.core.enums.IndexType;
 import org.apache.sedona.core.enums.JoinBuildSide;
-import org.apache.sedona.common.geometryObjects.Circle;
 import org.apache.sedona.core.joinJudgement.*;
 import org.apache.sedona.core.monitoring.Metric;
+import org.apache.sedona.core.monitoring.Metrics;
 import org.apache.sedona.core.spatialPartitioning.SpatialPartitioner;
 import org.apache.sedona.core.spatialRDD.CircleRDD;
 import org.apache.sedona.core.spatialRDD.SpatialRDD;
@@ -37,7 +38,6 @@ import org.apache.spark.api.java.JavaRDD;
 import org.apache.spark.api.java.JavaSparkContext;
 import org.apache.spark.api.java.function.Function2;
 import org.apache.spark.api.java.function.PairFunction;
-import org.apache.sedona.core.monitoring.Metrics;
 import org.locationtech.jts.geom.Geometry;
 import scala.Tuple2;
 
diff --git a/docs/api/flink/Function.md b/docs/api/flink/Function.md
index 517d01b2..7dd69c29 100644
--- a/docs/api/flink/Function.md
+++ b/docs/api/flink/Function.md
@@ -546,6 +546,30 @@ SELECT ST_ConvexHull(polygondf.countyshape)
 FROM polygondf
 ```
 
+##  ST_CoordDim
+
+Introduction: Returns the coordinate dimensions of the geometry. It is an 
alias of `ST_NDims`.
+
+Format: `ST_CoordDim(geom: geometry)`
+
+Since: `v1.5.0`
+
+Example with x, y, z coordinate:
+
+```sql
+SELECT ST_CoordDim(ST_GeomFromText('POINT(1 1 2'))
+```
+
+Output: `3`
+
+Example with x, y coordinate:
+
+```sql
+SELECT ST_CoordDim(ST_GeomFromEWKT('POINT(3 7)'))
+```
+
+Output: `2`
+
 ## ST_Dimension
 
 Introduction: Return the topological dimension of this Geometry object, which 
must be less than or equal to the coordinate dimension. OGC SPEC s2.1.1.1 - 
returns 0 for POINT, 1 for LINESTRING, 2 for POLYGON, and the largest dimension 
of the components of a GEOMETRYCOLLECTION. If the dimension is unknown (e.g. 
for an empty GEOMETRYCOLLECTION) 0 is returned.
@@ -1932,3 +1956,5 @@ SELECT ST_ZMin(ST_GeomFromText('LINESTRING(1 3 4, 5 6 
7)'))
 ```
 
 Output: `4.0`
+
+
diff --git a/docs/api/sql/Function.md b/docs/api/sql/Function.md
index 59a65c2f..8edda106 100644
--- a/docs/api/sql/Function.md
+++ b/docs/api/sql/Function.md
@@ -593,6 +593,30 @@ SELECT ST_ConvexHull(polygondf.countyshape)
 FROM polygondf
 ```
 
+##  ST_CoordDim
+
+Introduction: Returns the coordinate dimensions of the geometry. It is an 
alias of `ST_NDims`.
+
+Format: `ST_CoordDim(geom: geometry)`
+
+Since: `v1.5.0`
+
+Example with x, y, z coordinate:
+
+```sql
+SELECT ST_CoordDim(ST_GeomFromText('POINT(1 1 2'))
+```
+
+Output: `3`
+
+Example with x, y coordinate:
+
+```sql
+SELECT ST_CoordDim(ST_GeomFromEWKT('POINT(3 7)'))
+```
+
+Output: `2`
+
 ## ST_Degrees
 
 Introduction: Convert an angle in radian to degrees.
diff --git a/flink/src/main/java/org/apache/sedona/flink/Catalog.java 
b/flink/src/main/java/org/apache/sedona/flink/Catalog.java
index d773438b..5d343227 100644
--- a/flink/src/main/java/org/apache/sedona/flink/Catalog.java
+++ b/flink/src/main/java/org/apache/sedona/flink/Catalog.java
@@ -132,6 +132,7 @@ public class Catalog {
                 new Functions.ST_Angle(),
                 new Functions.ST_Degrees(),
                 new Functions.ST_HausdorffDistance(),
+                new Functions.ST_CoordDim(),
         };
     }
 
diff --git 
a/flink/src/main/java/org/apache/sedona/flink/expressions/Functions.java 
b/flink/src/main/java/org/apache/sedona/flink/expressions/Functions.java
index 971a9451..3f4b63eb 100644
--- a/flink/src/main/java/org/apache/sedona/flink/expressions/Functions.java
+++ b/flink/src/main/java/org/apache/sedona/flink/expressions/Functions.java
@@ -922,6 +922,15 @@ public class Functions {
         }
     }
 
+
+    public static class ST_CoordDim extends ScalarFunction {
+        @DataTypeHint("Integer")
+        public Integer eval(@DataTypeHint(value = "RAW", bridgedTo = 
org.locationtech.jts.geom.Geometry.class) Object o) {
+            Geometry geom = (Geometry) o;
+            return org.apache.sedona.common.Functions.nDims(geom);
+        }
+    }
+
     public static class ST_Angle extends ScalarFunction {
 
         @DataTypeHint("Double")
@@ -962,6 +971,7 @@ public class Functions {
         @DataTypeHint("Double")
         public Double eval(@DataTypeHint("Double") Double angleInRadian) {
             return org.apache.sedona.common.Functions.degrees(angleInRadian);
+
         }
     }
 }
diff --git a/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java 
b/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
index 247e4635..c7dea77f 100644
--- a/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
+++ b/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
@@ -1020,4 +1020,21 @@ public class FunctionTest extends TestBase{
         assertEquals(expected, actual);
         assertEquals(expectedDefault, actualDefault);
     }
+
+    @Test
+    public void testCoordDimFor2D() {
+        Table polygonTable = tableEnv.sqlQuery("SELECT ST_GeomFromWKT('POINT(3 
7)') AS " + polygonColNames[0]);
+        polygonTable = 
polygonTable.select(call(Functions.ST_CoordDim.class.getSimpleName(), 
$(polygonColNames[0])));
+        int result = (int) first(polygonTable).getField(0);
+        assertEquals(2, result, 0);
+    }
+
+    @Test
+    public void testCoordDimFor3D() {
+        Table polygonTable = tableEnv.sqlQuery("SELECT ST_GeomFromWKT('POINT(1 
2 1)') AS " + polygonColNames[0]);
+        polygonTable = 
polygonTable.select(call(Functions.ST_CoordDim.class.getSimpleName(), 
$(polygonColNames[0])));
+        int result = (int) first(polygonTable).getField(0);
+        assertEquals(3, result, 0);
+    }
+
 }
diff --git a/python/sedona/sql/st_functions.py 
b/python/sedona/sql/st_functions.py
index 81f067ab..97cdaac3 100644
--- a/python/sedona/sql/st_functions.py
+++ b/python/sedona/sql/st_functions.py
@@ -118,6 +118,7 @@ __all__ = [
     "ST_Angle",
     "ST_Degrees",
     "ST_FrechetDistance",
+    "ST_CoordDim",
     "ST_Affine",
     "ST_BoundingDiagonal"
 ]
@@ -1422,3 +1423,14 @@ def ST_HausdorffDistance(g1: ColumnOrName, g2: 
ColumnOrName, densityFrac: Option
     args = (g1, g2, densityFrac)
     return _call_st_function("ST_HausdorffDistance", args)
 
+@validate_argument_types
+def ST_CoordDim(geometry: ColumnOrName) -> Column:
+    """Return the number of dimensions contained in a coordinate
+
+    :param geometry: Geometry column to return for.
+    :type geometry: ColumnOrName
+    :return: Number of dimensinos in a coordinate column as an integer column.
+    :rtype: Column
+    """
+    return _call_st_function("ST_CoordDim", geometry)
+
diff --git a/python/tests/sql/test_dataframe_api.py 
b/python/tests/sql/test_dataframe_api.py
index 5590a514..7adf1bca 100644
--- a/python/tests/sql/test_dataframe_api.py
+++ b/python/tests/sql/test_dataframe_api.py
@@ -82,6 +82,7 @@ test_configurations = [
     (stf.ST_ConcaveHull, ("geom", 1.0), "triangle_geom", "", "POLYGON ((0 0, 1 
1, 1 0, 0 0))"),
     (stf.ST_ConcaveHull, ("geom", 1.0, True), "triangle_geom", "", "POLYGON 
((1 1, 1 0, 0 0, 1 1))"),
     (stf.ST_ConvexHull, ("geom",), "triangle_geom", "", "POLYGON ((0 0, 1 1, 1 
0, 0 0))"),
+    (stf.ST_CoordDim, ("point",), "point_geom", "", 2),
     (stf.ST_Difference, ("a", "b"), "overlapping_polys", "", "POLYGON ((1 0, 0 
0, 0 1, 1 1, 1 0))"),
     (stf.ST_Dimension, ("geom",), "geometry_geom_collection", "", 1),
     (stf.ST_Distance, ("a", "b"), "two_points", "", 3.0),
diff --git a/python/tests/sql/test_function.py 
b/python/tests/sql/test_function.py
index 2954d5a2..b02dda0c 100644
--- a/python/tests/sql/test_function.py
+++ b/python/tests/sql/test_function.py
@@ -1177,3 +1177,9 @@ class TestPredicateJoin(TestBase):
         actual_default = actual_df_default.take(1)[0][0]
         assert expected == actual
         assert expected == actual_default
+
+    def test_st_coord_dim(self):
+
+        point_df = self.spark.sql("SELECT ST_GeomFromWkt('POINT(7 8 6)') AS 
geom")
+        point_row = [pt_row[0] for pt_row in 
point_df.selectExpr("ST_CoordDim(geom)").collect()]
+        assert(point_row == [3])
\ No newline at end of file
diff --git a/sql/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala 
b/sql/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
index dcbf198c..de1d1e69 100644
--- a/sql/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
+++ b/sql/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
@@ -47,6 +47,7 @@ object Catalog {
     function[ST_GeomFromGeoJSON](),
     function[ST_GeomFromGML](),
     function[ST_GeomFromKML](),
+    function[ST_CoordDim](),
     function[ST_Point](),
     function[ST_PointZ](0),
     function[ST_PolygonFromEnvelope](),
diff --git 
a/sql/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
 
b/sql/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
index 235b38bd..a9bba934 100644
--- 
a/sql/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
+++ 
b/sql/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
@@ -1070,3 +1070,16 @@ case class ST_Degrees(inputExpressions: Seq[Expression])
     copy(inputExpressions = newChildren)
   }
 }
+
+/**
+ * Return the number of ddimensions in geometry.
+ *
+ * @param inputExpressions
+ * */
+case class ST_CoordDim(inputExpressions: Seq[Expression])
+  extends InferredExpression(Functions.nDims _) {
+  protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]): 
Expression = {
+    copy(inputExpressions = newChildren)
+  }
+}
+
diff --git 
a/sql/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_functions.scala
 
b/sql/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_functions.scala
index 05045ba9..be28d32e 100644
--- 
a/sql/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_functions.scala
+++ 
b/sql/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_functions.scala
@@ -380,5 +380,9 @@ object st_functions extends DataFrameAPI {
 
   def ST_HausdorffDistance(g1: String, g2: String, densityFrac: Double) = 
wrapExpression[ST_HausdorffDistance](g1, g2, densityFrac);
 
+  def ST_CoordDim(geometry: Column): Column = 
wrapExpression[ST_CoordDim](geometry)
+
+  def ST_CoordDim(geometry: String): Column = 
wrapExpression[ST_CoordDim](geometry)
+
 }
  
\ No newline at end of file
diff --git 
a/sql/common/src/test/scala/org/apache/sedona/sql/dataFrameAPITestScala.scala 
b/sql/common/src/test/scala/org/apache/sedona/sql/dataFrameAPITestScala.scala
index b02bf51d..51de7d2b 100644
--- 
a/sql/common/src/test/scala/org/apache/sedona/sql/dataFrameAPITestScala.scala
+++ 
b/sql/common/src/test/scala/org/apache/sedona/sql/dataFrameAPITestScala.scala
@@ -1044,6 +1044,38 @@ class dataFrameAPITestScala extends TestBaseScala {
       assertEquals(expected, actual)
     }
 
+    it("Passed ST_CoordDim with 3D point") {
+      val polyDf = sparkSession.sql("SELECT ST_GeomFromWKT('POINT(1 1 2)') AS 
geom")
+      val expected = 3
+      val df = polyDf.select(ST_CoordDim("geom"))
+      val actual = df.take(1)(0).getInt(0)
+      assert(expected == actual)
+    }
+
+    it("Passed ST_CoordDim with Z coordinates") {
+      val polyDf = sparkSession.sql("SELECT ST_GeomFromWKT('POINTZ(1 1 0.5)') 
AS geom")
+      val expected = 3
+      val df = polyDf.select(ST_CoordDim("geom"))
+      val actual = df.take(1)(0).getInt(0)
+      assert(expected == actual)
+    }
+
+    it("Passed ST_CoordDim with XYM point") {
+      val polyDf = sparkSession.sql("SELECT ST_GeomFromWKT('POINT M(1 2 3)') 
AS geom")
+      val expected = 3
+      val df = polyDf.select(ST_CoordDim("geom"))
+      val actual = df.take(1)(0).getInt(0)
+      assert(expected == actual)
+    }
+
+    it("Passed ST_CoordDim with XYZM point") {
+      val polyDf = sparkSession.sql("SELECT ST_GeomFromWKT('POINT ZM(1 2 3 
4)') AS geom")
+      val expected = 4
+      val df = polyDf.select(ST_CoordDim("geom"))
+      val actual = df.take(1)(0).getInt(0)
+      assert(expected == actual)
+    }
+
     it("Passed ST_Angle - 4 Points") {
       val polyDf = sparkSession.sql("SELECT ST_GeomFromWKT('POINT (10 10)') AS 
p1, ST_GeomFromWKT('POINT (0 0)') AS p2," +
         " ST_GeomFromWKT('POINT (90 90)') AS p3, ST_GeomFromWKT('POINT (100 
80)') AS p4")
diff --git 
a/sql/common/src/test/scala/org/apache/sedona/sql/functionTestScala.scala 
b/sql/common/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
index d1a4d851..56bf832f 100644
--- a/sql/common/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
+++ b/sql/common/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
@@ -2155,6 +2155,27 @@ class functionTestScala extends TestBaseScala with 
Matchers with GeometrySample
     }
   }
 
+
+  it("Passed ST_CoordDim with 3D point") {
+    val test = sparkSession.sql("SELECT ST_CoordDim(ST_GeomFromWKT('POINT(1 1 
2)'))")
+    assert(test.take(1)(0).get(0).asInstanceOf[Int] == 3)
+  }
+
+  it("Passed ST_CoordDim with Z coordinates") {
+    val test = sparkSession.sql("SELECT ST_CoordDim(ST_GeomFromWKT('POINTZ(1 1 
0.5)'))")
+    assert(test.take(1)(0).get(0).asInstanceOf[Int] == 3)
+  }
+
+  it("Passed ST_CoordDim with XYM point") {
+    val test = sparkSession.sql("SELECT ST_CoordDim(ST_GeomFromWKT('POINT M(1 
2 3)'))")
+    assert(test.take(1)(0).get(0).asInstanceOf[Int] == 3)
+  }
+
+  it("Passed ST_CoordDim with XYZM point") {
+    val test = sparkSession.sql("SELECT ST_CoordDim(ST_GeomFromWKT('POINT ZM(1 
2 3 4)'))")
+    assert(test.take(1)(0).get(0).asInstanceOf[Int] == 4)
+  }
+
   it ("should pass GeometryType") {
     val geomTestCases = Map (
       ("'POINT (51.3168 -0.56)'") -> "'POINT'",
@@ -2172,6 +2193,7 @@ class functionTestScala extends TestBaseScala with 
Matchers with GeometrySample
         val expected = df.take(1)(0).get(1).asInstanceOf[String]
         assertEquals(expected, actual)
     }
+
   }
   
 }

Reply via email to