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 0c2dda585 [SEDONA-589] Add ST_LongestLine (#1462)
0c2dda585 is described below
commit 0c2dda585a991e8053f61aa3c195eab25289c6a9
Author: Jia Yu <[email protected]>
AuthorDate: Fri Jun 7 10:49:06 2024 -0700
[SEDONA-589] Add ST_LongestLine (#1462)
* fix: bug of ST_LongestLine (#173)
* temp commit
* Revert "temp commit"
This reverts commit 8cd8ecc6b3ae533379b779ba08c23b12df47e2fc.
* feat: Add ST_LongestLine
* fix: bug that would cause null pointer exception
* Revert "fix: bug of ST_LongestLine (#173)"
This reverts commit 717a242cf7d584a410614845a90185e451f16c0e.
* [TASK-32] Add ST_LongestLine (#169)
* temp commit
* Revert "temp commit"
This reverts commit 8cd8ecc6b3ae533379b779ba08c23b12df47e2fc.
* feat: Add ST_LongestLine
* Update version
* fix: bug of ST_LongestLine (#173)
* temp commit
* Revert "temp commit"
This reverts commit 8cd8ecc6b3ae533379b779ba08c23b12df47e2fc.
* feat: Add ST_LongestLine
* fix: bug that would cause null pointer exception
---------
Co-authored-by: Furqaan Khan <[email protected]>
---
.../java/org/apache/sedona/common/Functions.java | 18 +++++++++++
.../org/apache/sedona/common/FunctionsTest.java | 37 ++++++++++++++++++++++
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, 232 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 ad85bea36..c583a3592 100644
--- a/common/src/main/java/org/apache/sedona/common/Functions.java
+++ b/common/src/main/java/org/apache/sedona/common/Functions.java
@@ -1058,6 +1058,24 @@ public class Functions {
return isExteriorRingCCW && isInteriorRingCCW;
}
+ public static Geometry longestLine(Geometry geom1, Geometry geom2) {
+ double maxLength = - Double.MAX_VALUE;
+ 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 9ce130930..3456fef9e 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,43 @@ 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);
+
+ geom1 = Constructors.geomFromWKT("POINT (0 0)", 0);
+ actual = Functions.asWKT(Functions.longestLine(geom1, geom1));
+ expected = "LINESTRING (0 0, 0 0)";
+ 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 81b7414b8..01da7ce93 100644
--- a/docs/api/flink/Function.md
+++ b/docs/api/flink/Function.md
@@ -2270,6 +2270,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: `v1.6.1`
+
+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 59fb5f40f..12b598d0d 100644
--- a/docs/api/sql/Function.md
+++ b/docs/api/sql/Function.md
@@ -2277,6 +2277,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: `v1.6.1`
+
+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 102289ed7..591b783d0 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 217d86cfc..e30769cc7 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 ab4e0e522..8105827e1 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 d93408916..9b65f6ad0 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 35d92dee8..0426c7414 100644
--- a/python/tests/sql/test_dataframe_api.py
+++ b/python/tests/sql/test_dataframe_api.py
@@ -156,6 +156,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),
@@ -341,6 +342,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 c50dda6ab..064e30277 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 7a2f79176..f3b46011d 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 0f91ecd08..2e1d5062d 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 02b0cb17b..374b5aaa4 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 7c6e05b7e..1fa25d270 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 dd76d3bdd..3f08784a3 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