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

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

commit 77b400944671b074cad766d7b444ee937780f5cb
Author: Furqaan Khan <[email protected]>
AuthorDate: Fri Mar 29 01:09:18 2024 -0400

    [111] Add ST_ForceRHR (#140)
---
 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   |  8 ++++++++
 .../java/org/apache/sedona/flink/FunctionTest.java   |  8 ++++++++
 python/sedona/sql/st_functions.py                    |  9 +++++++++
 python/tests/sql/test_dataframe_api.py               |  2 ++
 python/tests/sql/test_function.py                    |  6 ++++++
 .../sedona/snowflake/snowsql/TestFunctions.java      |  9 +++++++++
 .../sedona/snowflake/snowsql/TestFunctionsV2.java    |  9 +++++++++
 .../org/apache/sedona/snowflake/snowsql/UDFs.java    |  9 +++++++++
 .../org/apache/sedona/snowflake/snowsql/UDFsV2.java  |  9 +++++++++
 .../scala/org/apache/sedona/sql/UDF/Catalog.scala    |  1 +
 .../spark/sql/sedona_sql/expressions/Functions.scala |  7 +++++++
 .../sql/sedona_sql/expressions/st_functions.scala    |  3 +++
 .../apache/sedona/sql/dataFrameAPITestScala.scala    |  7 +++++++
 .../org/apache/sedona/sql/functionTestScala.scala    |  7 +++++++
 18 files changed, 153 insertions(+)

diff --git a/docs/api/flink/Function.md b/docs/api/flink/Function.md
index 5c6b2f6f3..f3c9ffea2 100644
--- a/docs/api/flink/Function.md
+++ b/docs/api/flink/Function.md
@@ -1274,6 +1274,26 @@ Output:
 POLYGON ((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), (30 20, 20 25, 20 15, 30 
20))
 ```
 
+## ST_ForceRHR
+
+Introduction: Sets the orientation of polygon vertex orderings to follow the 
Right-Hand-Rule convention. The exterior ring will have a clockwise winding 
order, while any interior rings are oriented counter-clockwise. This ensures 
the area bounded by the polygon falls on the right-hand side relative to the 
ring directions. The function is an alias for 
[ST_ForcePolygonCW](#st_forcepolygoncw).
+
+Format: `ST_ForceRHR(geom: Geometry)`
+
+Since: `vTBD`
+
+SQL Example:
+
+```sql
+SELECT ST_AsText(ST_ForceRHR(ST_GeomFromText('POLYGON ((20 35, 10 30, 10 10, 
30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20))')))
+```
+
+Output:
+
+```
+POLYGON ((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), (30 20, 20 25, 20 15, 30 
20))
+```
+
 ## ST_FrechetDistance
 
 Introduction: Computes and returns discrete [Frechet 
Distance](https://en.wikipedia.org/wiki/Fr%C3%A9chet_distance) between the 
given two geometries,
diff --git a/docs/api/snowflake/vector-data/Function.md 
b/docs/api/snowflake/vector-data/Function.md
index 6f02aaed1..f6401d170 100644
--- a/docs/api/snowflake/vector-data/Function.md
+++ b/docs/api/snowflake/vector-data/Function.md
@@ -1005,6 +1005,24 @@ Output:
 POLYGON ((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), (30 20, 20 25, 20 15, 30 
20))
 ```
 
+## ST_ForceRHR
+
+Introduction: Sets the orientation of polygon vertex orderings to follow the 
Right-Hand-Rule convention. The exterior ring will have a clockwise winding 
order, while any interior rings are oriented counter-clockwise. This ensures 
the area bounded by the polygon falls on the right-hand side relative to the 
ring directions. The function is an alias for 
[ST_ForcePolygonCW](#st_forcepolygoncw).
+
+Format: `ST_ForceRHR(geom: Geometry)`
+
+SQL Example:
+
+```sql
+SELECT ST_AsText(ST_ForceRHR(ST_GeomFromText('POLYGON ((20 35, 10 30, 10 10, 
30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20))')))
+```
+
+Output:
+
+```
+POLYGON ((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), (30 20, 20 25, 20 15, 30 
20))
+```
+
 ## ST_FrechetDistance
 
 Introduction: Computes and returns discrete [Frechet 
Distance](https://en.wikipedia.org/wiki/Fr%C3%A9chet_distance) between the 
given two geometries,
diff --git a/docs/api/sql/Function.md b/docs/api/sql/Function.md
index 814c9c376..671d4f696 100644
--- a/docs/api/sql/Function.md
+++ b/docs/api/sql/Function.md
@@ -1279,6 +1279,26 @@ Output:
 POLYGON ((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), (30 20, 20 25, 20 15, 30 
20))
 ```
 
+## ST_ForceRHR
+
+Introduction: Sets the orientation of polygon vertex orderings to follow the 
Right-Hand-Rule convention. The exterior ring will have a clockwise winding 
order, while any interior rings are oriented counter-clockwise. This ensures 
the area bounded by the polygon falls on the right-hand side relative to the 
ring directions. The function is an alias for 
[ST_ForcePolygonCW](#st_forcepolygoncw).
+
+Format: `ST_ForceRHR(geom: Geometry)`
+
+Since: `vTBD`
+
+SQL Example:
+
+```sql
+SELECT ST_AsText(ST_ForceRHR(ST_GeomFromText('POLYGON ((20 35, 10 30, 10 10, 
30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20))')))
+```
+
+Output:
+
+```
+POLYGON ((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), (30 20, 20 25, 20 15, 30 
20))
+```
+
 ## ST_FrechetDistance
 
 Introduction: Computes and returns discrete [Frechet 
Distance](https://en.wikipedia.org/wiki/Fr%C3%A9chet_distance) between the 
given two geometries,
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 efd07c3ca..0948d0745 100644
--- a/flink/src/main/java/org/apache/sedona/flink/Catalog.java
+++ b/flink/src/main/java/org/apache/sedona/flink/Catalog.java
@@ -142,6 +142,7 @@ public class Catalog {
                 new Functions.ST_NumPoints(),
                 new Functions.ST_Force3D(),
                 new Functions.ST_ForcePolygonCW(),
+                new Functions.ST_ForceRHR(),
                 new Functions.ST_NRings(),
                 new Functions.ST_IsPolygonCCW(),
                 new Functions.ST_ForcePolygonCCW(),
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 150c2048a..c79cf867d 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
@@ -1022,6 +1022,14 @@ public class Functions {
         }
     }
 
+    public static class ST_ForceRHR 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) {
+            Geometry geometry = (Geometry) o;
+            return org.apache.sedona.common.Functions.forcePolygonCW(geometry);
+        }
+    }
+
     public static class ST_NRings extends ScalarFunction {
         @DataTypeHint(value = "Integer")
         public int eval(@DataTypeHint(value = "RAW", bridgedTo = 
org.locationtech.jts.geom.Geometry.class) Object o) throws Exception {
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 c8d1a2f2e..e9f746dde 100644
--- a/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
+++ b/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
@@ -1216,6 +1216,14 @@ public class FunctionTest extends TestBase{
         assertEquals(expectedDims, actual);
     }
 
+    @Test
+    public void testForceRHR() {
+        Table polyTable = tableEnv.sqlQuery("SELECT 
ST_ForceRHR(ST_GeomFromWKT('POLYGON ((20 35, 10 30, 10 10, 30 5, 45 20, 20 
35),(30 20, 20 15, 20 25, 30 20))')) AS polyCW");
+        String actual = (String) 
first(polyTable.select(call(Functions.ST_AsText.class.getSimpleName(), 
$("polyCW")))).getField(0);
+        String expected = "POLYGON ((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), 
(30 20, 20 25, 20 15, 30 20))";
+        assertEquals(expected, actual);
+    }
+
     @Test
     public void testForcePolygonCW() {
         Table polyTable = tableEnv.sqlQuery("SELECT 
ST_ForcePolygonCW(ST_GeomFromWKT('POLYGON ((20 35, 10 30, 10 10, 30 5, 45 20, 
20 35),(30 20, 20 15, 20 25, 30 20))')) AS polyCW");
diff --git a/python/sedona/sql/st_functions.py 
b/python/sedona/sql/st_functions.py
index dfd9ae13c..7cd9b7df7 100644
--- a/python/sedona/sql/st_functions.py
+++ b/python/sedona/sql/st_functions.py
@@ -1458,6 +1458,15 @@ def ST_ForcePolygonCW(geometry: ColumnOrName) -> Column:
     """
     return _call_st_function("ST_ForcePolygonCW", geometry)
 
+@validate_argument_types
+def ST_ForceRHR(geometry: ColumnOrName) -> Column:
+    """
+    Returns
+    :param geometry: Geometry column to change orientation
+    :return: Clockwise oriented geometry
+    """
+    return _call_st_function("ST_ForceRHR", geometry)
+
 @validate_argument_types
 def ST_NRings(geometry: ColumnOrName) -> Column:
     """
diff --git a/python/tests/sql/test_dataframe_api.py 
b/python/tests/sql/test_dataframe_api.py
index 56ec8212a..bf81c282a 100644
--- a/python/tests/sql/test_dataframe_api.py
+++ b/python/tests/sql/test_dataframe_api.py
@@ -117,6 +117,7 @@ test_configurations = [
     (stf.ST_Force3D, ("point", 1.0), "point_geom", "", "POINT Z (0 1 1)"),
     (stf.ST_ForcePolygonCW, ("geom",), "geom_with_hole", "", "POLYGON ((0 0, 3 
3, 3 0, 0 0), (1 1, 2 1, 2 2, 1 1))"),
     (stf.ST_ForcePolygonCCW, ("geom",), "geom_with_hole", "", "POLYGON ((0 0, 
3 0, 3 3, 0 0), (1 1, 2 2, 2 1, 1 1))"),
+    (stf.ST_ForceRHR, ("geom",), "geom_with_hole", "", "POLYGON ((0 0, 3 3, 3 
0, 0 0), (1 1, 2 1, 2 2, 1 1))"),
     (stf.ST_FrechetDistance, ("point", "line",), "point_and_line", "", 
5.0990195135927845),
     (stf.ST_GeometricMedian, ("multipoint",), "multipoint_geom", "", "POINT 
(22.500002656424286 21.250001168173426)"),
     (stf.ST_GeometryN, ("geom", 0), "multipoint", "", "POINT (0 0)"),
@@ -278,6 +279,7 @@ wrong_type_configurations = [
     (stf.ST_Force_2D, (None,)),
     (stf.ST_ForcePolygonCW, (None,)),
     (stf.ST_ForcePolygonCCW, (None,)),
+    (stf.ST_ForceRHR, (None,)),
     (stf.ST_GeometryN, (None, 0)),
     (stf.ST_GeometryN, ("", None)),
     (stf.ST_GeometryN, ("", 0.0)),
diff --git a/python/tests/sql/test_function.py 
b/python/tests/sql/test_function.py
index ea8497132..8635cfb8b 100644
--- a/python/tests/sql/test_function.py
+++ b/python/tests/sql/test_function.py
@@ -1374,6 +1374,12 @@ class TestPredicateJoin(TestBase):
         expected = "POLYGON ((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), (30 
20, 20 25, 20 15, 30 20))"
         assert expected == actual
 
+    def test_forceRHR(self):
+        actualDf = self.spark.sql("SELECT ST_ForceRHR(ST_GeomFromWKT('POLYGON 
((20 35, 10 30, 10 10, 30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20))')) AS 
polyCW")
+        actual = actualDf.selectExpr("ST_AsText(polyCW)").take(1)[0][0]
+        expected = "POLYGON ((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), (30 
20, 20 25, 20 15, 30 20))"
+        assert expected == actual
+
     def test_nRings(self):
         expected = 1
         actualDf = self.spark.sql("SELECT ST_GeomFromText('POLYGON ((1 0, 1 1, 
2 1, 2 0, 1 0))') AS geom")
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 a0b283156..74860ebde 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
@@ -1033,6 +1033,15 @@ public class TestFunctions extends TestBase {
         );
     }
 
+    @Test
+    public void test_ST_ForceRHR() {
+        registerUDF("ST_ForceRHR", byte[].class);
+        verifySqlSingleRes(
+                "SELECT 
sedona.ST_AsText(sedona.ST_ForceRHR(sedona.ST_GeomFromWKT('POLYGON ((20 35, 10 
30, 10 10, 30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20))')))",
+                "POLYGON ((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), (30 20, 
20 25, 20 15, 30 20))"
+        );
+    }
+
     @Test
     public void test_ST_LengthSpheroid() {
         registerUDF("ST_LengthSpheroid", byte[].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 3921b4f09..33aebf589 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
@@ -992,6 +992,15 @@ public class TestFunctionsV2
         );
     }
 
+    @Test
+    public void test_ST_ForceRHR() {
+        registerUDFV2("ST_ForceRHR", String.class);
+        verifySqlSingleRes(
+                "SELECT ST_AsText(sedona.ST_ForceRHR(ST_GeomFromWKT('POLYGON 
((20 35, 10 30, 10 10, 30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20))')))",
+                "POLYGON((20 35,45 20,30 5,10 10,10 30,20 35),(30 20,20 25,20 
15,30 20))"
+        );
+    }
+
     @Test
     public void test_ST_LengthSpheroid() {
         registerUDFV2("ST_LengthSpheroid", String.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 bad3f0c89..5546f5cc0 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
@@ -1348,6 +1348,15 @@ public class UDFs {
         );
     }
 
+    @UDFAnnotations.ParamMeta(argNames = {"geom"})
+    public static byte[] ST_ForceRHR(byte[] geom) {
+        return GeometrySerde.serialize(
+                Functions.forcePolygonCW(
+                        GeometrySerde.deserialize(geom)
+                )
+        );
+    }
+
     @UDFAnnotations.ParamMeta(argNames = {"geom"})
     public static double ST_LengthSpheroid(byte[] geom) {
         return Spheroid.length(
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 2c6ed7907..128ad2b03 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
@@ -1191,6 +1191,15 @@ public class UDFsV2
         );
     }
 
+    @UDFAnnotations.ParamMeta(argNames = {"geom"}, argTypes = {"Geometry"}, 
returnTypes = "Geometry")
+    public static String ST_ForceRHR(String geom) {
+        return GeometrySerde.serGeoJson(
+                Functions.forcePolygonCW(
+                        GeometrySerde.deserGeoJson(geom)
+                )
+        );
+    }
+
     @UDFAnnotations.ParamMeta(argNames = {"geom"}, argTypes = {"Geometry"})
     public static double ST_LengthSpheroid(String geom) {
         return Spheroid.length(
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 bd2e801ad..def481157 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
@@ -150,6 +150,7 @@ object Catalog {
     function[ST_AsEWKT](),
     function[ST_Force_2D](),
     function[ST_ForcePolygonCW](),
+    function[ST_ForceRHR](),
     function[ST_ZMax](),
     function[ST_ZMin](),
     function[ST_YMax](),
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 4b9c09c03..7e3145bdd 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
@@ -1123,6 +1123,13 @@ case class ST_ForcePolygonCW(inputExpressions: 
Seq[Expression])
   }
 }
 
+case class ST_ForceRHR(inputExpressions: Seq[Expression])
+  extends InferredExpression(Functions.forcePolygonCW _) {
+  protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) = 
{
+    copy(inputExpressions = newChildren)
+  }
+}
+
 case class ST_NRings(inputExpressions: Seq[Expression])
   extends InferredExpression(Functions.nRings _) {
   protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) = 
{
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 b78917303..166b46098 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
@@ -397,6 +397,9 @@ object st_functions extends DataFrameAPI {
   def ST_ForcePolygonCW(geometry: Column): Column = 
wrapExpression[ST_ForcePolygonCW](geometry)
   def ST_ForcePolygonCW(geometry: String): Column = 
wrapExpression[ST_ForcePolygonCW](geometry)
 
+  def ST_ForceRHR(geometry: Column): Column = 
wrapExpression[ST_ForceRHR](geometry)
+  def ST_ForceRHR(geometry: String): Column = 
wrapExpression[ST_ForceRHR](geometry)
+
   def ST_NRings(geometry: Column): Column = wrapExpression[ST_NRings](geometry)
 
   def ST_NRings(geometry: String): Column = wrapExpression[ST_NRings](geometry)
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 1ff67eeeb..4341a56ad 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
@@ -1204,6 +1204,13 @@ class dataFrameAPITestScala extends TestBaseScala {
       assertEquals(expectedGeomDefaultValue, 
wktWriter.write(actualGeomDefaultValue))
     }
 
+    it("Passed ST_ForceRHR") {
+      val baseDf = sparkSession.sql("SELECT ST_GeomFromWKT('POLYGON ((20 35, 
10 30, 10 10, 30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20))') AS poly")
+      val actual = 
baseDf.select(ST_AsText(ST_ForceRHR("poly"))).take(1)(0).get(0).asInstanceOf[String]
+      val expected = "POLYGON ((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), (30 
20, 20 25, 20 15, 30 20))"
+      assertEquals(expected, actual)
+    }
+
     it("Passed ST_ForcePolygonCW") {
       val baseDf = sparkSession.sql("SELECT ST_GeomFromWKT('POLYGON ((20 35, 
10 30, 10 10, 30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20))') AS poly")
       val actual = 
baseDf.select(ST_AsText(ST_ForcePolygonCW("poly"))).take(1)(0).get(0).asInstanceOf[String]
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 3fee1e53c..f8cb2b24d 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
@@ -948,6 +948,13 @@ class functionTestScala extends TestBaseScala with 
Matchers with GeometrySample
     assert(expected.equals(actual))
   }
 
+  it("Should pass ST_ForceRHR") {
+    val baseDf = sparkSession.sql("SELECT ST_GeomFromWKT('POLYGON ((20 35, 10 
30, 10 10, 30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20))') as poly")
+    val actual = 
baseDf.selectExpr("ST_AsText(ST_ForceRHR(poly))").first().getString(0)
+    val expected = "POLYGON ((20 35, 45 20, 30 5, 10 10, 10 30, 20 35), (30 
20, 20 25, 20 15, 30 20))"
+    assert(expected.equals(actual))
+  }
+
   it("Should pass ST_IsPolygonCW") {
     var actual = sparkSession.sql("SELECT 
ST_IsPolygonCW(ST_GeomFromWKT('POLYGON ((20 35, 10 30, 10 10, 30 5, 45 20, 20 
35),(30 20, 20 15, 20 25, 30 20))'))").first().getBoolean(0)
     assert(actual == false)

Reply via email to