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/incubator-sedona.git


The following commit(s) were added to refs/heads/master by this push:
     new 5c0f9270 [SEDONA-201] add ST_MPolyFromText and  ST_MLineFromText 
methods (#718)
5c0f9270 is described below

commit 5c0f92701b45d49dbab78a5366776e30b0fef834
Author: gmaraswa <[email protected]>
AuthorDate: Fri Dec 9 00:41:48 2022 -0700

    [SEDONA-201] add ST_MPolyFromText and  ST_MLineFromText methods (#718)
---
 .../org/apache/sedona/common/Constructors.java     | 16 +++++++++
 .../org/apache/sedona/common/ConstructorsTest.java | 38 ++++++++++++++++++++++
 docs/api/flink/Constructor.md                      | 28 ++++++++++++++++
 docs/api/sql/Constructor.md                        | 32 ++++++++++++++++++
 .../main/java/org/apache/sedona/flink/Catalog.java |  2 ++
 .../sedona/flink/expressions/Constructors.java     | 26 ++++++++++++++-
 .../org/apache/sedona/flink/ConstructorTest.java   | 24 ++++++++++++++
 .../java/org/apache/sedona/flink/TestBase.java     | 38 ++++++++++++++++++++++
 python/sedona/sql/st_constructors.py               | 24 ++++++++++++++
 python/tests/sql/test_constructor_test.py          | 11 +++++++
 .../scala/org/apache/sedona/sql/UDF/Catalog.scala  |  2 ++
 .../sql/sedona_sql/expressions/Constructors.scala  | 26 +++++++++++++++
 .../sedona_sql/expressions/st_constructors.scala   | 13 ++++++++
 .../apache/sedona/sql/constructorTestScala.scala   | 19 +++++++++++
 14 files changed, 298 insertions(+), 1 deletion(-)

diff --git a/common/src/main/java/org/apache/sedona/common/Constructors.java 
b/common/src/main/java/org/apache/sedona/common/Constructors.java
index 101ba043..7cd5e4a8 100644
--- a/common/src/main/java/org/apache/sedona/common/Constructors.java
+++ b/common/src/main/java/org/apache/sedona/common/Constructors.java
@@ -28,4 +28,20 @@ public class Constructors {
         GeometryFactory geometryFactory = new GeometryFactory(new 
PrecisionModel(), srid);
         return new WKTReader(geometryFactory).read(wkt);
     }
+
+    public static Geometry mLineFromText(String wkt, int srid) throws 
ParseException {
+        if (wkt == null || !wkt.startsWith("MULTILINESTRING")) {
+            return null;
+        }
+        GeometryFactory geometryFactory = new GeometryFactory(new 
PrecisionModel(), srid);
+        return new WKTReader(geometryFactory).read(wkt);
+    }
+
+    public static Geometry mPolyFromText(String wkt, int srid) throws 
ParseException {
+        if (wkt == null || !wkt.startsWith("MULTIPOLYGON")) {
+            return null;
+        }
+        GeometryFactory geometryFactory = new GeometryFactory(new 
PrecisionModel(), srid);
+        return new WKTReader(geometryFactory).read(wkt);
+    }
 }
diff --git 
a/common/src/test/java/org/apache/sedona/common/ConstructorsTest.java 
b/common/src/test/java/org/apache/sedona/common/ConstructorsTest.java
index 5cfaeee4..89fe729c 100644
--- a/common/src/test/java/org/apache/sedona/common/ConstructorsTest.java
+++ b/common/src/test/java/org/apache/sedona/common/ConstructorsTest.java
@@ -36,4 +36,42 @@ public class ConstructorsTest {
         ParseException invalid = assertThrows(ParseException.class, () -> 
Constructors.geomFromWKT("not valid", 0));
         assertEquals("Unknown geometry type: NOT (line 1)", 
invalid.getMessage());
     }
+    @Test
+    public void mLineFromWKT() throws ParseException {
+        assertNull(Constructors.mLineFromText(null, 0));
+        assertNull(Constructors.mLineFromText("POINT (1 1)", 0));
+        Geometry geom = Constructors.mLineFromText("MULTILINESTRING((1 2, 3 
4), (4 5, 6 7))", 0);
+        assertEquals(0,geom.getSRID());
+        assertEquals("MULTILINESTRING ((1 2, 3 4), (4 5, 6 7))",geom.toText());
+
+        geom = Constructors.mLineFromText("MULTILINESTRING((1 2, 3 4), (4 5, 6 
7))", 3306);
+        assertEquals(3306,geom.getSRID());
+        assertEquals("MULTILINESTRING ((1 2, 3 4), (4 5, 6 7))",geom.toText());
+
+        ParseException invalid = assertThrows(ParseException.class, () -> 
Constructors.mLineFromText("MULTILINESTRING(not valid)", 0));
+        assertEquals("Expected EMPTY or ( but found 'not' (line 1)", 
invalid.getMessage());
+
+    }
+
+    @Test
+    public void mPolyFromWKT() throws ParseException {
+        assertNull(Constructors.mPolyFromText(null, 0));
+        assertNull(Constructors.mPolyFromText("POINT (1 1)", 0));
+        Geometry geom = Constructors.mPolyFromText("MULTIPOLYGON(((0 0 ,20 0 
,20 20 ,0 20 ,0 0 ),(5 5 ,5 7 ,7 7 ,7 5 ,5 5)))", 0);
+        assertEquals(0,geom.getSRID());
+        assertEquals("MULTIPOLYGON (((0 0, 20 0, 20 20, 0 20, 0 0), (5 5, 5 7, 
7 7, 7 5, 5 5)))",geom.toText());
+
+        geom = Constructors.mPolyFromText("MULTIPOLYGON(((0 0 ,20 0 ,20 20 ,0 
20 ,0 0 ),(5 5 ,5 7 ,7 7 ,7 5 ,5 5)))", 3306);
+        assertEquals(3306,geom.getSRID());
+        assertEquals("MULTIPOLYGON (((0 0, 20 0, 20 20, 0 20, 0 0), (5 5, 5 7, 
7 7, 7 5, 5 5)))"
+                ,geom.toText());
+
+        IllegalArgumentException invalid = 
assertThrows(IllegalArgumentException.class,
+                () -> Constructors.mPolyFromText("MULTIPOLYGON(((-70.916 
42.1002,-70.9468 42.0946,-70.9765 42.0872 )))", 0));
+        assertEquals("Points of LinearRing do not form a closed linestring", 
invalid.getMessage());
+
+        ParseException parseException = assertThrows(ParseException.class, () 
-> Constructors.mPolyFromText("MULTIPOLYGON(not valid)", 0));
+        assertEquals("Expected EMPTY or ( but found 'not' (line 1)", 
parseException.getMessage());
+
+    }
 }
