This is an automated email from the ASF dual-hosted git repository. jiayu pushed a commit to branch SEDONA-589 in repository https://gitbox.apache.org/repos/asf/sedona.git
commit efc296d1e1e4dc39820a9fded0a1238df2d65a58 Author: Furqaan Khan <[email protected]> AuthorDate: Thu Apr 25 22:42:37 2024 -0400 [TASK-32] Add ST_LongestLine (#169) * temp commit * Revert "temp commit" This reverts commit 8cd8ecc6b3ae533379b779ba08c23b12df47e2fc. * feat: Add ST_LongestLine --- .../java/org/apache/sedona/common/Functions.java | 18 ++++++++++++ .../org/apache/sedona/common/FunctionsTest.java | 32 ++++++++++++++++++++++ docs/api/flink/Function.md | 23 ++++++++++++++++ docs/api/snowflake/vector-data/Function.md | 21 ++++++++++++++ docs/api/sql/Function.md | 23 ++++++++++++++++ .../main/java/org/apache/sedona/flink/Catalog.java | 1 + .../apache/sedona/flink/expressions/Functions.java | 10 +++++++ .../java/org/apache/sedona/flink/FunctionTest.java | 10 +++++++ python/sedona/sql/st_functions.py | 13 +++++++++ python/tests/sql/test_dataframe_api.py | 4 +++ python/tests/sql/test_function.py | 6 ++++ .../sedona/snowflake/snowsql/TestFunctions.java | 9 ++++++ .../sedona/snowflake/snowsql/TestFunctionsV2.java | 10 +++++++ .../org/apache/sedona/snowflake/snowsql/UDFs.java | 11 ++++++++ .../apache/sedona/snowflake/snowsql/UDFsV2.java | 10 +++++++ .../scala/org/apache/sedona/sql/UDF/Catalog.scala | 1 + .../sql/sedona_sql/expressions/Functions.scala | 8 ++++++ .../sql/sedona_sql/expressions/st_functions.scala | 3 ++ .../apache/sedona/sql/dataFrameAPITestScala.scala | 7 +++++ .../org/apache/sedona/sql/functionTestScala.scala | 7 +++++ 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 ac88ce04f..5025fd19f 100644 --- a/common/src/main/java/org/apache/sedona/common/Functions.java +++ b/common/src/main/java/org/apache/sedona/common/Functions.java @@ -1062,6 +1062,24 @@ public class Functions { return isExteriorRingCCW && isInteriorRingCCW; } + public static Geometry longestLine(Geometry geom1, Geometry geom2) { + double maxLength = 0; + Coordinate longestStart = null; + Coordinate longestEnd = null; + + for (Coordinate coord1: geom1.getCoordinates()) { + for (Coordinate coord2: geom2.getCoordinates()) { + double length = coord1.distance(coord2); + if (length > maxLength) { + maxLength = length; + longestStart = coord1; + longestEnd = coord2; + } + } + } + return geom1.getFactory().createLineString(new Coordinate[] {longestStart, longestEnd}); + } + public static Geometry difference(Geometry leftGeometry, Geometry rightGeometry) { boolean isIntersects = leftGeometry.intersects(rightGeometry); if (!isIntersects) { 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 017f65e64..ab0ebe0db 100644 --- a/common/src/test/java/org/apache/sedona/common/FunctionsTest.java +++ b/common/src/test/java/org/apache/sedona/common/FunctionsTest.java @@ -1012,6 +1012,38 @@ public class FunctionsTest extends TestBase { assertEquals("Median failed to converge within 1.0E-06 after 5 iterations.", e.getMessage()); } + @Test + public void longestLine() throws ParseException { + Geometry geom1 = Constructors.geomFromWKT("POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))", 0); + Geometry geom2 = Functions.buffer(Constructors.geomFromWKT("POINT (10.123456 -20.654321)", 0), 30); + String actual = Functions.asWKT(Functions.longestLine(geom1, geom2)); + String expected = "LINESTRING (40 40, -1.3570469709526929 -48.37070697533861)"; + assertEquals(expected, actual); + + geom1 = Constructors.geomFromWKT("POLYGON ((190 150, 20 10, 160 70, 190 150))", 0); + geom2 = Constructors.geomFromWKT("POINT(80 160)", 0); + actual = Functions.asWKT(Functions.reducePrecision(Functions.longestLine(geom1, Functions.buffer(geom2, 30)), 8)); + expected = "LINESTRING (20 10, 91.48050297 187.71638598)"; + assertEquals(expected, actual); + + geom1 = Constructors.geomFromWKT("POINT (160 40)", 0); + geom2 = Constructors.geomFromWKT("LINESTRING (10 30, 50 50, 30 110, 70 90, 180 140, 130 190)", 0); + actual = Functions.asWKT(Functions.longestLine(geom1, geom2)); + expected = "LINESTRING (160 40, 130 190)"; + assertEquals(expected, actual); + + geom1 = Constructors.geomFromWKT("POLYGON ((40 180, 110 160, 180 180, 180 120, 140 90, 160 40, 80 10, 70 40, 20 50, 40 180),(60 140, 99 77.5, 90 140, 60 140))", 0); + actual = Functions.asWKT(Functions.normalize(Functions.longestLine(geom1, geom1))); + expected = "LINESTRING (20 50, 180 180)"; + assertEquals(expected, actual); + + geom1 = Constructors.geomFromWKT("POINT Z (10 20 5)", 0); + geom2 = Constructors.geomFromWKT("POLYGON Z ((30 40 10, 40 50 15, 50 60 20, 30 40 10))", 0); + actual = Functions.asWKT(Functions.longestLine(geom1, geom2)); + expected = "LINESTRING Z(10 20 5, 50 60 20)"; + assertEquals(expected, actual); + } + @Test public void makepolygonWithSRID() { Geometry lineString1 = GEOMETRY_FACTORY.createLineString(coordArray(0, 0, 1, 1, 1, 0, 0, 0)); diff --git a/docs/api/flink/Function.md b/docs/api/flink/Function.md index 9a51cae82..7653b709c 100644 --- a/docs/api/flink/Function.md +++ b/docs/api/flink/Function.md @@ -2184,6 +2184,29 @@ Output: LINESTRING (69.28469348539744 94.28469348539744, 100 125, 111.70035626068274 140.21046313888758) ``` +## ST_LongestLine + +Introduction: Returns the LineString geometry representing the maximum distance between any two points from the input geometries. + +Format: `ST_LongestLine(geom1: Geometry, geom2: Geometry)` + +Since: `vTBD` + +SQL Example: + +```sql +SELECT ST_LongestLine( + ST_GeomFromText("POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))"), + ST_GeomFromText("POLYGON ((10 20, 30 30, 40 20, 30 10, 10 20))") +) +``` + +Output: + +``` +LINESTRING (40 40, 10 20) +``` + ## ST_M Introduction: Returns M Coordinate of given Point, null otherwise. diff --git a/docs/api/snowflake/vector-data/Function.md b/docs/api/snowflake/vector-data/Function.md index 0da9461f0..95e41d2ca 100644 --- a/docs/api/snowflake/vector-data/Function.md +++ b/docs/api/snowflake/vector-data/Function.md @@ -1636,6 +1636,27 @@ SQL example: SELECT ST_LineSubstring(ST_GeomFromWKT('LINESTRING(25 50, 100 125, 150 190)'), 0.333, 0.666) as Substring ``` +## ST_LongestLine + +Introduction: Returns the LineString geometry representing the maximum distance between any two points from the input geometries. + +Format: `ST_LongestLine(geom1: Geometry, geom2: Geometry)` + +SQL Example: + +```sql +SELECT ST_LongestLine( + ST_GeomFromText("POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))"), + ST_GeomFromText("POLYGON ((10 20, 30 30, 40 20, 30 10, 10 20))") +) +``` + +Output: + +``` +LINESTRING (40 40, 10 20) +``` + Output: ``` diff --git a/docs/api/sql/Function.md b/docs/api/sql/Function.md index 9a7a3eafe..9587b8cbe 100644 --- a/docs/api/sql/Function.md +++ b/docs/api/sql/Function.md @@ -2191,6 +2191,29 @@ Output: LINESTRING (69.28469348539744 94.28469348539744, 100 125, 111.70035626068274 140.21046313888758) ``` +## ST_LongestLine + +Introduction: Returns the LineString geometry representing the maximum distance between any two points from the input geometries. + +Format: `ST_LongestLine(geom1: Geometry, geom2: Geometry)` + +Since: `vTBD` + +SQL Example: + +```sql +SELECT ST_LongestLine( + ST_GeomFromText("POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))"), + ST_GeomFromText("POLYGON ((10 20, 30 30, 40 20, 30 10, 10 20))") +) +``` + +Output: + +``` +LINESTRING (40 40, 10 20) +``` + ## ST_M Introduction: Returns M Coordinate of given Point, null otherwise. 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 df8c86186..91705e59c 100644 --- a/flink/src/main/java/org/apache/sedona/flink/Catalog.java +++ b/flink/src/main/java/org/apache/sedona/flink/Catalog.java @@ -82,6 +82,7 @@ public class Catalog { new Functions.ST_LengthSpheroid(), new Functions.ST_LineInterpolatePoint(), new Functions.ST_LineLocatePoint(), + new Functions.ST_LongestLine(), new FunctionsGeoTools.ST_Transform(), new Functions.ST_FlipCoordinates(), new Functions.ST_GeoHash(), 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 c1e031b83..dcc36b029 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 @@ -354,6 +354,16 @@ public class Functions { } } + public static class ST_LongestLine 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 g1, + @DataTypeHint(value = "RAW", bridgedTo = org.locationtech.jts.geom.Geometry.class) Object g2) { + Geometry geom1 = (Geometry) g1; + Geometry geom2 = (Geometry) g2; + return org.apache.sedona.common.Functions.longestLine(geom1, geom2); + } + } + public static class ST_YMin extends ScalarFunction { @DataTypeHint("Double") public Double eval(@DataTypeHint(value = "RAW", bridgedTo = org.locationtech.jts.geom.Geometry.class) Object o){ 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 6db3f9493..c1e0bff00 100644 --- a/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java +++ b/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java @@ -444,6 +444,16 @@ public class FunctionTest extends TestBase{ assertEquals(expected, actual, 0.1); } + @Test + public void testLongestLine() { + Table tbl = tableEnv.sqlQuery( + "SELECT ST_GeomFromWKT('POLYGON ((40 180, 110 160, 180 180, 180 120, 140 90, 160 40, 80 10, 70 40, 20 50, 40 180),(60 140, 99 77.5, 90 140, 60 140))') as geom1"); + String actual = (String) first(tbl.select(call(Functions.ST_LongestLine.class.getSimpleName(), $("geom1"), $("geom1"))).as("geom") + .select(call(Functions.ST_AsText.class.getSimpleName(), $("geom")))).getField(0); + String expected = "LINESTRING (180 180, 20 50)"; + assertEquals(expected, actual); + } + @Test public void testLineInterpolatePoint() { Table table = tableEnv.sqlQuery("SELECT ST_GeomFromWKT('LINESTRING (0 0, 2 0)') AS line"); diff --git a/python/sedona/sql/st_functions.py b/python/sedona/sql/st_functions.py index 82ca9c2fe..f38c0cebf 100644 --- a/python/sedona/sql/st_functions.py +++ b/python/sedona/sql/st_functions.py @@ -881,6 +881,19 @@ def ST_LineSubstring(line_string: ColumnOrName, start_fraction: ColumnOrNameOrNu """ return _call_st_function("ST_LineSubstring", (line_string, start_fraction, end_fraction)) +@validate_argument_types +def ST_LongestLine(geom1: ColumnOrName, geom2: ColumnOrName) -> Column: + """Compute the longest line between the two geometries + + :param geom1: + :type geom1: ColumnOrName + :param geom2: + :type geom2: ColumnOrName + :return: Longest line between the two input geometries + :rtype: Column + """ + return _call_st_function("ST_LongestLine", (geom1, geom2)) + @validate_argument_types def ST_HasZ(geom: ColumnOrName) -> Column: """Check whether geometry has Z coordinate diff --git a/python/tests/sql/test_dataframe_api.py b/python/tests/sql/test_dataframe_api.py index 42818f07f..3bb66493e 100644 --- a/python/tests/sql/test_dataframe_api.py +++ b/python/tests/sql/test_dataframe_api.py @@ -154,6 +154,7 @@ test_configurations = [ (stf.ST_LineLocatePoint, ("line", "point"), "line_and_point", "", 0.5), (stf.ST_LineMerge, ("geom",), "multiline_geom", "", "LINESTRING (0 0, 1 0, 1 1, 0 0)"), (stf.ST_LineSubstring, ("line", 0.5, 1.0), "linestring_geom", "", "LINESTRING (2.5 0, 3 0, 4 0, 5 0)"), + (stf.ST_LongestLine, ("geom", "geom"), "geom_collection", "", "LINESTRING (0 0, 1 0)"), (stf.ST_HasZ, ("a",), "two_points", "", True), (stf.ST_HasM, ("point",), "4D_point", "", True), (stf.ST_M, ("point",), "4D_point", "", 4.0), @@ -337,6 +338,9 @@ wrong_type_configurations = [ (stf.ST_LineSubstring, (None, 0.5, 1.0)), (stf.ST_LineSubstring, ("", None, 1.0)), (stf.ST_LineSubstring, ("", 0.5, None)), + (stf.ST_LongestLine, (None, "")), + (stf.ST_LongestLine, (None, None)), + (stf.ST_LongestLine, ("", None)), (stf.ST_HasZ, (None,)), (stf.ST_HasM, (None,)), (stf.ST_M, (None,)), diff --git a/python/tests/sql/test_function.py b/python/tests/sql/test_function.py index 7686eb81a..73897126b 100644 --- a/python/tests/sql/test_function.py +++ b/python/tests/sql/test_function.py @@ -1386,6 +1386,12 @@ class TestPredicateJoin(TestBase): "select ST_AsText(ST_LineFromMultiPoint(ST_GeomFromText({})))".format(input_geom)) assert line_geometry.take(1)[0][0] == expected_geom + def test_st_longest_line(self): + basedf = self.spark.sql("SELECT ST_GeomFromWKT('POLYGON ((40 180, 110 160, 180 180, 180 120, 140 90, 160 40, 80 10, 70 40, 20 50, 40 180),(60 140, 99 77.5, 90 140, 60 140))') as geom") + actual = basedf.selectExpr("ST_AsText(ST_LongestLine(geom, geom))").take(1)[0][0] + expected = "LINESTRING (180 180, 20 50)" + assert expected == actual + def test_st_s2_cell_ids(self): test_cases = [ "'POLYGON((-1 0, 1 0, 0 0, 0 1, -1 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 c0842d36b..7d0e0e19a 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 @@ -590,6 +590,15 @@ public class TestFunctions extends TestBase { ); } + @Test + public void test_ST_LongestLine() { + registerUDF("ST_LongestLine", byte[].class, byte[].class); + verifySqlSingleRes( + "SELECT sedona.ST_AsText(sedona.ST_LongestLine(sedona.ST_GeomFromWKT('POLYGON ((40 180, 110 160, 180 180, 180 120, 140 90, 160 40, 80 10, 70 40, 20 50, 40 180),(60 140, 99 77.5, 90 140, 60 140))'), sedona.ST_GeomFromWKT('POLYGON ((40 180, 110 160, 180 180, 180 120, 140 90, 160 40, 80 10, 70 40, 20 50, 40 180),(60 140, 99 77.5, 90 140, 60 140))')))", + "LINESTRING (180 180, 20 50)" + ); + } + @Test public void test_ST_MakeLine() { registerUDF("ST_MakeLine", byte[].class, 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 350ccbace..2154027f2 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 @@ -590,6 +590,16 @@ public class TestFunctionsV2 "LINESTRING(45.173118104 45.743370112,50 20,90 80,112.975930502 49.365425998)" ); } + + @Test + public void test_ST_LongestLine() { + registerUDFV2("ST_LongestLine", String.class, String.class); + verifySqlSingleRes( + "SELECT ST_AsText(sedona.ST_LongestLine(ST_GeomFromWKT('POLYGON ((40 180, 110 160, 180 180, 180 120, 140 90, 160 40, 80 10, 70 40, 20 50, 40 180),(60 140, 99 77.5, 90 140, 60 140))'), ST_GeomFromWKT('POLYGON ((40 180, 110 160, 180 180, 180 120, 140 90, 160 40, 80 10, 70 40, 20 50, 40 180),(60 140, 99 77.5, 90 140, 60 140))')))", + "LINESTRING(180 180,20 50)" + ); + } + @Test public void test_ST_MakePolygon() { registerUDFV2("ST_MakePolygon", 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 b478f1ee0..a184cc6ec 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 @@ -766,6 +766,17 @@ public class UDFs { ) ); } + + @UDFAnnotations.ParamMeta(argNames = {"geom1", "geom2"}) + public static byte[] ST_LongestLine(byte[] geom1, byte[] geom2) { + return GeometrySerde.serialize( + Functions.longestLine( + GeometrySerde.deserialize(geom1), + GeometrySerde.deserialize(geom2) + ) + ); + } + @UDFAnnotations.ParamMeta(argNames = {"point1", "point2"}) public static byte[] ST_MakeLine(byte[] geom1, byte[] geom2) { return GeometrySerde.serialize( 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 4c419b71d..720f106b3 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 @@ -684,6 +684,16 @@ public class UDFsV2 ); } + @UDFAnnotations.ParamMeta(argNames = {"geom1", "geom2"}, argTypes = {"Geometry", "Geometry"}, returnTypes = "Geometry") + public static String ST_LongestLine(String geom1, String geom2) { + return GeometrySerde.serGeoJson( + Functions.longestLine( + GeometrySerde.deserGeoJson(geom1), + GeometrySerde.deserGeoJson(geom2) + ) + ); + } + @UDFAnnotations.ParamMeta(argNames = {"point1", "point2"}, argTypes = {"Geometry", "Geometry"}, returnTypes = "Geometry") public static String ST_MakeLine(String geom1, String geom2) { return GeometrySerde.serGeoJson( 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 509687a6d..fe53d86fa 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_LineSubstring](), function[ST_LineInterpolatePoint](), function[ST_LineLocatePoint](), + function[ST_LongestLine](), function[ST_SubDivideExplode](), function[ST_SubDivide](), function[ST_MakeLine](), 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 d414d30d0..d7a836580 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 @@ -1185,6 +1185,14 @@ case class ST_LengthSpheroid(inputExpressions: Seq[Expression]) } } +case class ST_LongestLine(inputExpressions: Seq[Expression]) + extends InferredExpression(Functions.longestLine _) { + + protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) = { + copy(inputExpressions = newChildren) + } +} + case class ST_NumPoints(inputExpressions: Seq[Expression]) extends InferredExpression(Functions.numPoints _) { 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 a54e59044..77d2223e2 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 @@ -221,6 +221,9 @@ object st_functions extends DataFrameAPI { def ST_LineSubstring(lineString: Column, startFraction: Column, endFraction: Column): Column = wrapExpression[ST_LineSubstring](lineString, startFraction, endFraction) def ST_LineSubstring(lineString: String, startFraction: Double, endFraction: Double): Column = wrapExpression[ST_LineSubstring](lineString, startFraction, endFraction) + def ST_LongestLine(geom1: Column, geom2: Column): Column = wrapExpression[ST_LongestLine](geom1, geom2) + def ST_LongestLine(geom1: String, geom2: String): Column = wrapExpression[ST_LongestLine](geom1, geom2) + def ST_HasZ(geoms: Column): Column = wrapExpression[ST_HasZ](geoms) def ST_HasZ(geoms: String): Column = wrapExpression[ST_HasZ](geoms) 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 72a55323d..f97fb6525 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 @@ -928,6 +928,13 @@ class dataFrameAPITestScala extends TestBaseScala { assert(actualResult == expectedResult) } + it("Passed ST_LongestLine") { + val baseDf = sparkSession.sql("SELECT ST_GeomFromWKT('POLYGON ((40 180, 110 160, 180 180, 180 120, 140 90, 160 40, 80 10, 70 40, 20 50, 40 180),(60 140, 99 77.5, 90 140, 60 140))') as geom") + val actual = baseDf.select(ST_LongestLine("geom", "geom")).first().get(0).asInstanceOf[Geometry].toText + val expected = "LINESTRING (180 180, 20 50)" + assert(expected.equals(actual)) + } + it("Passed ST_FlipCoordinates") { val baseDf = sparkSession.sql("SELECT ST_Point(0.0, 1.0) AS geom") val df = baseDf.select(ST_FlipCoordinates("geom")) 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 cf7e40460..1dc0359e5 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 @@ -1626,6 +1626,13 @@ class functionTestScala extends TestBaseScala with Matchers with GeometrySample "GEOMETRYCOLLECTION EMPTY") } + it("Should pass ST_LongestLine") { + val baseDf = sparkSession.sql("SELECT ST_GeomFromWKT('POLYGON ((40 180, 110 160, 180 180, 180 120, 140 90, 160 40, 80 10, 70 40, 20 50, 40 180),(60 140, 99 77.5, 90 140, 60 140))') as geom") + val actual = baseDf.selectExpr("ST_LongestLine(geom, geom)").first().get(0).asInstanceOf[Geometry].toText + val expected = "LINESTRING (180 180, 20 50)" + assert(expected.equals(actual)) + } + it("Should pass ST_FlipCoordinates") { val pointDF = createSamplePointDf(5, "geom") val oldX = pointDF.take(1)(0).get(0).asInstanceOf[Geometry].getCoordinate.x
