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 dba56d7a20 [SEDONA-675] Add ST_InterpolatePoint (#1684)
dba56d7a20 is described below

commit dba56d7a20e70f0d982bafde670592933f339b84
Author: Pranav Toggi <[email protected]>
AuthorDate: Tue Nov 19 11:35:46 2024 -0800

    [SEDONA-675] Add ST_InterpolatePoint (#1684)
---
 .../java/org/apache/sedona/common/Functions.java   | 53 +++++++++++++++++
 .../org/apache/sedona/common/FunctionsTest.java    | 25 ++++++++
 docs/api/flink/Function.md                         | 26 +++++++++
 docs/api/sql/Function.md                           | 26 +++++++++
 .../main/java/org/apache/sedona/flink/Catalog.java |  1 +
 .../apache/sedona/flink/expressions/Functions.java | 11 ++++
 .../java/org/apache/sedona/flink/FunctionTest.java | 67 ++++++++++++++++++++++
 python/sedona/sql/st_functions.py                  | 15 +++++
 python/tests/sql/test_dataframe_api.py             |  5 ++
 .../scala/org/apache/sedona/sql/UDF/Catalog.scala  |  3 +-
 .../sql/sedona_sql/expressions/Functions.scala     |  6 ++
 .../sql/sedona_sql/expressions/st_functions.scala  |  6 ++
 .../apache/sedona/sql/dataFrameAPITestScala.scala  | 25 ++++++++
 .../org/apache/sedona/sql/functionTestScala.scala  | 61 ++++++++++++++++++++
 14 files changed, 329 insertions(+), 1 deletion(-)

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 9c01cbb5f1..c93bae3e2f 100644
--- a/common/src/main/java/org/apache/sedona/common/Functions.java
+++ b/common/src/main/java/org/apache/sedona/common/Functions.java
@@ -2377,4 +2377,57 @@ public class Functions {
     AffineTransformation rotation = 
AffineTransformation.rotationInstance(angle, originX, originY);
     return rotation.transform(geometry);
   }
+
+  /**
+   * This function returns the m coordinate of the closest point in a 
LineString to the specified
+   * Point.
+   *
+   * @param geom1 The LineString (with or without M values) to be evaluated.
+   * @param geom2 The Point object to find the closest point to.
+   * @return The interpolated M value of the closest point on the LineString.
+   */
+  public static double interpolatePoint(Geometry geom1, Geometry geom2) {
+    if 
(!(Geometry.TYPENAME_LINESTRING.equalsIgnoreCase(geom1.getGeometryType()))) {
+      throw new IllegalArgumentException(
+          String.format(
+              "First argument is of type %s, should be a LineString.", 
geom1.getGeometryType()));
+    }
+    if (!(Geometry.TYPENAME_POINT.equalsIgnoreCase(geom2.getGeometryType()))) {
+      throw new IllegalArgumentException(
+          String.format(
+              "Second argument is of type %s, should be a Point.", 
geom2.getGeometryType()));
+    }
+    if (Float.isNaN((float) geom1.getCoordinate().getM())) {
+      throw new IllegalArgumentException("The given linestring does not have a 
measure value.");
+    }
+
+    if (geom1.getSRID() != geom2.getSRID()) {
+      throw new IllegalArgumentException(
+          String.format(
+              "The Line has SRID %d and Point has SRID %d. The Line and Point 
should be in the same SRID.",
+              geom1.getSRID(), geom2.getSRID()));
+    }
+
+    LineString line = (LineString) geom1;
+    Point point = (Point) geom2;
+
+    // Find the closest point on the line to the input point
+    Coordinate closestPoint = DistanceOp.nearestPoints(line, point)[0];
+
+    // Use LengthIndexedLine to extract the index at the closest point
+    LengthIndexedLine indexedLine = new LengthIndexedLine(line);
+    double index = indexedLine.indexOf(closestPoint);
+
+    // Extract the point at that index and compute its length fraction
+    double totalLength = indexedLine.getEndIndex();
+    double fractionAlongLine = index / totalLength;
+
+    // Get the start and end coordinates of the line
+    Geometry start = line.getStartPoint();
+    Geometry end = line.getEndPoint();
+
+    // Interpolate the M value
+    return fractionAlongLine * (end.getCoordinate().getM() - 
start.getCoordinate().getM())
+        + start.getCoordinate().getM();
+  }
 }
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 e9e9af6322..74ab3483b0 100644
--- a/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
+++ b/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
@@ -4086,4 +4086,29 @@ public class FunctionsTest extends TestBase {
         "LINESTRING (0 0, -0.8390715290764524 -0.5440211108893698, 
-0.2950504181870827 -1.383092639965822, 0 0)",
         result);
   }
