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

jiayu pushed a commit to branch fix/2373-azimuth-identical-points
in repository https://gitbox.apache.org/repos/asf/sedona.git

commit 32a26cdaff53fffa7dad3970e2316156121999a7
Author: Jia Yu <[email protected]>
AuthorDate: Sat Feb 7 12:42:16 2026 -0800

    Fix ST_Azimuth returning 0.0 instead of null for identical points
    
    When both input points are identical, ST_Azimuth now returns null instead 
of 0.0,
    matching PostGIS behavior. Changed return type from primitive double to 
Double
    in common Functions and Snowflake UDF wrappers.
    
    Added unit tests for azimuth: north (0.0), south (pi), and identical points 
(null).
    Updated docs for Spark SQL, Flink, and Snowflake to clarify null return 
behavior.
    
    Fixes #2373
---
 .../java/org/apache/sedona/common/Functions.java   |  5 ++++-
 .../org/apache/sedona/common/FunctionsTest.java    | 26 ++++++++++++++++++++++
 docs/api/flink/Function.md                         |  2 +-
 docs/api/snowflake/vector-data/Function.md         |  2 +-
 docs/api/sql/Function.md                           |  2 +-
 .../org/apache/sedona/snowflake/snowsql/UDFs.java  |  2 +-
 .../apache/sedona/snowflake/snowsql/UDFsV2.java    |  2 +-
 7 files changed, 35 insertions(+), 6 deletions(-)

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 0be88a9b1b..6bb88563d7 100644
--- a/common/src/main/java/org/apache/sedona/common/Functions.java
+++ b/common/src/main/java/org/apache/sedona/common/Functions.java
@@ -201,11 +201,14 @@ public class Functions {
     return Math.sqrt(closest);
   }
 
-  public static double azimuth(Geometry left, Geometry right) {
+  public static Double azimuth(Geometry left, Geometry right) {
     Coordinate leftCoordinate = left.getCoordinate();
     Coordinate rightCoordinate = right.getCoordinate();
     double deltaX = rightCoordinate.x - leftCoordinate.x;
     double deltaY = rightCoordinate.y - leftCoordinate.y;
+    if (deltaX == 0 && deltaY == 0) {
+      return null;
+    }
     double azimuth = Math.atan2(deltaX, deltaY);
     return azimuth < 0 ? azimuth + (2 * Math.PI) : azimuth;
   }
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 e379e67d6d..5137f40d6a 100644
--- a/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
+++ b/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
@@ -3580,6 +3580,32 @@ public class FunctionsTest extends TestBase {
     assertEquals(expected, actual);
   }
 
+  @Test
+  public void azimuthNorth() {
+    Point a = GEOMETRY_FACTORY.createPoint(new Coordinate(0, 0));
+    Point b = GEOMETRY_FACTORY.createPoint(new Coordinate(0, 1));
+    Double result = Functions.azimuth(a, b);
+    assertNotNull(result);
+    assertEquals(0.0, result, 1e-9);
+  }
+
+  @Test
+  public void azimuthSouth() {
+    Point a = GEOMETRY_FACTORY.createPoint(new Coordinate(0, 25));
+    Point b = GEOMETRY_FACTORY.createPoint(new Coordinate(0, 0));
+    Double result = Functions.azimuth(a, b);
+    assertNotNull(result);
+    assertEquals(Math.PI, result, 1e-9);
+  }
+
+  @Test
+  public void azimuthIdenticalPoints() {
+    Point a = GEOMETRY_FACTORY.createPoint(new Coordinate(0, 25));
+    Point b = GEOMETRY_FACTORY.createPoint(new Coordinate(0, 25));
+    Double result = Functions.azimuth(a, b);
+    assertNull(result);
+  }
+
   @Test
   public void angleFourPoints() {
     Point start1 = GEOMETRY_FACTORY.createPoint(new Coordinate(0, 0));
diff --git a/docs/api/flink/Function.md b/docs/api/flink/Function.md
index d74552617f..1c13ecf1e2 100644
--- a/docs/api/flink/Function.md
+++ b/docs/api/flink/Function.md
@@ -617,7 +617,7 @@ POINT ZM(1 1 1 1)
 
 ## ST_Azimuth
 
-Introduction: Returns Azimuth for two given points in radians null otherwise.
+Introduction: Returns Azimuth for two given points in radians. Returns null if 
the two points are identical.
 
 Format: `ST_Azimuth(pointA: Point, pointB: Point)`
 
diff --git a/docs/api/snowflake/vector-data/Function.md 
b/docs/api/snowflake/vector-data/Function.md
index 28eb433c3b..2ca1f88341 100644
--- a/docs/api/snowflake/vector-data/Function.md
+++ b/docs/api/snowflake/vector-data/Function.md
@@ -457,7 +457,7 @@ FROM polygondf
 
 ## ST_Azimuth
 
-Introduction: Returns Azimuth for two given points in radians null otherwise.
+Introduction: Returns Azimuth for two given points in radians. Returns null if 
the two points are identical.
 
 Format: `ST_Azimuth(pointA: Point, pointB: Point)`
 
diff --git a/docs/api/sql/Function.md b/docs/api/sql/Function.md
index 9c61520f6d..9f6d18f93f 100644
--- a/docs/api/sql/Function.md
+++ b/docs/api/sql/Function.md
@@ -682,7 +682,7 @@ POINT ZM(1 1 1 1)
 
 ## ST_Azimuth
 
-Introduction: Returns Azimuth for two given points in radians null otherwise.
+Introduction: Returns Azimuth for two given points in radians. Returns null if 
the two points are identical.
 
 Format: `ST_Azimuth(pointA: Point, pointB: Point)`
 
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 3e2d0095a6..99682eff30 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
@@ -171,7 +171,7 @@ public class UDFs {
   }
 
   @UDFAnnotations.ParamMeta(argNames = {"left", "right"})
-  public static double ST_Azimuth(byte[] left, byte[] right) {
+  public static Double ST_Azimuth(byte[] left, byte[] right) {
     return Functions.azimuth(GeometrySerde.deserialize(left), 
GeometrySerde.deserialize(right));
   }
 
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 5d545f4b6c..d68079e818 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
@@ -228,7 +228,7 @@ public class UDFsV2 {
   @UDFAnnotations.ParamMeta(
       argNames = {"left", "right"},
       argTypes = {"Geometry", "Geometry"})
-  public static double ST_Azimuth(String left, String right) {
+  public static Double ST_Azimuth(String left, String right) {
     return Functions.azimuth(GeometrySerde.deserGeoJson(left), 
GeometrySerde.deserGeoJson(right));
   }
 

Reply via email to