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)
}
+
}
}