+
+  @Test
+  public void interpolatePoint() throws ParseException {
+    Geometry line = Constructors.geomFromEWKT("LINESTRING M (0 0 0, 2 0 2, 4 0 
4)");
+    Geometry point = Constructors.geomFromEWKT("POINT(1 1)");
+
+    double actual = Functions.interpolatePoint(line, point);
+    double expected = 1.0;
+    assertEquals(expected, actual, 1e-6);
+
+    line = Constructors.geomFromEWKT("LINESTRING M (0 0 0, -2 2 2, -4 4 4)");
+    point = Constructors.geomFromEWKT("POINT(-1 1)");
+    actual = Functions.interpolatePoint(line, point);
+    assertEquals(expected, actual, 1e-6);
+
+    line = Constructors.geomFromEWKT("LINESTRING M (0 0 0, 2 2 2, 4 0 4)");
+    point = Constructors.geomFromEWKT("POINT(2 0)");
+    actual = Functions.interpolatePoint(line, point);
+    assertEquals(expected, actual, 1e-6);
+
+    point = Constructors.geomFromEWKT("POINT(2.5 1)");
+    actual = Functions.interpolatePoint(line, point);
+    expected = 2.75;
+    assertEquals(expected, actual, 1e-6);
+  }
 }
diff --git a/docs/api/flink/Function.md b/docs/api/flink/Function.md
index 4782f46555..56c358a3bf 100644
--- a/docs/api/flink/Function.md
+++ b/docs/api/flink/Function.md
@@ -2017,6 +2017,32 @@ Output:
 LINEARRING (1 1, 2 1, 2 2, 1 2, 1 1)
 ```
 
+## ST_InterpolatePoint
+
+Introduction: Returns the interpolated measure value of a linear measured 
LineString at the point closest to the specified point.
+
+!!!Note
+    Make sure that both geometries have the same SRID, otherwise the function 
will throw an IllegalArgumentException.
+
+Format: `ST_InterpolatePoint(linestringM: Geometry, point: Geometry)`
+
+Since: `v1.7.0`
+
+SQL Example
+
+```sql
+SELECT ST_InterpolatePoint(
+    ST_GeomFromWKT("LINESTRING M (0 0 0, 2 0 2, 4 0 4)"),
+    ST_GeomFromWKT("POINT (1 1)")
+    )
+```
+
+Output:
+
+```
+1.0
+```
+
 ## ST_Intersection
 
 Introduction: Return the intersection geometry of A and B
diff --git a/docs/api/sql/Function.md b/docs/api/sql/Function.md
index 1e946517d4..d909bd3cab 100644
--- a/docs/api/sql/Function.md
+++ b/docs/api/sql/Function.md
@@ -2023,6 +2023,32 @@ Output:
 LINESTRING (1 1, 2 1, 2 2, 1 2, 1 1)
 ```
 
+## ST_InterpolatePoint
+
+Introduction: Returns the interpolated measure value of a linear measured 
LineString at the point closest to the specified point.
+
+!!!Note
+    Make sure that both geometries have the same SRID, otherwise the function 
will throw an IllegalArgumentException.
+
+Format: `ST_InterpolatePoint(linestringM: Geometry, point: Geometry)`
+
+Since: `v1.7.0`
+
+SQL Example
+
+```sql
+SELECT ST_InterpolatePoint(
+    ST_GeomFromWKT("LINESTRING M (0 0 0, 2 0 2, 4 0 4)"),
+    ST_GeomFromWKT("POINT (1 1)")
+    )
+```
+
+Output:
+
+```
+1.0
+```
+
 ## ST_Intersection
 
 Introduction: Return the intersection geometry of A and B
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 21728c5727..5844fc30f0 100644
--- a/flink/src/main/java/org/apache/sedona/flink/Catalog.java
+++ b/flink/src/main/java/org/apache/sedona/flink/Catalog.java
@@ -88,6 +88,7 @@ public class Catalog {
       new Functions.ST_DelaunayTriangles(),
       new Functions.ST_EndPoint(),
       new Functions.ST_GeometryType(),
+      new Functions.ST_InterpolatePoint(),
       new Functions.ST_Intersection(),
       new Functions.ST_Length(),
       new Functions.ST_Length2D(),
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 bccdbe2364..83d53e999b 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
@@ -2068,4 +2068,15 @@ public class Functions {
       return org.apache.sedona.common.Functions.rotate(geom1, angle, originX, 
originY);
     }
   }
