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 20488c09e [SEDONA-652] Add ST_MakeEnvelope (#1585)
20488c09e is described below

commit 20488c09eca7b3288f24969973fc088e131b3232
Author: Furqaan Khan <[email protected]>
AuthorDate: Thu Sep 12 21:10:32 2024 -0400

    [SEDONA-652] Add ST_MakeEnvelope (#1585)
---
 .../org/apache/sedona/common/Constructors.java     | 11 +++++++++
 .../org/apache/sedona/common/ConstructorsTest.java | 23 ++++++++++++++----
 docs/api/flink/Constructor.md                      | 28 ++++++++++++++++++++++
 docs/api/snowflake/vector-data/Constructor.md      | 26 ++++++++++++++++++++
 docs/api/sql/Constructor.md                        | 28 ++++++++++++++++++++++
 .../main/java/org/apache/sedona/flink/Catalog.java |  1 +
 .../sedona/flink/expressions/Constructors.java     | 21 ++++++++++++++++
 .../org/apache/sedona/flink/ConstructorTest.java   | 27 +++++++++++++++++++++
 python/sedona/sql/st_constructors.py               | 22 +++++++++++++++++
 python/tests/sql/test_constructor_test.py          | 10 ++++++++
 python/tests/sql/test_dataframe_api.py             |  7 ++++++
 .../sedona/snowflake/snowsql/TestConstructors.java | 16 +++++++++++++
 .../org/apache/sedona/snowflake/snowsql/UDFs.java  | 11 +++++++++
 .../scala/org/apache/sedona/sql/UDF/Catalog.scala  |  1 +
 .../sql/sedona_sql/expressions/Constructors.scala  | 15 ++++++++++++
 .../sedona_sql/expressions/st_constructors.scala   | 23 ++++++++++++++++++
 .../org/apache/sedona/sql/PreserveSRIDSuite.scala  |  1 +
 .../apache/sedona/sql/constructorTestScala.scala   | 11 +++++++++
 .../apache/sedona/sql/dataFrameAPITestScala.scala  | 25 +++++++++++++++++++
 19 files changed, 303 insertions(+), 4 deletions(-)

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 4789f4430..3cd472924 100644
--- a/common/src/main/java/org/apache/sedona/common/Constructors.java
+++ b/common/src/main/java/org/apache/sedona/common/Constructors.java
@@ -271,6 +271,17 @@ public class Constructors {
     return GEOMETRY_FACTORY.createPolygon(coordinates);
   }
 
+  public static Geometry makeEnvelope(
+      double minX, double minY, double maxX, double maxY, int srid) {
+    Geometry envelope = polygonFromEnvelope(minX, minY, maxX, maxY);
+    envelope.setSRID(srid);
+    return envelope;
+  }
+
+  public static Geometry makeEnvelope(double minX, double minY, double maxX, 
double maxY) {
+    return makeEnvelope(minX, minY, maxX, maxY, 0);
+  }
+
   public static Geometry geomFromGeoHash(String geoHash, Integer precision) {
     try {
       return GeoHashDecoder.decode(geoHash, precision);
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 9619b3ba7..1cb4d17dc 100644
--- a/common/src/test/java/org/apache/sedona/common/ConstructorsTest.java
+++ b/common/src/test/java/org/apache/sedona/common/ConstructorsTest.java
@@ -22,10 +22,7 @@ import static org.junit.Assert.*;
 
 import org.apache.sedona.common.utils.GeomUtils;
 import org.junit.Test;
-import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.geom.GeometryFactory;
-import org.locationtech.jts.geom.Point;
+import org.locationtech.jts.geom.*;
 import org.locationtech.jts.io.ParseException;
 import org.locationtech.jts.io.WKBWriter;
 
@@ -226,6 +223,24 @@ public class ConstructorsTest {
     assertEquals("POINT (-112.5 22.5)", point);
   }
 
+  @Test
+  public void makeEnvelope() {
+    Geometry geom = Constructors.makeEnvelope(10, 10, 11, 11, 4326);
+    assertTrue(geom instanceof Polygon);
+    String actual = Functions.asWKT(geom);
+    String expected = "POLYGON ((10 10, 10 11, 11 11, 11 10, 10 10))";
+    assertEquals(expected, actual);
+
+    int actualSrid = geom.getSRID();
+    int expectedSrid = 4326;
+    assertEquals(expectedSrid, actualSrid);
+
+    geom = Constructors.makeEnvelope(10, 10, 11, 11);
+    assertTrue(geom instanceof Polygon);
+    actual = Functions.asWKT(geom);
+    assertEquals(expected, actual);
+  }
+
   @Test
   public void makePointM() {
     Geometry point = Constructors.makePointM(1, 2, 3);
diff --git a/docs/api/flink/Constructor.md b/docs/api/flink/Constructor.md
index 7552cddcd..e65628f31 100644
--- a/docs/api/flink/Constructor.md
+++ b/docs/api/flink/Constructor.md
@@ -448,6 +448,34 @@ Output:
 LINESTRING (-2.1047439575195312 -0.354827880859375, -1.49606454372406 
-0.6676061153411865)
 ```
 
+## ST_MakeEnvelope
+
+Introduction: Construct a Polygon from MinX, MinY, MaxX, MaxY, and an optional 
SRID.
+
+Format:
+
+```
+ST_MakeEnvelope(MinX: Double, MinY: Double, MaxX: Double, MaxY: Double)
+```
+
+```
+ST_MakeEnvelope(MinX: Double, MinY: Double, MaxX: Double, MaxY: Double, srid: 
Integer)
+```
+
+Since: `v1.7.0`
+
+SQL Example
+
+```sql
+SELECT ST_MakeEnvelope(1.234, 2.234, 3.345, 3.345, 4236)
+```
+
+Output:
+
+```
+POLYGON ((1.234 2.234, 1.234 3.345, 3.345 3.345, 3.345 2.234, 1.234 2.234))
+```
+
 ## ST_MLineFromText
 
 Introduction: Construct a MultiLineString from Text and Optional SRID
diff --git a/docs/api/snowflake/vector-data/Constructor.md 
b/docs/api/snowflake/vector-data/Constructor.md
index 9dcb1938c..ba69e76df 100644
--- a/docs/api/snowflake/vector-data/Constructor.md
+++ b/docs/api/snowflake/vector-data/Constructor.md
@@ -408,6 +408,32 @@ Output:
 LINESTRING (-2.1047439575195312 -0.354827880859375, -1.49606454372406 
-0.6676061153411865)
 ```
 
+## ST_MakeEnvelope
+
+Introduction: Construct a Polygon from MinX, MinY, MaxX, MaxY, and an optional 
SRID.
+
+Format:
+
+```
+ST_MakeEnvelope(MinX: Double, MinY: Double, MaxX: Double, MaxY: Double)
+```
+
+```
+ST_MakeEnvelope(MinX: Double, MinY: Double, MaxX: Double, MaxY: Double, srid: 
Integer)
+```
+
+SQL Example
+
+```sql
+SELECT ST_MakeEnvelope(1.234, 2.234, 3.345, 3.345, 4236)
+```
+
+Output:
+
+```
+POLYGON ((1.234 2.234, 1.234 3.345, 3.345 3.345, 3.345 2.234, 1.234 2.234))
+```
+
 ## ST_MLineFromText
 
 Introduction: Construct a MultiLineString from Wkt. If srid is not set, it 
defaults to 0 (unknown).
diff --git a/docs/api/sql/Constructor.md b/docs/api/sql/Constructor.md
index a1f715a0a..ccea1e3b1 100644
--- a/docs/api/sql/Constructor.md
+++ b/docs/api/sql/Constructor.md
@@ -449,6 +449,34 @@ Output:
 LINESTRING (-2.1047439575195312 -0.354827880859375, -1.49606454372406 
-0.6676061153411865)
 ```
 
+## ST_MakeEnvelope
+
+Introduction: Construct a Polygon from MinX, MinY, MaxX, MaxY, and an optional 
SRID.
+
+Format:
+
+```
+ST_MakeEnvelope(MinX: Double, MinY: Double, MaxX: Double, MaxY: Double)
+```
+
+```
+ST_MakeEnvelope(MinX: Double, MinY: Double, MaxX: Double, MaxY: Double, srid: 
Integer)
+```
+
+Since: `v1.7.0`
+
+SQL Example
+
+```sql
+SELECT ST_MakeEnvelope(1.234, 2.234, 3.345, 3.345, 4236)
+```
+
+Output:
+
+```
+POLYGON ((1.234 2.234, 1.234 3.345, 3.345 3.345, 3.345 2.234, 1.234 2.234))
+```
+
 ## ST_MLineFromText
 
 Introduction: Construct a MultiLineString from Wkt. If srid is not set, it 
defaults to 0 (unknown).
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 6fd3c7668..08bc209b0 100644
--- a/flink/src/main/java/org/apache/sedona/flink/Catalog.java
+++ b/flink/src/main/java/org/apache/sedona/flink/Catalog.java
@@ -36,6 +36,7 @@ public class Catalog {
       new Constructors.ST_PointFromWKB(),
       new Constructors.ST_LineFromWKB(),
       new Constructors.ST_LinestringFromWKB(),
+      new Constructors.ST_MakeEnvelope(),
       new Constructors.ST_MakePoint(),
       new Constructors.ST_MakePointM(),
       new Constructors.ST_LineStringFromText(),
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 88ee33b66..2e43f4c76 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
@@ -212,6 +212,27 @@ public class Constructors {
     }
   }
 
+  public static class ST_MakeEnvelope extends ScalarFunction {
+    @DataTypeHint(value = "RAW", bridgedTo = 
org.locationtech.jts.geom.Geometry.class)
+    public Geometry eval(
+        @DataTypeHint("Double") Double minX,
+        @DataTypeHint("Double") Double minY,
+        @DataTypeHint("Double") Double maxX,
+        @DataTypeHint("Double") Double maxY,
+        @DataTypeHint("Integer") Integer srid) {
+      return org.apache.sedona.common.Constructors.makeEnvelope(minX, minY, 
maxX, maxY, srid);
+    }
+
+    @DataTypeHint(value = "RAW", bridgedTo = 
org.locationtech.jts.geom.Geometry.class)
+    public Geometry eval(
+        @DataTypeHint("Double") Double minX,
+        @DataTypeHint("Double") Double minY,
+        @DataTypeHint("Double") Double maxX,
+        @DataTypeHint("Double") Double maxY) {
+      return org.apache.sedona.common.Constructors.makeEnvelope(minX, minY, 
maxX, maxY);
+    }
+  }
+
   public static class ST_PolygonFromEnvelope extends ScalarFunction {
     @DataTypeHint(value = "RAW", bridgedTo = 
org.locationtech.jts.geom.Geometry.class)
     public Geometry eval(
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 e13f00d4d..007222c74 100644
--- a/flink/src/test/java/org/apache/sedona/flink/ConstructorTest.java
+++ b/flink/src/test/java/org/apache/sedona/flink/ConstructorTest.java
@@ -367,6 +367,33 @@ public class ConstructorTest extends TestBase {
     assertEquals(4326, actual);
   }
 
+  @Test
+  public void testMakeEvelope() {
+    Double minX = 1.0;
+    Double minY = 100.0;
+    Double maxX = 2.0;
+    Double maxY = 200.0;
+    Coordinate[] coordinates = new Coordinate[5];
+    coordinates[0] = new Coordinate(minX, minY);
+    coordinates[1] = new Coordinate(minX, maxY);
+    coordinates[2] = new Coordinate(maxX, maxY);
+    coordinates[3] = new Coordinate(maxX, minY);
+    coordinates[4] = coordinates[0];
+    GeometryFactory geometryFactory = new GeometryFactory();
+    Geometry geom = geometryFactory.createPolygon(coordinates);
+    Geometry actualGeom =
+        (Geometry)
+            last(tableEnv.sqlQuery("SELECT ST_MakeEnvelope(1, 100, 2, 200, 
1111)")).getField(0);
+    assertEquals(actualGeom.toString(), geom.toString());
+    assertEquals(1111, actualGeom.getSRID());
+
+    assertEquals(
+        last(tableEnv.sqlQuery("SELECT ST_MakeEnvelope(1.0, 100.0, 2.0, 
200.0)"))
+            .getField(0)
+            .toString(),
+        geom.toString());
+  }
+
   @Test
   public void testPolygonFromEnvelope() {
     Double minX = 1.0;
diff --git a/python/sedona/sql/st_constructors.py 
b/python/sedona/sql/st_constructors.py
index 35403fbc7..594a36c66 100644
--- a/python/sedona/sql/st_constructors.py
+++ b/python/sedona/sql/st_constructors.py
@@ -361,6 +361,28 @@ def ST_MakePoint(x: ColumnOrNameOrNumber, y: 
ColumnOrNameOrNumber, z: Optional[C
         args = args + (m,)
     return _call_constructor_function("ST_MakePoint", (args))
 
+@validate_argument_types
+def ST_MakeEnvelope(min_x: ColumnOrNameOrNumber, min_y: ColumnOrNameOrNumber, 
max_x: ColumnOrNameOrNumber, max_y: ColumnOrNameOrNumber, srid: 
Optional[ColumnOrNameOrNumber] = None) -> Column:
+    """Generate a polygon geometry column from the minimum and maximum 
coordinates of an envelope with an option to add SRID
+
+    :param min_x: Minimum X coordinate for the envelope.
+    :type min_x: ColumnOrNameOrNumber
+    :param min_y: Minimum Y coordinate for the envelope.
+    :type min_y: ColumnOrNameOrNumber
+    :param max_x: Maximum X coordinate for the envelope.
+    :type max_x: ColumnOrNameOrNumber
+    :param max_y: Maximum Y coordinate for the envelope.
+    :type max_y: ColumnOrNameOrNumber
+    :param srid: SRID to be set for the envelope.
+    :type srid: ColumnOrNameOrNumber
+    :return: Polygon geometry column representing the envelope described by 
the coordinate bounds.
+    :rtype: Column
+    """
+    args = (min_x, min_y, max_x, max_y, srid)
+    if srid is None:
+        args = (min_x, min_y, max_x, max_y)
+
+    return _call_constructor_function("ST_MakeEnvelope", args)
 
 @validate_argument_types
 def ST_PolygonFromEnvelope(min_x: ColumnOrNameOrNumber, min_y: 
ColumnOrNameOrNumber, max_x: ColumnOrNameOrNumber, max_y: ColumnOrNameOrNumber) 
-> Column:
diff --git a/python/tests/sql/test_constructor_test.py 
b/python/tests/sql/test_constructor_test.py
index 9e994595d..345862d4c 100644
--- a/python/tests/sql/test_constructor_test.py
+++ b/python/tests/sql/test_constructor_test.py
@@ -117,6 +117,16 @@ class TestConstructors(TestBase):
         polygon_df = self.spark.sql("select ST_GeomFromWkt(wkt) as geomn from 
input_wkt")
         assert polygon_df.count() == 8
 
+    def test_st_make_envelope(self):
+        polygonDF = self.spark.sql(
+            "select 
ST_MakeEnvelope(double(1.234),double(2.234),double(3.345),double(3.345), 1111) 
as geom")
+        assert (polygonDF.count() == 1)
+        assert (1111 == polygonDF.selectExpr("ST_SRID(geom)").first()[0])
+
+        polygonDF = self.spark.sql(
+            "select 
ST_MakeEnvelope(double(1.234),double(2.234),double(3.345),double(3.345))")
+        assert (polygonDF.count() == 1)
+
     def test_st_geom_from_text(self):
         polygon_wkt_df = self.spark.read.format("csv").\
             option("delimiter", "\t").\
diff --git a/python/tests/sql/test_dataframe_api.py 
b/python/tests/sql/test_dataframe_api.py
index 59f79a0f1..913e97e42 100644
--- a/python/tests/sql/test_dataframe_api.py
+++ b/python/tests/sql/test_dataframe_api.py
@@ -67,6 +67,9 @@ test_configurations = [
     (stc.ST_PointFromWKB, ("wkbPoint",), "constructor", "", "POINT (10 15)"),
     (stc.ST_MakePoint, ("x", "y", "z"), "constructor", "", "POINT Z (0 1 2)"),
     (stc.ST_MakePointM, ("x", "y", "z"), "constructor", "ST_AsText(geom)", 
"POINT M(0 1 2)"),
+    (stc.ST_MakeEnvelope, ("minx", "miny", "maxx", "maxy"), "min_max_x_y", "", 
"POLYGON ((0 1, 0 3, 2 3, 2 1, 0 1))"),
+    (stc.ST_MakeEnvelope, ("minx", "miny", "maxx", "maxy", lambda: 
f.lit(1111)), "min_max_x_y", "", "POLYGON ((0 1, 0 3, 2 3, 2 1, 0 1))"),
+    (stc.ST_MakeEnvelope, ("minx", "miny", "maxx", "maxy", lambda: 
f.lit(1111)), "min_max_x_y", "ST_SRID(geom)", 1111),
     (stc.ST_PolygonFromEnvelope, ("minx", "miny", "maxx", "maxy"), 
"min_max_x_y", "", "POLYGON ((0 1, 0 3, 2 3, 2 1, 0 1))"),
     (stc.ST_PolygonFromEnvelope, (0.0, 1.0, 2.0, 3.0), "null", "", "POLYGON 
((0 1, 0 3, 2 3, 2 1, 0 1))"),
     (stc.ST_PolygonFromText, ("multiple_point", lambda: f.lit(',')), 
"constructor", "", "POLYGON ((0 0, 1 0, 1 1, 0 0))"),
@@ -296,6 +299,10 @@ wrong_type_configurations = [
     (stc.ST_PointFromText, ("", None)),
     (stc.ST_PointFromWKB, (None,)),
     (stc.ST_MPointFromText, (None,)),
+    (stc.ST_MakeEnvelope, (None, "", "", "", "")),
+    (stc.ST_MakeEnvelope, ("", None, "", "", "")),
+    (stc.ST_MakeEnvelope, ("", "", None, "", None)),
+    (stc.ST_MakeEnvelope, ("", "", "", None, None)),
     (stc.ST_PolygonFromEnvelope, (None, "", "", "")),
     (stc.ST_PolygonFromEnvelope, ("", None, "", "")),
     (stc.ST_PolygonFromEnvelope, ("", "", None, "")),
diff --git 
a/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestConstructors.java
 
b/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestConstructors.java
index 45b09fb77..e3ac68fa3 100644
--- 
a/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestConstructors.java
+++ 
b/snowflake-tester/src/test/java/org/apache/sedona/snowflake/snowsql/TestConstructors.java
@@ -241,6 +241,22 @@ public class TestConstructors extends TestBase {
         "select sedona.ST_AsText(sedona.ST_PointFromText('1.23,2.3', ','))", 
"POINT (1.23 2.3)");
   }
 
+  @Test
+  public void test_ST_MakeEnvelope() {
+    registerUDF("ST_MakeEnvelope", double.class, double.class, double.class, 
double.class);
+    verifySqlSingleRes(
+        "select sedona.ST_AsText(sedona.ST_MakeEnvelope(1.23, 2.3, 3.4, 4.5))",
+        "POLYGON ((1.23 2.3, 1.23 4.5, 3.4 4.5, 3.4 2.3, 1.23 2.3))");
+
+    registerUDF(
+        "ST_MakeEnvelope", double.class, double.class, double.class, 
double.class, int.class);
+    verifySqlSingleRes(
+        "select sedona.ST_AsText(sedona.ST_MakeEnvelope(1.23, 2.3, 3.4, 4.5, 
1111))",
+        "POLYGON ((1.23 2.3, 1.23 4.5, 3.4 4.5, 3.4 2.3, 1.23 2.3))");
+    verifySqlSingleRes(
+        "select sedona.ST_SRID(sedona.ST_MakeEnvelope(1.23, 2.3, 3.4, 4.5, 
1111))", 1111);
+  }
+
   @Test
   public void test_ST_PolygonFromEnvelope() {
     registerUDF("ST_PolygonFromEnvelope", double.class, double.class, 
double.class, double.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 b9268fc2b..2f6d1ef01 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
@@ -873,6 +873,17 @@ public class UDFs {
     return GeometrySerde.serialize(Constructors.polygonFromEnvelope(minX, 
minY, maxX, maxY));
   }
 
+  @UDFAnnotations.ParamMeta(argNames = {"minX", "minY", "maxX", "maxY"})
+  public static byte[] ST_MakeEnvelope(double minX, double minY, double maxX, 
double maxY) {
+    return GeometrySerde.serialize(Constructors.makeEnvelope(minX, minY, maxX, 
maxY));
+  }
+
+  @UDFAnnotations.ParamMeta(argNames = {"minX", "minY", "maxX", "maxY", 
"srid"})
+  public static byte[] ST_MakeEnvelope(
+      double minX, double minY, double maxX, double maxY, int srid) {
+    return GeometrySerde.serialize(Constructors.makeEnvelope(minX, minY, maxX, 
maxY, srid));
+  }
+
   @UDFAnnotations.ParamMeta(argNames = {"geomString", "delimiter"})
   public static byte[] ST_PolygonFromText(String geomString, String 
geomFormat) {
     return GeometrySerde.serialize(Constructors.polygonFromText(geomString, 
geomFormat));
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 fe32b0014..1e336739b 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
@@ -57,6 +57,7 @@ object Catalog {
     function[ST_CoordDim](),
     function[ST_Point](),
     function[ST_Points](),
+    function[ST_MakeEnvelope](),
     function[ST_MakePoint](null, null),
     function[ST_MakePointM](),
     function[ST_PointZ](0),
diff --git 
a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Constructors.scala
 
b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Constructors.scala
index 34c8d0351..39e57411e 100644
--- 
a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Constructors.scala
+++ 
b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/Constructors.scala
@@ -510,6 +510,21 @@ case class ST_MakePoint(inputExpressions: Seq[Expression])
   }
 }
 
+/**
+ * Return a polygon given minX,minY,maxX,maxY and optional SRID
+ *
+ * @param inputExpressions
+ */
+case class ST_MakeEnvelope(inputExpressions: Seq[Expression])
+    extends InferredExpression(
+      inferrableFunction5(Constructors.makeEnvelope),
+      inferrableFunction4(Constructors.makeEnvelope)) {
+
+  protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) = 
{
+    copy(inputExpressions = newChildren)
+  }
+}
+
 /**
  * Return a polygon given minX,minY,maxX,maxY
  *
diff --git 
a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_constructors.scala
 
b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_constructors.scala
index 890ac1039..437ad9163 100644
--- 
a/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_constructors.scala
+++ 
b/spark/common/src/main/scala/org/apache/spark/sql/sedona_sql/expressions/st_constructors.scala
@@ -194,6 +194,29 @@ object st_constructors extends DataFrameAPI {
   def ST_PointFromText(coords: String, delimiter: String): Column =
     wrapExpression[ST_PointFromText](coords, delimiter)
 
+  def ST_MakeEnvelope(minX: Column, minY: Column, maxX: Column, maxY: Column): 
Column =
+    wrapExpression[ST_MakeEnvelope](minX, minY, maxX, maxY)
+  def ST_MakeEnvelope(minX: String, minY: String, maxX: String, maxY: String): 
Column =
+    wrapExpression[ST_MakeEnvelope](minX, minY, maxX, maxY)
+  def ST_MakeEnvelope(minX: Double, minY: Double, maxX: Double, maxY: Double): 
Column =
+    wrapExpression[ST_MakeEnvelope](minX, minY, maxX, maxY)
+  def ST_MakeEnvelope(
+      minX: Column,
+      minY: Column,
+      maxX: Column,
+      maxY: Column,
+      srid: Column): Column =
+    wrapExpression[ST_MakeEnvelope](minX, minY, maxX, maxY, srid)
+  def ST_MakeEnvelope(
+      minX: String,
+      minY: String,
+      maxX: String,
+      maxY: String,
+      srid: String): Column =
+    wrapExpression[ST_MakeEnvelope](minX, minY, maxX, maxY, srid)
+  def ST_MakeEnvelope(minX: Double, minY: Double, maxX: Double, maxY: Double, 
srid: Int): Column =
+    wrapExpression[ST_MakeEnvelope](minX, minY, maxX, maxY, srid)
+
   def ST_PolygonFromEnvelope(minX: Column, minY: Column, maxX: Column, maxY: 
Column): Column =
     wrapExpression[ST_PolygonFromEnvelope](minX, minY, maxX, maxY)
   def ST_PolygonFromEnvelope(minX: String, minY: String, maxX: String, maxY: 
String): Column =
diff --git 
a/spark/common/src/test/scala/org/apache/sedona/sql/PreserveSRIDSuite.scala 
b/spark/common/src/test/scala/org/apache/sedona/sql/PreserveSRIDSuite.scala
index 4714233da..74d80b8e4 100644
--- a/spark/common/src/test/scala/org/apache/sedona/sql/PreserveSRIDSuite.scala
+++ b/spark/common/src/test/scala/org/apache/sedona/sql/PreserveSRIDSuite.scala
@@ -73,6 +73,7 @@ class PreserveSRIDSuite extends TestBaseScala with 
TableDrivenPropertyChecks {
       ("ST_ClosestPoint(geom1, geom2)", 1000),
       ("ST_FlipCoordinates(geom1)", 1000),
       ("ST_SubDivide(geom4, 4)", 1000),
+      ("ST_MakeEnvelope(0, 1, 2, 3, 1000)", 1000),
       ("ST_MakeLine(geom3, geom3)", 1000),
       ("ST_Points(geom1)", 1000),
       ("ST_Polygon(ST_InteriorRingN(geom4, 0), 2000)", 2000),
diff --git 
a/spark/common/src/test/scala/org/apache/sedona/sql/constructorTestScala.scala 
b/spark/common/src/test/scala/org/apache/sedona/sql/constructorTestScala.scala
index d1eff9deb..1eab00fe3 100644
--- 
a/spark/common/src/test/scala/org/apache/sedona/sql/constructorTestScala.scala
+++ 
b/spark/common/src/test/scala/org/apache/sedona/sql/constructorTestScala.scala
@@ -118,6 +118,17 @@ class constructorTestScala extends TestBaseScala {
       assert(pointDf.count() == 1)
     }
 
+    it("Passed ST_MakeEnvelope") {
+      var polygonDF = sparkSession.sql(
+        "select 
ST_MakeEnvelope(double(1.234),double(2.234),double(3.345),double(3.345), 1111) 
as geom")
+      assert(polygonDF.count() == 1)
+      assert(1111 == polygonDF.selectExpr("ST_SRID(geom)").first().getInt(0))
+
+      polygonDF = sparkSession.sql(
+        "select 
ST_MakeEnvelope(double(1.234),double(2.234),double(3.345),double(3.345))")
+      assert(polygonDF.count() == 1)
+    }
+
     it("Passed ST_PolygonFromEnvelope") {
       val polygonDF = sparkSession.sql(
         "select 
ST_PolygonFromEnvelope(double(1.234),double(2.234),double(3.345),double(3.345))")
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 b7e0a5686..f37849b3c 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
@@ -295,6 +295,31 @@ class dataFrameAPITestScala extends TestBaseScala {
       assert(actualResult == expectedResult)
     }
 
+    it("passed st_makeenvlope") {
+      val df = sparkSession.sql(
+        "SELECT 0.0 AS minx, 1.0 AS miny, 2.0 AS maxx, 3.0 AS maxy, 1111 AS 
srid")
+      val actualResult =
+        df.select(ST_MakeEnvelope("minx", "miny", "maxx", "maxy", 
"srid").as("geom"))
+      var actualGeom = actualResult
+        .take(1)(0)
+        .get(0)
+        .asInstanceOf[Geometry]
+        .toText()
+      var expectedResult = "POLYGON ((0 1, 0 3, 2 3, 2 1, 0 1))"
+      assert(actualGeom == expectedResult)
+
+      assert(1111 == 
actualResult.selectExpr("ST_SRID(geom)").first().getInt(0))
+
+      actualGeom = df
+        .select(ST_MakeEnvelope("minx", "miny", "maxx", "maxy"))
+        .take(1)(0)
+        .get(0)
+        .asInstanceOf[Geometry]
+        .toText()
+      expectedResult = "POLYGON ((0 1, 0 3, 2 3, 2 1, 0 1))"
+      assert(actualGeom == expectedResult)
+    }
+
     it("passed st_polygonfromenvelope with column values") {
       val df = sparkSession.sql("SELECT 0.0 AS minx, 1.0 AS miny, 2.0 AS maxx, 
3.0 AS maxy")
       val actualResult = df

Reply via email to