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 143289659 [SEDONA-654] Add ST_RotateY (#1588)
143289659 is described below
commit 143289659e1b8928ac97450cd48b91f56a2aa8a4
Author: Furqaan Khan <[email protected]>
AuthorDate: Fri Sep 13 19:19:10 2024 -0400
[SEDONA-654] Add ST_RotateY (#1588)
---
.../java/org/apache/sedona/common/Functions.java | 9 ++++++++
.../org/apache/sedona/common/FunctionsTest.java | 15 ++++++++++++
docs/api/flink/Function.md | 20 ++++++++++++++++
docs/api/snowflake/vector-data/Function.md | 18 +++++++++++++++
docs/api/sql/Function.md | 20 ++++++++++++++++
.../main/java/org/apache/sedona/flink/Catalog.java | 1 +
.../apache/sedona/flink/expressions/Functions.java | 10 ++++++++
.../java/org/apache/sedona/flink/FunctionTest.java | 16 +++++++++++++
python/sedona/sql/st_functions.py | 14 +++++++++++
python/tests/sql/test_dataframe_api.py | 1 +
python/tests/sql/test_function.py | 11 +++++++++
.../sedona/snowflake/snowsql/TestFunctions.java | 8 +++++++
.../sedona/snowflake/snowsql/TestFunctionsV2.java | 9 ++++++++
.../org/apache/sedona/snowflake/snowsql/UDFs.java | 5 ++++
.../apache/sedona/snowflake/snowsql/UDFsV2.java | 8 +++++++
.../scala/org/apache/sedona/sql/UDF/Catalog.scala | 1 +
.../sql/sedona_sql/expressions/Functions.scala | 7 ++++++
.../sql/sedona_sql/expressions/st_functions.scala | 7 ++++++
.../apache/sedona/sql/dataFrameAPITestScala.scala | 20 ++++++++++++++++
.../org/apache/sedona/sql/functionTestScala.scala | 27 ++++++++++++++++++++++
20 files changed, 227 insertions(+)
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 5c6940539..e4f2a088c 100644
--- a/common/src/main/java/org/apache/sedona/common/Functions.java
+++ b/common/src/main/java/org/apache/sedona/common/Functions.java
@@ -2230,6 +2230,15 @@ public class Functions {
return affine(geometry, 1, 0, 0, 0, cosAngle, -sinAngle, 0, sinAngle,
cosAngle, 0, 0, 0);
}
+ public static Geometry rotateY(Geometry geometry, double angle) {
+ if (GeomUtils.isAnyGeomEmpty(geometry)) {
+ return geometry;
+ }
+ double sinAngle = Math.sin(angle);
+ double cosAngle = Math.cos(angle);
+ return affine(geometry, cosAngle, 0, sinAngle, 0, 1, 0, -sinAngle, 0,
cosAngle, 0, 0, 0);
+ }
+
/**
* Rotates a geometry by a given angle in radians.
*
diff --git a/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
b/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
index e6284097b..b22e09e19 100644
--- a/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
+++ b/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
@@ -3951,6 +3951,21 @@ public class FunctionsTest extends TestBase {
assertEquals(expected, actual);
}
+ @Test
+ public void rotateY() throws ParseException {
+ Geometry lineString = Constructors.geomFromEWKT("LINESTRING (50 160, 50
50, 100 50)");
+ String actual = Functions.asEWKT(Functions.rotateY(lineString, Math.PI));
+ String expected = "LINESTRING (-50 160, -50 50, -100 50)";
+ assertEquals(expected, actual);
+
+ lineString = Constructors.geomFromWKT("LINESTRING(1 2 3, 1 1 1)", 1234);
+ Geometry geomActual = Functions.rotateY(lineString, Math.PI / 2);
+ actual = Functions.asWKT(geomActual);
+ expected = "LINESTRING Z(3 2 -0.9999999999999998, 1 1
-0.9999999999999999)";
+ assertEquals(1234, geomActual.getSRID());
+ assertEquals(expected, actual);
+ }
+
@Test
public void rotate() throws ParseException {
Geometry lineString = Constructors.geomFromEWKT("LINESTRING (50 160, 50
50, 100 50)");
diff --git a/docs/api/flink/Function.md b/docs/api/flink/Function.md
index be24e51d0..b5c11c37a 100644
--- a/docs/api/flink/Function.md
+++ b/docs/api/flink/Function.md
@@ -3321,6 +3321,26 @@ Output:
SRID=4326;POLYGON ((0 0, 1 0, 1 -0.8390715290764524, 0 0))
```
+## ST_RotateY
+
+Introduction: Performs a counter-clockwise rotation of the specified geometry
around the Y-axis by the given angle measured in radians.
+
+Format: `ST_RotateY(geometry: Geometry, angle: Double)`
+
+Since: `v1.7.0`
+
+SQL Example:
+
+```sql
+SELECT ST_RotateY(ST_GeomFromEWKT('SRID=4326;POLYGON ((0 0, 1 0, 1 1, 0 0))'),
10)
+```
+
+Output:
+
+```
+SRID=4326;POLYGON ((0 0, -0.8390715290764524 0, -0.8390715290764524 1, 0 0))
+```
+
## ST_S2CellIDs
Introduction: Cover the geometry with Google S2 Cells, return the
corresponding cell IDs with the given level.
diff --git a/docs/api/snowflake/vector-data/Function.md
b/docs/api/snowflake/vector-data/Function.md
index 7a3e68ae9..7848f7bcf 100644
--- a/docs/api/snowflake/vector-data/Function.md
+++ b/docs/api/snowflake/vector-data/Function.md
@@ -2558,6 +2558,24 @@ Output:
SRID=4326;POLYGON ((0 0, 1 0, 1 -0.8390715290764524, 0 0))
```
+## ST_RotateY
+
+Introduction: Performs a counter-clockwise rotation of the specified geometry
around the Y-axis by the given angle measured in radians.
+
+Format: `ST_RotateY(geometry: Geometry, angle: Double)`
+
+SQL Example:
+
+```sql
+SELECT ST_RotateY(ST_GeomFromEWKT('SRID=4326;POLYGON ((0 0, 1 0, 1 1, 0 0))'),
10)
+```
+
+Output:
+
+```
+SRID=4326;POLYGON ((0 0, -0.8390715290764524 0, -0.8390715290764524 1, 0 0))
+```
+
## ST_S2CellIDs
Introduction: Cover the geometry with Google S2 Cells, return the
corresponding cell IDs with the given level.
diff --git a/docs/api/sql/Function.md b/docs/api/sql/Function.md
index 8d3e437c8..46063b9c7 100644
--- a/docs/api/sql/Function.md
+++ b/docs/api/sql/Function.md
@@ -3401,6 +3401,26 @@ Output:
SRID=4326;POLYGON ((0 0, 1 0, 1 -0.8390715290764524, 0 0))
```
+## ST_RotateY
+
+Introduction: Performs a counter-clockwise rotation of the specified geometry
around the Y-axis by the given angle measured in radians.
+
+Format: `ST_RotateY(geometry: Geometry, angle: Double)`
+
+Since: `v1.7.0`
+
+SQL Example:
+
+```sql
+SELECT ST_RotateY(ST_GeomFromEWKT('SRID=4326;POLYGON ((0 0, 1 0, 1 1, 0 0))'),
10)
+```
+
+Output:
+
+```
+SRID=4326;POLYGON ((0 0, -0.8390715290764524 0, -0.8390715290764524 1, 0 0))
+```
+
## ST_S2CellIDs
Introduction: Cover the geometry with Google S2 Cells, return the
corresponding cell IDs with the given level.
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 08bc209b0..61d88a5c0 100644
--- a/flink/src/main/java/org/apache/sedona/flink/Catalog.java
+++ b/flink/src/main/java/org/apache/sedona/flink/Catalog.java
@@ -104,6 +104,7 @@ public class Catalog {
new Functions.ST_Reverse(),
new Functions.ST_Rotate(),
new Functions.ST_RotateX(),
+ new Functions.ST_RotateY(),
new Functions.ST_GeometryN(),
new Functions.ST_InteriorRingN(),
new Functions.ST_PointN(),
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 7f8404024..38e41fce2 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
@@ -1954,6 +1954,16 @@ public class Functions {
}
}
+ public static class ST_RotateY extends ScalarFunction {
+ @DataTypeHint(value = "RAW", bridgedTo =
org.locationtech.jts.geom.Geometry.class)
+ public Geometry eval(
+ @DataTypeHint(value = "RAW", bridgedTo =
org.locationtech.jts.geom.Geometry.class) Object o,
+ @DataTypeHint(value = "Double") Double angle) {
+ Geometry geom = (Geometry) o;
+ return org.apache.sedona.common.Functions.rotateY(geom, angle);
+ }
+ }
+
public static class ST_Rotate extends ScalarFunction {
@DataTypeHint(value = "RAW", bridgedTo =
org.locationtech.jts.geom.Geometry.class)
public Geometry eval(
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 1b07834a3..e08813da7 100644
--- a/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
+++ b/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
@@ -2644,6 +2644,22 @@ public class FunctionTest extends TestBase {
assertEquals(expected, actual);
}
+ @Test
+ public void testRotateY() {
+ Table tbl =
+ tableEnv.sqlQuery(
+ "SELECT ST_GeomFromEWKT('POLYGON ((0 0, 2 0, 1 1, 2 2, 0 2, 1 1, 0
0))') AS geom");
+ String actual =
+ (String)
+ first(
+
tbl.select(call(Functions.ST_RotateY.class.getSimpleName(), $("geom"), Math.PI))
+ .as("geom")
+
.select(call(Functions.ST_AsEWKT.class.getSimpleName(), $("geom"))))
+ .getField(0);
+ String expected = "POLYGON ((0 0, -2 0, -1 1, -2 2, 0 2, -1 1, 0 0))";
+ assertEquals(expected, actual);
+ }
+
@Test
public void testRotate() {
Table tbl =
diff --git a/python/sedona/sql/st_functions.py
b/python/sedona/sql/st_functions.py
index 96a47684f..fccc1c565 100644
--- a/python/sedona/sql/st_functions.py
+++ b/python/sedona/sql/st_functions.py
@@ -2050,6 +2050,20 @@ def ST_RotateX(geometry: ColumnOrName, angle:
Union[ColumnOrName, float]) -> Col
return _call_st_function("ST_RotateX", (geometry, angle))
+@validate_argument_types
+def ST_RotateY(geometry: ColumnOrName, angle: Union[ColumnOrName, float]) ->
Column:
+ """Returns geometry rotated by the given angle in Y axis
+
+ @param geometry: Geometry column or name
+ :type geometry: ColumnOrName
+ @param angle: Rotation angle in radians
+ :type angle: float
+ @return: Y-axis rotated geometry
+ """
+
+ return _call_st_function("ST_RotateY", (geometry, angle))
+
+
@validate_argument_types
def ST_Rotate(geometry: ColumnOrName, angle: Union[ColumnOrName, float],
originX: Union[ColumnOrName, float] = None,
originY: Union[ColumnOrName, float] = None, pointOrigin:
ColumnOrName = None) -> Column:
diff --git a/python/tests/sql/test_dataframe_api.py
b/python/tests/sql/test_dataframe_api.py
index 913e97e42..08fa955f7 100644
--- a/python/tests/sql/test_dataframe_api.py
+++ b/python/tests/sql/test_dataframe_api.py
@@ -210,6 +210,7 @@ test_configurations = [
(stf.ST_RemoveRepeatedPoints, ("geom",), "repeated_multipoint", "",
"MULTIPOINT (1 1, 2 2, 3 3, 4 4)"),
(stf.ST_Reverse, ("line",), "linestring_geom", "", "LINESTRING (5 0, 4 0,
3 0, 2 0, 1 0, 0 0)"),
(stf.ST_RotateX, ("line", 10.0), "4D_line", "ST_ReducePrecision(geom, 2)",
"LINESTRING Z (1 -0.3 -1.383092639965822, 2 -0.59 -2.766185279931644, 3 -0.89
-4.149277919897466, -1 0.3 1.383092639965822)"),
+ (stf.ST_RotateY, ("line", 10.0), "4D_line",
"ST_AsText(ST_ReducePrecision(geom, 2))", "LINESTRING ZM(-1.38 1
-0.2950504181870827 1, -2.77 2 -0.5901008363741653 2, -4.15 3
-0.8851512545612479 3, 1.38 -1 0.2950504181870827 -1)"),
(stf.ST_Rotate, ("line", 10.0), "linestring_geom",
"ST_ReducePrecision(geom, 2)", "LINESTRING (0 0, -0.84 -0.54, -1.68 -1.09,
-2.52 -1.63, -3.36 -2.18, -4.2 -2.72)"),
(stf.ST_Rotate, ("line", 10.0, 0.0, 0.0), "linestring_geom",
"ST_ReducePrecision(geom, 2)", "LINESTRING (0 0, -0.84 -0.54, -1.68 -1.09,
-2.52 -1.63, -3.36 -2.18, -4.2 -2.72)"),
(stf.ST_S2CellIDs, ("point", 30), "point_geom", "", [1153451514845492609]),
diff --git a/python/tests/sql/test_function.py
b/python/tests/sql/test_function.py
index b42e8c156..f139c6963 100644
--- a/python/tests/sql/test_function.py
+++ b/python/tests/sql/test_function.py
@@ -960,6 +960,17 @@ class TestPredicateJoin(TestBase):
expected = "LINESTRING Z (1 -3 2, 1 -0.9999999999999999 1)"
assert expected == actual
+ def test_st_rotate_y(self):
+ baseDf = self.spark.sql("SELECT ST_GeomFromWKT('LINESTRING (50 160, 50
50, 100 50)') as geom1, ST_GeomFromWKT('LINESTRING(1 2 3, 1 1 1)') AS geom2")
+
+ actual = baseDf.selectExpr("ST_RotateY(geom1, PI())").first()[0].wkt
+ expected = "LINESTRING (-50 160, -50 50, -100 50)"
+ assert expected == actual
+
+ actual = baseDf.selectExpr("ST_RotateY(geom2, PI() /
2)").first()[0].wkt
+ expected = "LINESTRING Z (3 2 -0.9999999999999998, 1 1
-0.9999999999999999)"
+ assert expected == actual
+
def test_st_remove_point(self):
result_and_expected = [
[self.calculate_st_remove("Linestring(0 0, 1 1, 1 0, 0 0)", 0),
"LINESTRING (1 1, 1 0, 0 0)"],
diff --git
a/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctions.java
b/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctions.java
index 3e2eebabf..40bc28b8b 100644
---
a/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctions.java
+++
b/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctions.java
@@ -1227,6 +1227,14 @@ public class TestFunctions extends TestBase {
"LINESTRING (0 0, 1 0, 1 -0.8390715290764524, 0 0)");
}
+ @Test
+ public void test_ST_RotateY() {
+ registerUDF("ST_RotateY", byte[].class, double.class);
+ verifySqlSingleRes(
+ "SELECT
sedona.ST_AsText(sedona.ST_RotateY(sedona.ST_GeomFromWKT('LINESTRING (0 0, 1 0,
1 1, 0 0)'), 10))",
+ "LINESTRING (0 0, -0.8390715290764524 0, -0.8390715290764524 1, 0 0)");
+ }
+
@Test
public void test_ST_Rotate() {
registerUDF("ST_Rotate", byte[].class, double.class);
diff --git
a/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctionsV2.java
b/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctionsV2.java
index a8675eba0..b3c21f7c0 100644
---
a/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctionsV2.java
+++
b/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestFunctionsV2.java
@@ -1183,6 +1183,15 @@ public class TestFunctionsV2 extends TestBase {
"LINESTRING(0 0,1 0,1 -0.84,0 0)");
}
+ @Test
+ public void test_ST_RotateY() {
+ registerUDFV2("ST_RotateY", String.class, double.class);
+ registerUDFV2("ST_ReducePrecision", String.class, int.class);
+ verifySqlSingleRes(
+ "select
ST_AsText(ST_ReducePrecision(sedona.ST_RotateY(ST_GeometryFromWKT('LINESTRING
(0 0, 1 0, 1 1, 0 0)'), 10),2))",
+ "LINESTRING(0 0,-0.84 0,-0.84 1,0 0)");
+ }
+
@Test
public void test_ST_Rotate() {
registerUDFV2("ST_Rotate", String.class, double.class);
diff --git
a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFs.java
b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFs.java
index 2f6d1ef01..a5622039e 100644
--- a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFs.java
+++ b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFs.java
@@ -1277,6 +1277,11 @@ public class UDFs {
return
GeometrySerde.serialize(Functions.rotateX(GeometrySerde.deserialize(geometry),
angle));
}
+ @UDFAnnotations.ParamMeta(argNames = {"geometry", "angle"})
+ public static byte[] ST_RotateY(byte[] geometry, double angle) {
+ return
GeometrySerde.serialize(Functions.rotateY(GeometrySerde.deserialize(geometry),
angle));
+ }
+
@UDFAnnotations.ParamMeta(argNames = {"geom", "angle"})
public static byte[] ST_Rotate(byte[] geom, double angle) {
return
GeometrySerde.serialize(Functions.rotate(GeometrySerde.deserialize(geom),
angle));
diff --git
a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFsV2.java
b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFsV2.java
index 089d4002e..75109cb4a 100644
--- a/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFsV2.java
+++ b/snowflake/src/main/java/org/apache/sedona/snowflake/snowsql/UDFsV2.java
@@ -1516,6 +1516,14 @@ public class UDFsV2 {
return
GeometrySerde.serGeoJson(Functions.rotateX(GeometrySerde.deserGeoJson(geometry),
angle));
}
+ @UDFAnnotations.ParamMeta(
+ argNames = {"geometry", "angle"},
+ argTypes = {"Geometry", "double"},
+ returnTypes = "Geometry")
+ public static String ST_RotateY(String geometry, double angle) {
+ return
GeometrySerde.serGeoJson(Functions.rotateY(GeometrySerde.deserGeoJson(geometry),
angle));
+ }
+
@UDFAnnotations.ParamMeta(
argNames = {"geom", "angle"},
argTypes = {"Geometry", "double"},
diff --git
a/spark/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
b/spark/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
index 1e336739b..80ffdabb7 100644
--- a/spark/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
+++ b/spark/common/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
@@ -234,6 +234,7 @@ object Catalog {
function[ST_IsValidReason](),
function[ST_Rotate](),
function[ST_RotateX](),
+ function[ST_RotateY](),
// Expression for rasters
function[RS_NormalizedDifference](),
function[RS_Mean](),
diff --git
a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
index ce6500ede..0e64d5930 100644
---
a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
+++
b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Functions.scala
@@ -1715,6 +1715,13 @@ case class ST_RotateX(inputExpressions: Seq[Expression])
copy(inputExpressions = newChildren)
}
+case class ST_RotateY(inputExpressions: Seq[Expression])
+ extends InferredExpression(inferrableFunction2(Functions.rotateY)) {
+
+ protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) =
+ copy(inputExpressions = newChildren)
+}
+
case class ST_Rotate(inputExpressions: Seq[Expression])
extends InferredExpression(
inferrableFunction2(Functions.rotate),
diff --git
a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_functions.scala
b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_functions.scala
index d1c94b126..0101978b1 100644
---
a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_functions.scala
+++
b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_functions.scala
@@ -490,6 +490,13 @@ object st_functions extends DataFrameAPI {
def ST_RotateX(geometry: String, angle: String): Column =
wrapExpression[ST_RotateX](geometry, angle)
+ def ST_RotateY(geometry: Column, angle: Column): Column =
+ wrapExpression[ST_RotateY](geometry, angle)
+ def ST_RotateY(geometry: String, angle: Double): Column =
+ wrapExpression[ST_RotateY](geometry, angle)
+ def ST_RotateY(geometry: String, angle: String): Column =
+ wrapExpression[ST_RotateY](geometry, angle)
+
def ST_Rotate(geometry: Column, angle: Column): Column =
wrapExpression[ST_Rotate](geometry, angle)
def ST_Rotate(geometry: String, angle: Double): Column =
diff --git
a/spark/common/src/test/scala/org/apache/sedona/sql/dataFrameAPITestScala.scala
b/spark/common/src/test/scala/org/apache/sedona/sql/dataFrameAPITestScala.scala
index f37849b3c..2f8faeb0c 100644
---
a/spark/common/src/test/scala/org/apache/sedona/sql/dataFrameAPITestScala.scala
+++
b/spark/common/src/test/scala/org/apache/sedona/sql/dataFrameAPITestScala.scala
@@ -2282,6 +2282,26 @@ class dataFrameAPITestScala extends TestBaseScala {
}
}
+ it("Should pass ST_RotateY") {
+ val geomTestCases = Map(
+ (
+ 1,
+ "'LINESTRING (50 160, 50 50, 100 50)'",
+ Math.PI) -> "'LINESTRING (-50 160, -50 50, -100 50)'",
+ (
+ 2,
+ "'LINESTRING(1 2 3, 1 1 1)'",
+ Math.PI / 2) -> "LINESTRING Z(3 2 -0.9999999999999998, 1 1
-0.9999999999999999)")
+
+ for (((index, geom, angle), expectedResult) <- geomTestCases) {
+ val baseDf = sparkSession.sql(s"SELECT ST_GeomFromEWKT($geom) as geom")
+ val df = baseDf.select(ST_AsEWKT(ST_RotateY("geom", angle)))
+
+ val actual = df.take(1)(0).get(0).asInstanceOf[String]
+ assert(actual == expectedResult.stripPrefix("'").stripSuffix("'"))
+ }
+ }
+
it("Passed ST_Rotate") {
val baseDf = sparkSession.sql(
"SELECT ST_GeomFromEWKT('SRID=4326;POLYGON ((0 0, 2 0, 2 2, 0 2, 1 1,
0 0))') AS geom1, ST_GeomFromText('POINT (2 2)') AS geom2")
diff --git
a/spark/common/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
b/spark/common/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
index fcbb45d9d..cb034376f 100644
--- a/spark/common/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
+++ b/spark/common/src/test/scala/org/apache/sedona/sql/functionTestScala.scala
@@ -3459,6 +3459,33 @@ class functionTestScala
}
}
+ it("Should pass ST_RotateY") {
+ val geomTestCases = Map(
+ (
+ 1,
+ "'LINESTRING (50 160, 50 50, 100 50)'",
+ "PI()") -> "'LINESTRING (-50 160, -50 50, -100 50)'",
+ (
+ 2,
+ "'LINESTRING(1 2 3, 1 1 1)'",
+ "PI()/2") -> "LINESTRING Z(3 2 -0.9999999999999998, 1 1
-0.9999999999999999)")
+
+ for (((index, geom, angle), expectedResult) <- geomTestCases) {
+ val df = sparkSession.sql(s"""
+ |SELECT
+ | ST_AsEWKT(
+ | ST_RotateY(
+ | ST_GeomFromEWKT($geom),
+ | $angle
+ | )
+ | ) AS geom
+ """.stripMargin)
+
+ val actual = df.take(1)(0).get(0).asInstanceOf[String]
+ assert(actual == expectedResult.stripPrefix("'").stripSuffix("'"))
+ }
+ }
+
it("Should pass ST_Rotate") {
val geomTestCases = Map(
(