+
+  public static class ST_InterpolatePoint extends ScalarFunction {
+    @DataTypeHint("Double")
+    public double eval(
+        @DataTypeHint(value = "RAW", bridgedTo = Geometry.class) Object o1,
+        @DataTypeHint(value = "RAW", bridgedTo = Geometry.class) Object o2) {
+      Geometry geom1 = (Geometry) o1;
+      Geometry geom2 = (Geometry) o2;
+      return org.apache.sedona.common.Functions.interpolatePoint(geom1, geom2);
+    }
+  }
 }
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 ca9b8c1908..d3d569d940 100644
--- a/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
+++ b/flink/src/test/java/org/apache/sedona/flink/FunctionTest.java
@@ -2776,4 +2776,71 @@ public class FunctionTest extends TestBase {
         "POLYGON ((0.0700679430157733 0.5247497074078575, 2 0, 
1.2974088252118154 1.227340882196042, 2.5247497074078575 1.9299320569842267, 
0.5948176504236309 2.454681764392084, 1.2974088252118154 1.227340882196042, 
0.0700679430157733 0.5247497074078575))";
     assertEquals(expected, actual);
   }
+
+  @Test
+  public void testInterpolatePoint() {
+    // Create a table with the test geometries
+    Table tbl =
+        tableEnv.sqlQuery(
+            "SELECT "
+                + "ST_GeomFromEWKT('LINESTRING M (0 0 0, 2 0 2, 4 0 4)') AS 
line1, "
+                + "ST_GeomFromEWKT('POINT(1 1)') AS point1, "
+                + "ST_GeomFromEWKT('LINESTRING M (0 0 0, -2 2 2, -4 4 4)') AS 
line2, "
+                + "ST_GeomFromEWKT('POINT(-1 1)') AS point2, "
+                + "ST_GeomFromEWKT('LINESTRING M (0 0 0, 2 2 2, 4 0 4)') AS 
line3, "
+                + "ST_GeomFromEWKT('POINT(2 0)') AS point3, "
+                + "ST_GeomFromEWKT('POINT(2.5 1)') AS point4");
+
+    double actual =
+        (double)
+            first(
+                    tbl.select(
+                            call(
+                                
Functions.ST_InterpolatePoint.class.getSimpleName(),
+                                $("line1"),
+                                $("point1")))
+                        .as("result"))
+                .getField(0);
+    double expected = 1.0; // Closest point on line is (1, 0) and interpolated 
M is 1
+    assertEquals(expected, actual, 1e-6);
+
+    actual =
+        (double)
+            first(
+                    tbl.select(
+                            call(
+                                
Functions.ST_InterpolatePoint.class.getSimpleName(),
+                                $("line2"),
+                                $("point2")))
+                        .as("result"))
+                .getField(0);
+    expected = 1.0; // Interpolated M value
+    assertEquals(expected, actual, 1e-6);
+
+    actual =
+        (double)
+            first(
+                    tbl.select(
+                            call(
+                                
Functions.ST_InterpolatePoint.class.getSimpleName(),
+                                $("line3"),
+                                $("point3")))
+                        .as("result"))
+                .getField(0);
+    expected = 1.0; // Interpolated M value
+    assertEquals(expected, actual, 1e-6);
+
+    actual =
+        (double)
+            first(
+                    tbl.select(
+                            call(
+                                
Functions.ST_InterpolatePoint.class.getSimpleName(),
+                                $("line3"),
+                                $("point4")))
+                        .as("result"))
+                .getField(0);
+    expected = 2.75;
+    assertEquals(expected, actual, 1e-6);
+  }
 }
