You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sedona.apache.org by ji...@apache.org on 2026/04/26 19:31:39 UTC

(sedona) branch master updated: [GH-2830] Adds Geography dual-dispatch to ST_GeometryType (#2850)

This is an automated email from the ASF dual-hosted git repository.

jiayuasu 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 ca1be45004 [GH-2830] Adds Geography dual-dispatch to ST_GeometryType (#2850)
ca1be45004 is described below

commit ca1be450045678aca6fb5305859b05368dd30677
Author: Feng Zhang <fe...@apache.org>
AuthorDate: Sun Apr 26 12:31:34 2026 -0700

    [GH-2830] Adds Geography dual-dispatch to ST_GeometryType (#2850)
---
 .../apache/sedona/common/geography/Functions.java  |  6 ++++
 .../sedona/common/Geography/FunctionTest.java      | 29 +++++++++++++++
 docs/api/sql/geography/Geography-Functions.md      |  1 +
 .../Geography-Functions/ST_GeometryType.md         | 42 ++++++++++++++++++++++
 .../sql/sedona_sql/expressions/Functions.scala     |  4 ++-
 .../sql/geography/GeographyFunctionTest.scala      | 16 ++++++++-
 6 files changed, 96 insertions(+), 2 deletions(-)

diff --git a/common/src/main/java/org/apache/sedona/common/geography/Functions.java b/common/src/main/java/org/apache/sedona/common/geography/Functions.java
index d6a0b407b1..e41be2a211 100644
--- a/common/src/main/java/org/apache/sedona/common/geography/Functions.java
+++ b/common/src/main/java/org/apache/sedona/common/geography/Functions.java
@@ -85,6 +85,12 @@ public class Functions {
     return toJTS(g).getNumPoints();
   }
 
+  /** Return the geometry type string of a geography, prefixed with "ST_". */
+  public static String geometryType(Geography g) {
+    if (g == null) return null;
+    return "ST_" + toJTS(g).getGeometryType();
+  }
+
   /** Return the WKT text representation of a geography. */
   public static String asText(Geography g) {
     if (g == null) return null;
diff --git a/common/src/test/java/org/apache/sedona/common/Geography/FunctionTest.java b/common/src/test/java/org/apache/sedona/common/Geography/FunctionTest.java
index ab2daca5df..3e5cf2d058 100644
--- a/common/src/test/java/org/apache/sedona/common/Geography/FunctionTest.java
+++ b/common/src/test/java/org/apache/sedona/common/Geography/FunctionTest.java
@@ -148,6 +148,35 @@ public class FunctionTest {
     assertEquals(5, Functions.nPoints(g));
   }
 
+  @Test
+  public void geometryType_point() throws ParseException {
+    Geography g = Constructors.geogFromWKT("POINT (1 2)", 4326);
+    assertEquals("ST_Point", Functions.geometryType(g));
+  }
+
+  @Test
+  public void geometryType_linestring() throws ParseException {
+    Geography g = Constructors.geogFromWKT("LINESTRING (0 0, 1 1, 2 2)", 4326);
+    assertEquals("ST_LineString", Functions.geometryType(g));
+  }
+
+  @Test
+  public void geometryType_polygon() throws ParseException {
+    Geography g = Constructors.geogFromWKT("POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))", 4326);
+    assertEquals("ST_Polygon", Functions.geometryType(g));
+  }
+
+  @Test
+  public void geometryType_multipoint() throws ParseException {
+    Geography g = Constructors.geogFromWKT("MULTIPOINT ((0 0), (1 1))", 4326);
+    assertEquals("ST_MultiPoint", Functions.geometryType(g));
+  }
+
+  @Test
+  public void geometryType_nullHandling() {
+    assertNull(Functions.geometryType(null));
+  }
+
   @Test
   public void asText_point() throws ParseException {
     Geography g = Constructors.geogFromWKT("POINT (1 2)", 4326);
diff --git a/docs/api/sql/geography/Geography-Functions.md b/docs/api/sql/geography/Geography-Functions.md
index 86b5a12fb5..b701c6cf83 100644
--- a/docs/api/sql/geography/Geography-Functions.md
+++ b/docs/api/sql/geography/Geography-Functions.md
@@ -44,6 +44,7 @@ These functions operate on geography type objects.
 | [ST_AsEWKT](Geography-Functions/ST_AsEWKT.md) | String | Return the Extended Well-Known Text representation of a geography. | v1.8.0 |
 | [ST_AsText](Geography-Functions/ST_AsText.md) | String | Return the Well-Known Text (WKT) representation of a geography. | v1.9.1 |
 | [ST_Envelope](Geography-Functions/ST_Envelope.md) | Geography | Return the bounding box (envelope) of a geography. Supports anti-meridian splitting. | v1.8.0 |
+| [ST_GeometryType](Geography-Functions/ST_GeometryType.md) | String | Return the type of a geography as a string (e.g., "ST_Point", "ST_Polygon"). | v1.9.1 |
 | [ST_NPoints](Geography-Functions/ST_NPoints.md) | Integer | Return the number of points (vertices) in a geography. | v1.9.0 |
 | [ST_Distance](Geography-Functions/ST_Distance.md) | Double | Return the minimum geodesic distance between two geographies in meters. | v1.9.0 |
 | [ST_Contains](Geography-Functions/ST_Contains.md) | Boolean | Test whether geography A fully contains geography B. | v1.9.0 |
diff --git a/docs/api/sql/geography/Geography-Functions/ST_GeometryType.md b/docs/api/sql/geography/Geography-Functions/ST_GeometryType.md
new file mode 100644
index 0000000000..f6e840f555
--- /dev/null
+++ b/docs/api/sql/geography/Geography-Functions/ST_GeometryType.md
@@ -0,0 +1,42 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ -->
+
+# ST_GeometryType
+
+Introduction: Returns the type of the geography object as a string (e.g., "ST_Point", "ST_Polygon", "ST_LineString").
+
+Format:
+
+`ST_GeometryType (A: Geography)`
+
+Return type: `String`
+
+Since: `v1.9.1`
+
+SQL Example
+
+```sql
+SELECT ST_GeometryType(ST_GeogFromWKT('POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))'));
+```
+
+Output:
+
+```
+ST_Polygon
+```
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 66f01a6ccf..7354cbad46 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
@@ -633,7 +633,9 @@ private[apache] case class ST_SetSRID(inputExpressions: Seq[Expression])
 }
 
 private[apache] case class ST_GeometryType(inputExpressions: Seq[Expression])
-    extends InferredExpression(Functions.geometryType _) {
+    extends InferredExpression(
+      inferrableFunction1(Functions.geometryType),
+      inferrableFunction1(org.apache.sedona.common.geography.Functions.geometryType)) {
 
   protected def withNewChildrenInternal(newChildren: IndexedSeq[Expression]) = {
     copy(inputExpressions = newChildren)
diff --git a/spark/common/src/test/scala/org/apache/sedona/sql/geography/GeographyFunctionTest.scala b/spark/common/src/test/scala/org/apache/sedona/sql/geography/GeographyFunctionTest.scala
index 7f47ae5182..afa221419a 100644
--- a/spark/common/src/test/scala/org/apache/sedona/sql/geography/GeographyFunctionTest.scala
+++ b/spark/common/src/test/scala/org/apache/sedona/sql/geography/GeographyFunctionTest.scala
@@ -78,7 +78,7 @@ class GeographyFunctionTest extends TestBaseScala {
     }
   }
 
-  // ─── Level 1: ST_NPoints, ST_AsText ────────────────────────────────────
+  // ─── Level 1: ST_NPoints, ST_GeometryType, ST_AsText ───────────────────
 
   describe("Level 1: Structural") {
 
@@ -89,6 +89,20 @@ class GeographyFunctionTest extends TestBaseScala {
       assertEquals(3, row.getInt(0))
     }
 
+    it("ST_GeometryType point") {
+      val row = sparkSession
+        .sql("SELECT ST_GeometryType(ST_GeogFromWKT('POINT (1 2)', 4326)) AS t")
+        .first()
+      assertEquals("ST_Point", row.getString(0))
+    }
+
+    it("ST_GeometryType polygon") {
+      val row = sparkSession
+        .sql("SELECT ST_GeometryType(ST_GeogFromWKT('POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))', 4326)) AS t")
+        .first()
+      assertEquals("ST_Polygon", row.getString(0))
+    }
+
     it("ST_AsText") {
       val row = sparkSession
         .sql("SELECT ST_AsText(ST_GeogFromWKT('POINT (1 2)', 4326)) AS wkt")