\ No newline at end of file
diff --git a/docs/api/flink/Constructor.md b/docs/api/flink/Constructor.md
index 2999fef7..22cff1ac 100644
--- a/docs/api/flink/Constructor.md
+++ b/docs/api/flink/Constructor.md
@@ -134,6 +134,34 @@ Spark SQL example:
 SELECT ST_LineStringFromText('Linestring(1 2, 3 4)') AS line
 ```
 
+## ST_MLineFromText
+
+Introduction: Construct a MultiLineString from Text and Optional SRID
+
+Format: `ST_MLineFromText (Text:string, Srid: int)`
+
+Since: `1.3.1`
+
+SQL example:
+```SQL
+SELECT ST_MLineFromText('MULTILINESTRING((1 2, 3 4), (4 5, 6 7))') AS multiLine
+SELECT ST_MLineFromText('MULTILINESTRING((1 2, 3 4), (4 5, 6 7))', 4269) AS 
multiLine
+```
+
+## ST_MPolyFromText
+
+Introduction: Construct a MultiPolygon from Text and Optional SRID
+
+Format: `ST_MPolyFromText (Text:string, Srid: int)`
+
+Since: `1.3.1`
+
+SQL example:
+```SQL
+SELECT ST_MPolyFromText('MULTIPOLYGON(((-70.916 42.1002,-70.9468 
42.0946,-70.9765 42.0872 )))') AS multiPolygon
+SELECT ST_MPolyFromText('MULTIPOLYGON(((-70.916 42.1002,-70.9468 
42.0946,-70.9765 42.0872 )))', 4269) AS multiPolygon
+```
+
 ## ST_Point
 
 Introduction: Construct a Point from X and Y
diff --git a/docs/api/sql/Constructor.md b/docs/api/sql/Constructor.md
index 39ae94a8..ec5b5e66 100644
--- a/docs/api/sql/Constructor.md
+++ b/docs/api/sql/Constructor.md
@@ -208,6 +208,38 @@ FROM linestringtable
 
 ```SQL
 SELECT 
