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 671c41d880 [GH-1874] Fix ST_XYMin/Max returning sentinel values for
EMPTY geometries (#2621)
671c41d880 is described below
commit 671c41d8806fbf02fdae5342ecfc9c09782bc02a
Author: Jia Yu <[email protected]>
AuthorDate: Sat Feb 7 15:15:36 2026 -0700
[GH-1874] Fix ST_XYMin/Max returning sentinel values for EMPTY geometries
(#2621)
---
.../java/org/apache/sedona/common/Functions.java | 16 ++++++------
.../org/apache/sedona/common/FunctionsTest.java | 30 ++++++++++++++++++++++
.../org/apache/sedona/snowflake/snowsql/UDFs.java | 8 +++---
.../apache/sedona/snowflake/snowsql/UDFsV2.java | 8 +++---
4 files changed, 46 insertions(+), 16 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 0ade0e66a1..f6805668ce 100644
--- a/common/src/main/java/org/apache/sedona/common/Functions.java
+++ b/common/src/main/java/org/apache/sedona/common/Functions.java
@@ -668,40 +668,40 @@ public class Functions {
return max == -Double.MAX_VALUE ? null : max;
}
- public static double xMin(Geometry geometry) {
+ public static Double xMin(Geometry geometry) {
Coordinate[] points = geometry.getCoordinates();
double min = Double.MAX_VALUE;
for (int i = 0; i < points.length; i++) {
min = Math.min(points[i].getX(), min);
}
- return min;
+ return min == Double.MAX_VALUE ? null : min;
}
- public static double xMax(Geometry geometry) {
+ public static Double xMax(Geometry geometry) {
Coordinate[] points = geometry.getCoordinates();
double max = -Double.MAX_VALUE;
for (int i = 0; i < points.length; i++) {
max = Math.max(points[i].getX(), max);
}
- return max;
+ return max == -Double.MAX_VALUE ? null : max;
}
- public static double yMin(Geometry geometry) {
+ public static Double yMin(Geometry geometry) {
Coordinate[] points = geometry.getCoordinates();
double min = Double.MAX_VALUE;
for (int i = 0; i < points.length; i++) {
min = Math.min(points[i].getY(), min);
}
- return min;
+ return min == Double.MAX_VALUE ? null : min;
}
- public static double yMax(Geometry geometry) {
+ public static Double yMax(Geometry geometry) {
Coordinate[] points = geometry.getCoordinates();
double max = -Double.MAX_VALUE;
for (int i = 0; i < points.length; i++) {
max = Math.max(points[i].getY(), max);
}
- return max;
+ return max == -Double.MAX_VALUE ? null : max;
}
public static Double zMax(Geometry geometry) {
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 c2aeced939..19f29cc3bd 100644
--- a/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
+++ b/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
@@ -3620,6 +3620,36 @@ public class FunctionsTest extends TestBase {
assertEquals(expected, actual);
}
+ @Test
+ public void boundsEmptyGeometryReturnsNull() {
+ Geometry emptyPoint = GEOMETRY_FACTORY.createPoint();
+ assertNull(Functions.xMin(emptyPoint));
+ assertNull(Functions.xMax(emptyPoint));
+ assertNull(Functions.yMin(emptyPoint));
+ assertNull(Functions.yMax(emptyPoint));
+
+ Geometry emptyPolygon = GEOMETRY_FACTORY.createPolygon();
+ assertNull(Functions.xMin(emptyPolygon));
+ assertNull(Functions.xMax(emptyPolygon));
+ assertNull(Functions.yMin(emptyPolygon));
+ assertNull(Functions.yMax(emptyPolygon));
+
+ Geometry emptyLineString = GEOMETRY_FACTORY.createLineString();
+ assertNull(Functions.xMin(emptyLineString));
+ assertNull(Functions.xMax(emptyLineString));
+ assertNull(Functions.yMin(emptyLineString));
+ assertNull(Functions.yMax(emptyLineString));
+ }
+
+ @Test
+ public void boundsNonEmptyGeometry() throws ParseException {
+ Geometry polygon = Constructors.geomFromWKT("POLYGON ((-1 -11, 0 10, 1 11,
2 12, -1 -11))", 0);
+ assertEquals(-1.0, Functions.xMin(polygon), 1e-9);
+ assertEquals(2.0, Functions.xMax(polygon), 1e-9);
+ assertEquals(-11.0, Functions.yMin(polygon), 1e-9);
+ assertEquals(12.0, Functions.yMax(polygon), 1e-9);
+ }
+
@Test
public void angleFourPoints() {
Point start1 = GEOMETRY_FACTORY.createPoint(new Coordinate(0, 0));
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..ccc5d88bea 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
@@ -1188,12 +1188,12 @@ public class UDFs {
}
@UDFAnnotations.ParamMeta(argNames = {"geometry"})
- public static double ST_XMax(byte[] geometry) {
+ public static Double ST_XMax(byte[] geometry) {
return Functions.xMax(GeometrySerde.deserialize(geometry));
}
@UDFAnnotations.ParamMeta(argNames = {"geometry"})
- public static double ST_XMin(byte[] geometry) {
+ public static Double ST_XMin(byte[] geometry) {
return Functions.xMin(GeometrySerde.deserialize(geometry));
}
@@ -1203,12 +1203,12 @@ public class UDFs {
}
@UDFAnnotations.ParamMeta(argNames = {"geometry"})
- public static double ST_YMax(byte[] geometry) {
+ public static Double ST_YMax(byte[] geometry) {
return Functions.yMax(GeometrySerde.deserialize(geometry));
}
@UDFAnnotations.ParamMeta(argNames = {"geometry"})
- public static double ST_YMin(byte[] geometry) {
+ public static Double ST_YMin(byte[] geometry) {
return Functions.yMin(GeometrySerde.deserialize(geometry));
}
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..0cc7b4e622 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
@@ -1427,14 +1427,14 @@ public class UDFsV2 {
@UDFAnnotations.ParamMeta(
argNames = {"geometry"},
argTypes = {"Geometry"})
- public static double ST_XMax(String geometry) {
+ public static Double ST_XMax(String geometry) {
return Functions.xMax(GeometrySerde.deserGeoJson(geometry));
}
@UDFAnnotations.ParamMeta(
argNames = {"geometry"},
argTypes = {"Geometry"})
- public static double ST_XMin(String geometry) {
+ public static Double ST_XMin(String geometry) {
return Functions.xMin(GeometrySerde.deserGeoJson(geometry));
}
@@ -1448,14 +1448,14 @@ public class UDFsV2 {
@UDFAnnotations.ParamMeta(
argNames = {"geometry"},
argTypes = {"Geometry"})
- public static double ST_YMax(String geometry) {
+ public static Double ST_YMax(String geometry) {
return Functions.yMax(GeometrySerde.deserGeoJson(geometry));
}
@UDFAnnotations.ParamMeta(
argNames = {"geometry"},
argTypes = {"Geometry"})
- public static double ST_YMin(String geometry) {
+ public static Double ST_YMin(String geometry) {
return Functions.yMin(GeometrySerde.deserGeoJson(geometry));
}