diff --git a/python/sedona/sql/st_functions.py 
b/python/sedona/sql/st_functions.py
index 22fd373583..3bec08d7bf 100644
--- a/python/sedona/sql/st_functions.py
+++ b/python/sedona/sql/st_functions.py
@@ -2393,6 +2393,21 @@ def ST_Rotate(
     return _call_st_function("ST_Rotate", args)
 
 
+@validate_argument_types
+def ST_InterpolatePoint(geom1: ColumnOrName, geom2: ColumnOrName) -> Column:
+    """Returns the interpolated Measure value at the point on the given 
linestring M that is closest to the given point.
+
+    :param geom1: LineString M Geometry column or name.
+    :type geom1: ColumnOrName
+    :param geom2: Point Geometry column or name.
+    :type geom2: ColumnOrName
+    :rtype: Column
+    """
+
+    args = (geom1, geom2)
+    return _call_st_function("ST_InterpolatePoint", args)
+
+
 # Automatically populate __all__
 __all__ = [
     name
diff --git a/python/tests/sql/test_dataframe_api.py 
b/python/tests/sql/test_dataframe_api.py
index ca37349cb8..9c5c65e093 100644
--- a/python/tests/sql/test_dataframe_api.py
+++ b/python/tests/sql/test_dataframe_api.py
@@ -611,6 +611,7 @@ test_configurations = [
         "",
         "POLYGON ((2 0, 1 0, 1 1, 2 1, 2 0))",
     ),
+    (stf.ST_InterpolatePoint, ("linem", "point"), "linestringm_and_point", "", 
1.0),
     (stf.ST_IsCollection, ("geom",), "geom_collection", "", True),
     (stf.ST_IsClosed, ("geom",), "closed_linestring_geom", "", True),
     (stf.ST_IsEmpty, ("geom",), "empty_geom", "", True),
@@ -1620,6 +1621,10 @@ class TestDataFrameAPI(TestBase):
             return TestDataFrameAPI.spark.sql(
                 "SELECT ST_GeomFromWKT('GEOMETRYCOLLECTION (LINESTRING (2 0, 2 
1, 2 2), LINESTRING (2 2, 2 3, 2 4), LINESTRING (0 2, 1 2, 2 2), LINESTRING (2 
2, 3 2, 4 2), LINESTRING (0 2, 1 3, 2 4), LINESTRING (2 4, 3 3, 4 2))') as geom"
             )
+        elif request.param == "linestringm_and_point":
+            return TestDataFrameAPI.spark.sql(
+                "SELECT ST_GeomFromWKT('LINESTRING M (0 0 0, 2 0 2, 4 0 4)') 
as linem, ST_GeomFromWKT('POINT (1 1)') as point"
+            )
         raise ValueError(f"Invalid base_df name passed: {request.param}")
 
     def _id_test_configuration(val):
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 f2ff868b45..442d0203c7 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
@@ -22,7 +22,7 @@ import org.apache.spark.sql.catalyst.FunctionIdentifier
 import org.apache.spark.sql.catalyst.analysis.FunctionRegistry.FunctionBuilder
 import org.apache.spark.sql.catalyst.expressions.{ExpectsInputTypes, 
Expression, ExpressionInfo, Literal}
 import org.apache.spark.sql.expressions.Aggregator
-import org.apache.spark.sql.sedona_sql.expressions._
+import org.apache.spark.sql.sedona_sql.expressions.{ST_InterpolatePoint, _}
 import org.apache.spark.sql.sedona_sql.expressions.collect.ST_Collect
 import org.apache.spark.sql.sedona_sql.expressions.raster._
 import org.locationtech.jts.geom.Geometry
@@ -150,6 +150,7 @@ object Catalog {
     function[ST_H3ToGeom](),
     function[ST_H3KRing](),
     function[ST_InteriorRingN](),
+    function[ST_InterpolatePoint](),
     function[ST_Dump](),
     function[ST_DumpPoints](),
     function[ST_IsClosed](),
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 9a6ea689fa..91f833e936 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
@@ -1765,3 +1765,9 @@ case class ST_Rotate(inputExpressions: Seq[Expression])
   protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) =
     copy(inputExpressions = newChildren)
 }
+
+case class ST_InterpolatePoint(inputExpressions: Seq[Expression])
+    extends 
InferredExpression(inferrableFunction2(Functions.interpolatePoint)) {
+  protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) =
+    copy(inputExpressions = newChildren)
+}
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 56a2227174..e7b11c3c17 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
@@ -926,4 +926,10 @@ object st_functions extends DataFrameAPI {
 
   def ST_IsCollection(geometry: String): Column = 
wrapExpression[ST_IsCollection](geometry)
 
+  def ST_InterpolatePoint(geom1: Column, geom2: Column): Column =
+    wrapExpression[ST_InterpolatePoint](geom1, geom2)
+
+  def ST_InterpolatePoint(geom1: String, geom2: String): Column =
+    wrapExpression[ST_InterpolatePoint](geom1, geom2)
+
 }
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 a2a4ded595..e0dbe5a60a 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
@@ -2383,5 +2383,30 @@ class dataFrameAPITestScala extends TestBaseScala {
       assert(exception2.getMessage.contains("POLYGON ((0 0, 0 1, 1 1, 1 0, 0 
0))"))
       assert(exception2.getMessage.contains("ST_MakeLine"))
     }