ST_LineStringFromText('-74.0428197,40.6867969,-74.0421975,40.6921336,-74.0508020,40.6912794',
 ',') AS linestringshape
+```
+## ST_MLineFromText
+
+Introduction: Construct a MultiLineString from Wkt. If srid is not set, it 
defaults to 0 (unknown).
+
+Format:
+`ST_MLineFromText (Wkt:string)`
+`ST_MLineFromText (Wkt:string, srid:integer)`
+
+Since: `v1.3.1`
+
+Spark SQL example:
+```SQL
+SELECT ST_MLineFromText('MULTILINESTRING((1 2, 3 4), (4 5, 6 7))') AS 
multiLine;
+SELECT ST_MLineFromText('MULTILINESTRING((1 2, 3 4), (4 5, 6 7))',4269) AS 
multiLine;
+```
+
+## ST_MPolyFromText
+
+Introduction: Construct a MultiPolygon from Wkt. If srid is not set, it 
defaults to 0 (unknown).
+
+Format:
+`ST_MPolyFromText (Wkt:string)`
+`ST_MPolyFromText (Wkt:string, srid:integer)`
+
+Since: `v1.3.1`
+
+Spark SQL example:
+```SQL
+SELECT ST_MPolyFromText('MULTIPOLYGON(((-70.916 42.1002,-70.9468 
42.0946,-70.9765 42.0872 )))') AS multiPolygon
+SELECT ST_MPolyFromText('MULTIPOLYGON(((-70.916 42.1002,-70.9468 
42.0946,-70.9765 42.0872 )))',4269) AS multiPolygon
+
 ```
 
 ## ST_Point
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 f290361d..40c9e450 100644
--- a/flink/src/main/java/org/apache/sedona/flink/Catalog.java
+++ b/flink/src/main/java/org/apache/sedona/flink/Catalog.java
@@ -34,6 +34,8 @@ public class Catalog {
                 new Constructors.ST_GeomFromGeoHash(),
                 new Constructors.ST_GeomFromGML(),
                 new Constructors.ST_GeomFromKML(),
+                new Constructors.ST_MPolyFromText(),
+                new Constructors.ST_MLineFromText(),
                 new Functions.ST_Area(),
                 new Functions.ST_Azimuth(),
                 new Functions.ST_Boundary(),
diff --git 
a/flink/src/main/java/org/apache/sedona/flink/expressions/Constructors.java 
b/flink/src/main/java/org/apache/sedona/flink/expressions/Constructors.java
index f7d60000..d6583ed8 100644
--- a/flink/src/main/java/org/apache/sedona/flink/expressions/Constructors.java
+++ b/flink/src/main/java/org/apache/sedona/flink/expressions/Constructors.java
@@ -30,7 +30,7 @@ import org.locationtech.jts.io.kml.KMLReader;
 public class Constructors {
 
     private static Geometry getGeometryByType(String geom, String 
inputDelimiter, GeometryType geometryType) throws ParseException {
-        FileDataSplitter delimiter = inputDelimiter == null? 
FileDataSplitter.CSV:FileDataSplitter.getFileDataSplitter(inputDelimiter);
+        FileDataSplitter delimiter = inputDelimiter == null ? 
FileDataSplitter.CSV : FileDataSplitter.getFileDataSplitter(inputDelimiter);
         FormatUtils<Geometry> formatUtils = new FormatUtils<>(delimiter, 
false, geometryType);
         return formatUtils.readGeometry(geom);
     }
@@ -185,4 +185,28 @@ public class Constructors {
             return new KMLReader().read(kml);
         }
     }
+
+    public static class ST_MPolyFromText extends ScalarFunction {
+        @DataTypeHint(value = "RAW", bridgedTo = 
org.locationtech.jts.geom.Geometry.class)
+        public Geometry eval(@DataTypeHint(value = "String") String wkt, 
@DataTypeHint("Int") Integer srid) throws ParseException {
+            return org.apache.sedona.common.Constructors.mPolyFromText(wkt, 
srid);
+        }
+
+        @DataTypeHint(value = "RAW", bridgedTo = 
org.locationtech.jts.geom.Geometry.class)
+        public Geometry eval(@DataTypeHint(value = "String") String wkt) 
throws ParseException {
+            return org.apache.sedona.common.Constructors.mPolyFromText(wkt, 0);
+        }
+    }
+
+    public static class ST_MLineFromText extends ScalarFunction {
+        @DataTypeHint(value = "RAW", bridgedTo = 
org.locationtech.jts.geom.Geometry.class)
+        public Geometry eval(@DataTypeHint(value = "String") String wkt, 
@DataTypeHint("Int") Integer srid) throws ParseException {
+            return org.apache.sedona.common.Constructors.mLineFromText(wkt, 
srid);
+        }
+        @DataTypeHint(value = "RAW", bridgedTo = 
org.locationtech.jts.geom.Geometry.class)
+        public Geometry eval(@DataTypeHint(value = "String") String wkt) 
throws ParseException {
+            return org.apache.sedona.common.Constructors.mLineFromText(wkt, 0);
+        }
+    }
+
 }
diff --git a/flink/src/test/java/org/apache/sedona/flink/ConstructorTest.java 
b/flink/src/test/java/org/apache/sedona/flink/ConstructorTest.java
index 35578334..2b0514e2 100644
--- a/flink/src/test/java/org/apache/sedona/flink/ConstructorTest.java
+++ b/flink/src/test/java/org/apache/sedona/flink/ConstructorTest.java
@@ -276,4 +276,28 @@ public class ConstructorTest extends TestBase{
                 $(polygonColNames[1]));
         assertTrue(first(geomTable).getField(0) instanceof Polygon);
     }
+
+    @Test
+    public void testMPolygonFromText() {
+        List<Row> data = createMultiPolygonText(testDataSize);
+        Row result = last(createMultiPolygonTable(testDataSize));
+        assertEquals(data.get(data.size() - 1).getField(0).toString(), 
result.getField(0).toString());
+    }
+
+    @Test
+    public void testMLineFromText() {
+        List<Row> data = new ArrayList<>();
+        data.add(Row.of("MULTILINESTRING((1 2, 3 4), (4 5, 6 7))", 
"multiline", 0L));
+
+        Table geohashTable = createTextTable(data, multilinestringColNames);
+        Table geomTable = geohashTable
+                
.select(call(Constructors.ST_MLineFromText.class.getSimpleName(),
+                        $(multilinestringColNames[0]))
+                        .as(multilinestringColNames[0]), 
$(multilinestringColNames[1]));
+        String result = first(geomTable)
+                .getFieldAs(0)
+                .toString();
+        String expectedGeom = "MULTILINESTRING ((1 2, 3 4), (4 5, 6 7))";
+        assertEquals(expectedGeom, result);
+    }
 }
diff --git a/flink/src/test/java/org/apache/sedona/flink/TestBase.java 
b/flink/src/test/java/org/apache/sedona/flink/TestBase.java
index 26c5f14c..db24dc88 100644
--- a/flink/src/test/java/org/apache/sedona/flink/TestBase.java
+++ b/flink/src/test/java/org/apache/sedona/flink/TestBase.java
@@ -45,7 +45,9 @@ public class TestBase {
     static int testDataSize = 1000;
     static String[] pointColNames = {"geom_point", "name_point", "event_time", 
"proc_time"};
     static String[] linestringColNames = {"geom_linestring", 
"name_linestring", "event_time", "proc_time"};
+    static String[] multilinestringColNames = {"geom_multilinestring", 
"name_multilinestring", "event_time", "proc_time"};
     static String[] polygonColNames = {"geom_polygon", "name_polygon", 
"event_time", "proc_time"};
+    static String[] multipolygonColNames = {"geom_multipolygon", 
"name_multipolygon", "event_time", "proc_time"};
     static String pointTableName = "point_table";
     static String polygonTableName = "polygon_table";
     static Long timestamp_base = new 
Timestamp(System.currentTimeMillis()).getTime();
@@ -212,6 +214,32 @@ public class TestBase {
         return data;
     }
 
+    static String createPolygonString(int i) {
+        // Each polygon is an envelope like (-0.5, -0.5, 0.5, 0.5)
+        String minX = String.valueOf(i - 0.5);
+        String minY = String.valueOf(i - 0.5);
+        String maxX = String.valueOf(i + 0.5);
+        String maxY = String.valueOf(i + 0.5);
+        List<String> polygon = new ArrayList<>();
+        polygon.add(minX + " " + minY);
+        polygon.add(minX + " " + maxY);
+        polygon.add(maxX + " " + maxY);
+        polygon.add(maxX + " " + minY);
+        polygon.add(minX + " " + minY);
+        return "(("+ String.join(", ", polygon)+"))";
+    }
+
+    static List<Row> createMultiPolygonText(int size) {
+        List<Row> data = new ArrayList<>();
+        for (int i = 0; i < size; i++) {
+            List<String> multiPolygon=new ArrayList<>();
+            multiPolygon.add(createPolygonString(i));
+            multiPolygon.add(createPolygonString(size-i-1));
+            data.add(Row.of("MULTIPOLYGON (" + String.join(", ", multiPolygon) 
+ ")", "multipolygon" + i, timestamp_base + time_interval * 1000 * i));
+        }
+        return data;
+    }
+
     static List<Row> createPolygonGeoJSON(int size) {
         List<Row> data = new ArrayList<>();
         GeometryFactory geometryFactory = new GeometryFactory();
@@ -271,6 +299,10 @@ public class TestBase {
         return createTextTable(createPolygonText(size), polygonColNames);
     }
 
+    static Table createMultiPolygonTextTable(int size) {
+        return createTextTable(createMultiPolygonText(size), 
multipolygonColNames);
+    }
+
     static Table createPolygonTextOverlappingTable(int size) {
         return createTextTable(createPolygonOverlapping(size), 
polygonColNames);
     }
@@ -303,6 +335,12 @@ public class TestBase {
                         $(polygonColNames[1]), $(polygonColNames[2]), 
$(polygonColNames[3]));
     }
 
+    Table createMultiPolygonTable(int size) {
+        return createMultiPolygonTextTable(size)
+                
.select(call(Constructors.ST_MPolyFromText.class.getSimpleName(),
+                                
$(multipolygonColNames[0])).as(multipolygonColNames[0]),
+                        $(multipolygonColNames[1]), 
$(multipolygonColNames[2]), $(multipolygonColNames[3]));
+    }
     //createPolygonTextOverlapping
 
     Table createPolygonOverlappingTable(int size) {
diff --git a/python/sedona/sql/st_constructors.py 
b/python/sedona/sql/st_constructors.py
index 679dc3e4..9d51a78a 100644
--- a/python/sedona/sql/st_constructors.py
+++ b/python/sedona/sql/st_constructors.py
@@ -37,6 +37,8 @@ __all__ = [
     "ST_PointFromText",
     "ST_PolygonFromEnvelope",
     "ST_PolygonFromText",
+    "ST_MLineFromText",
+    "ST_MPolyFromText"
 ]
 
 
@@ -221,3 +223,25 @@ def ST_PolygonFromText(coords: ColumnOrName, delimiter: 
ColumnOrName) -> Column:
     :rtype: Column
     """
     return _call_constructor_function("ST_PolygonFromText", (coords, 
delimiter))
+
+@validate_argument_types
+def ST_MPolyFromText(wkt: ColumnOrName) -> Column:
+    """Generate multiPolygon geometry from a multiPolygon WKT representation.
+
+    :param wkt: multiPolygon WKT string column to generate from.
+    :type wkt: ColumnOrName
+    :return: multiPolygon geometry generated from the wkt column.
+    :rtype: Column
+    """
+    return _call_constructor_function("ST_MPolyFromText", wkt)
+
+@validate_argument_types
+def ST_MLineFromText(wkt: ColumnOrName) -> Column:
+    """Generate multiLineString geometry from a multiLineString WKT 
representation.
+
+    :param wkt: multiLineString WKT string column to generate from.
+    :type wkt: ColumnOrName
+    :return: multiLineString geometry generated from the wkt column.
+    :rtype: Column
+    """
+    return _call_constructor_function("ST_MLineFromText", wkt)
diff --git a/python/tests/sql/test_constructor_test.py 
b/python/tests/sql/test_constructor_test.py
index aefb3763..89db0fa4 100644
--- a/python/tests/sql/test_constructor_test.py
+++ b/python/tests/sql/test_constructor_test.py
@@ -118,3 +118,14 @@ class TestConstructors(TestBase):
         line_df = self.spark.sql("select ST_LineFromText(wkt) as geom from 
input_wkt")
         assert line_df.count() == 1
 
+    def test_Mline_from_text(self) :
+        input_df = self.spark.createDataFrame([("MULTILINESTRING((1 2, 3 4), 
(4 5, 6 7))",)], ["wkt"])
+        input_df.createOrReplaceTempView("input_wkt")
+        line_df = self.spark.sql("select ST_MLineFromText(wkt) as geom from 
input_wkt")
+        assert line_df.count() == 1
+
+    def test_MPoly_from_text(self) :
+        input_df = self.spark.createDataFrame([("MULTIPOLYGON (((0 0, 20 0, 20 
20, 0 20, 0 0), (5 5, 5 7, 7 7, 7 5, 5 5)))",)], ["wkt"])
+        input_df.createOrReplaceTempView("input_wkt")
+        line_df = self.spark.sql("select ST_MPolyFromText(wkt) as geom from 
input_wkt")
+        assert line_df.count() == 1
\ No newline at end of file
diff --git a/sql/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala 
b/sql/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
index bd912feb..09e1d256 100644
--- a/sql/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
+++ b/sql/src/main/scala/org/apache/sedona/sql/UDF/Catalog.scala
@@ -136,6 +136,8 @@ object Catalog {
     function[ST_CollectionExtract](),
     function[ST_Normalize](),
     function[ST_LineFromMultiPoint](),
+    function[ST_MPolyFromText](0),
+    function[ST_MLineFromText](0),
     // Expression for rasters
     function[RS_NormalizedDifference](),
     function[RS_Mean](),
diff --git 
a/sql/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Constructors.scala
 
b/sql/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Constructors.scala
index 6e4909d0..5d2b095f 100644
--- 
a/sql/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Constructors.scala
+++ 
b/sql/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Constructors.scala
@@ -439,3 +439,29 @@ case class ST_GeomFromKML(inputExpressions: 
Seq[Expression])
     copy(inputExpressions = newChildren)
   }
 }
+
+/**
+ * Return a Geometry from a WKT string
+ *
+ * @param inputExpressions This function takes a geometry string and a srid. 
The string format must be WKT.
+ */
+case class ST_MPolyFromText(inputExpressions: Seq[Expression])
+  extends InferredBinaryExpression(Constructors.mPolyFromText) with 
FoldableExpression {
+  protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) = 
{
+    copy(inputExpressions = newChildren)
+  }
+}
+
+/**
+ * Return a Geometry from a WKT string
+ *
+ * @param inputExpressions This function takes a geometry string and a srid. 
The string format must be WKT.
+ */
+case class ST_MLineFromText(inputExpressions: Seq[Expression])
+  extends InferredBinaryExpression(Constructors.mLineFromText) with 
FoldableExpression {
+
+  protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) = 
{
+    copy(inputExpressions = newChildren)
+  }
+}
+
diff --git 
a/sql/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_constructors.scala
 
b/sql/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_constructors.scala
index 2a38b0a4..6f34d37b 100644
--- 
a/sql/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_constructors.scala
+++ 
b/sql/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_constructors.scala
@@ -73,4 +73,17 @@ object st_constructors extends DataFrameAPI {
 
   def ST_PolygonFromText(coords: Column, delimiter: Column): Column = 
wrapExpression[ST_PolygonFromText](coords, delimiter)
   def ST_PolygonFromText(coords: String, delimiter: String): Column = 
wrapExpression[ST_PolygonFromText](coords, delimiter)
+
+  def ST_MPolyFromText(wkt: Column): Column = 
wrapExpression[ST_MPolyFromText](wkt, 0)
+  def ST_MPolyFromText(wkt: String): Column = 
wrapExpression[ST_MPolyFromText](wkt, 0)
+
+  def ST_MPolyFromText(wkt: Column, srid: Column): Column = 
wrapExpression[ST_MPolyFromText](wkt, srid)
+  def ST_MPolyFromText(wkt: String, srid: Int): Column = 
wrapExpression[ST_GeomFromText](wkt, srid)
+
+  def ST_MLineFromText(wkt: Column): Column = 
wrapExpression[ST_MLineFromText](wkt, 0)
+  def ST_MLineFromText(wkt: String): Column = 
wrapExpression[ST_MLineFromText](wkt, 0)
+
+  def ST_MLineFromText(wkt: Column, srid: Column): Column = 
wrapExpression[ST_MLineFromText](wkt, srid)
+
+  def ST_MLineFromText(wkt: String, srid: Int): Column = 
wrapExpression[ST_MLineFromText](wkt, srid)
 }
diff --git 
a/sql/src/test/scala/org/apache/sedona/sql/constructorTestScala.scala 
b/sql/src/test/scala/org/apache/sedona/sql/constructorTestScala.scala
index 8f794065..372fe9f7 100644
--- a/sql/src/test/scala/org/apache/sedona/sql/constructorTestScala.scala
+++ b/sql/src/test/scala/org/apache/sedona/sql/constructorTestScala.scala
@@ -204,5 +204,24 @@ class constructorTestScala extends TestBaseScala {
       var spatialRDD2 = Adapter.toSpatialRdd(df, "geometry")
       Adapter.toDf(spatialRDD2, sparkSession).show(1)
     }
+
+    it("Passed ST_MLineFromText") {
+      var mLineDf = sparkSession.sql("select ST_MLineFromText('MULTILINESTRING 
((1 2, 3 4), (4 5, 6 7))')")
+      assert(mLineDf.count() == 1)
+    }
+    it("Passed ST_MLineFromText With Srid") {
+      var mLineDf = sparkSession.sql("select ST_MLineFromText('MULTILINESTRING 
((1 2, 3 4), (4 5, 6 7))',4269)")
+      assert(mLineDf.count() == 1)
+    }
+
+    it("Passed ST_MPolyFromText") {
+      var mLineDf = sparkSession.sql("select 
ST_MPolyFromText('MULTIPOLYGON(((-70.916 42.1002,-70.9468 42.0946,-70.9765 
42.0872 )))')")
+      assert(mLineDf.count() == 1)
+    }
+
+    it("Passed ST_MPolyFromText With Srid") {
+      var mLineDf = sparkSession.sql("select 
ST_MPolyFromText('MULTIPOLYGON(((-70.916 42.1002,-70.9468 42.0946,-70.9765 
42.0872 )))',4269)")
+      assert(mLineDf.count() == 1)
+    }
   }
 }

Reply via email to