+
+    it("Passed ST_InterpolatePoint") {
+      val testData = Seq(
+        ("LINESTRING M (0 0 0, 2 0 2, 4 0 4)", "POINT(1 1)", 1.0),
+        ("LINESTRING M (0 0 0, -2 2 2, -4 4 4)", "POINT(-1 1)", 1.0),
+        ("LINESTRING M (0 0 0, 2 2 2, 4 0 4)", "POINT(2 0)", 1.0),
+        ("LINESTRING M (0 0 0, 2 2 2, 4 0 4)", "POINT(2.5 1)", 2.75)).toDF(
+        "lineEWKT",
+        "pointEWKT",
+        "expectedResult")
+
+      val geomDf = testData
+        .withColumn("line", ST_GeomFromEWKT(col("lineEWKT")))
+        .withColumn("point", ST_GeomFromEWKT(col("pointEWKT")))
+
+      geomDf
+        .withColumn("result", ST_InterpolatePoint(col("line"), col("point")))
+        .select("result", "expectedResult")
+        .collect()
+        .foreach { row =>
+          val actual = row.getAs[Double]("result")
+          val expected = row.getAs[Double]("expectedResult")
+          assert(actual == expected, s"Expected $expected but got $actual")
+        }
+    }
   }
 }
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 c05f745f57..e727cfdd10 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
@@ -3611,4 +3611,65 @@ class functionTestScala
     exception.getMessage should include("The origin must be a non-empty Point 
geometry.")
   }
 
+  it("Should pass ST_InterpolatePoint") {
+    val geomTestCases = Map(
+      ("'LINESTRING M (0 0 0, 2 0 2, 4 0 4)'", "'POINT(1 1)'") -> 1.0,
+      ("'LINESTRING M (0 0 0, -2 2 2, -4 4 4)'", "'POINT(-1 1)'") -> 1.0,
+      ("'LINESTRING M (0 0 0, 2 2 2, 4 0 4)'", "'POINT(2 0)'") -> 1.0,
+      ("'LINESTRING M (0 0 0, 2 2 2, 4 0 4)'", "'POINT(2.5 1)'") -> 2.75)
+
+    for (((geom1, geom2), expectedResult) <- geomTestCases) {
+      val df = sparkSession.sql(s"""
+                                   |SELECT
+                                   |   ST_InterpolatePoint(
+                                   |     ST_GeomFromEWKT($geom1),
+                                   |     ST_GeomFromEWKT($geom2)
+                                   |   ) AS mValue
+         """.stripMargin)
+
+      val actual = df.take(1)(0).get(0).asInstanceOf[Double]
+      assert(actual == expectedResult)
+    }
+
+    // Test invalid arguments
+    var invalidOriginDf = sparkSession.sql("""
+                                             |SELECT 
ST_InterpolatePoint(ST_GeomFromText('LINESTRING (50 160, 50 50, 100 50)'), 
ST_GeomFromText('POINT (1 1)')) as result
+    """.stripMargin)
+
+    var exception = intercept[Exception] {
+      invalidOriginDf.collect()
+    }
+    exception.getMessage should include("The given linestring does not have a 
measure value.")
+
+    invalidOriginDf = sparkSession.sql("""
+                                         |SELECT 
ST_InterpolatePoint(ST_GeomFromText('POINT (0 1)'), ST_GeomFromText('POINT (1 
1)')) as result
+    """.stripMargin)
+
+    exception = intercept[Exception] {
+      invalidOriginDf.collect()
+    }
+    exception.getMessage should include(
+      "First argument is of type Point, should be a LineString.")
+
+    invalidOriginDf = sparkSession.sql("""
+                                         |SELECT 
ST_InterpolatePoint(ST_GeomFromText('LINESTRING M (0 0 0, 2 0 2, 4 0 4)'), 
ST_GeomFromText('LINESTRING (50 160, 50 50, 100 50)')) as result
+    """.stripMargin)
+
+    exception = intercept[Exception] {
+      invalidOriginDf.collect()
+    }
+    exception.getMessage should include(
+      "Second argument is of type LineString, should be a Point.")
+
+    invalidOriginDf = sparkSession.sql("""
+                                         |SELECT 
ST_InterpolatePoint(ST_SetSRID(ST_GeomFromText('LINESTRING M (0 0 0, 2 0 2, 4 0 
4)'), 4326), ST_SetSRID(ST_GeomFromText('POINT (1 1)'), 3857)) as result
+    """.stripMargin)
+
+    exception = intercept[Exception] {
+      invalidOriginDf.collect()
+    }
+    exception.getMessage should include(
+      "The Line has SRID 4326 and Point has SRID 3857. The Line and Point 
should be in the same SRID.")
+  }
+
 }

Reply via email to