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 f8bc4d3220 [SEDONA-672] Bug fix for ST_LengthSpheroid (#1679)
f8bc4d3220 is described below
commit f8bc4d3220418a1b70396f41c793b408a04a0903
Author: Furqaan Khan <[email protected]>
AuthorDate: Thu Nov 7 21:26:02 2024 -0500
[SEDONA-672] Bug fix for ST_LengthSpheroid (#1679)
---
.../org/apache/sedona/common/sphere/Spheroid.java | 21 +++++++++++++++++----
.../org/apache/sedona/common/FunctionsTest.java | 22 ++++++++++++++--------
2 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/common/src/main/java/org/apache/sedona/common/sphere/Spheroid.java
b/common/src/main/java/org/apache/sedona/common/sphere/Spheroid.java
index 986d66a4c5..50a3beb77b 100644
--- a/common/src/main/java/org/apache/sedona/common/sphere/Spheroid.java
+++ b/common/src/main/java/org/apache/sedona/common/sphere/Spheroid.java
@@ -27,6 +27,7 @@ import net.sf.geographiclib.PolygonResult;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.Polygon;
public class Spheroid {
// Standard EPSG Codes
@@ -79,7 +80,8 @@ public class Spheroid {
*/
public static double length(Geometry geom) {
String geomType = geom.getGeometryType();
- if (geomType.equals("Polygon") || geomType.equals("LineString")) {
+ if (geomType.equals(Geometry.TYPENAME_LINEARRING)
+ || geomType.equals(Geometry.TYPENAME_LINESTRING)) {
PolygonArea p = new PolygonArea(Geodesic.WGS84, true);
Coordinate[] coordinates = geom.getCoordinates();
for (int i = 0; i < coordinates.length; i++) {
@@ -89,9 +91,20 @@ public class Spheroid {
}
PolygonResult compute = p.Compute();
return compute.perimeter;
- } else if (geomType.equals("MultiPolygon")
- || geomType.equals("MultiLineString")
- || geomType.equals("GeometryCollection")) {
+ } else if (geomType.equals(Geometry.TYPENAME_POLYGON)) {
+ Polygon poly = (Polygon) geom;
+ double length = length(poly.getExteriorRing());
+
+ if (poly.getNumInteriorRing() > 0) {
+ for (int i = 0; i < poly.getNumInteriorRing(); i++) {
+ length += length(poly.getInteriorRingN(i));
+ }
+ }
+
+ return length;
+ } else if (geomType.equals(Geometry.TYPENAME_MULTIPOLYGON)
+ || geomType.equals(Geometry.TYPENAME_MULTILINESTRING)
+ || geomType.equals(Geometry.TYPENAME_GEOMETRYCOLLECTION)) {
double length = 0.0;
for (int i = 0; i < geom.getNumGeometries(); i++) {
length += length(geom.getGeometryN(i));
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 926aa77dcb..e9e9af6322 100644
--- a/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
+++ b/common/src/test/java/org/apache/sedona/common/FunctionsTest.java
@@ -1614,30 +1614,36 @@ public class FunctionsTest extends TestBase {
}
@Test
- public void spheroidLength() {
+ public void spheroidLength() throws ParseException {
Point point = GEOMETRY_FACTORY.createPoint(new Coordinate(90, 0));
- assertEquals(0, Spheroid.length(point), 0.1);
+ assertEquals(0, Spheroid.length(point), FP_TOLERANCE2);
LineString line = GEOMETRY_FACTORY.createLineString(coordArray(0, 0, 90,
0));
- assertEquals(1.0018754171394622E7, Spheroid.length(line), 0.1);
+ assertEquals(1.0018754171394622E7, Spheroid.length(line), FP_TOLERANCE2);
Polygon polygon = GEOMETRY_FACTORY.createPolygon(coordArray(0, 0, 90, 0,
0, 0));
- assertEquals(2.0037508342789244E7, Spheroid.length(polygon), 0.1);
+ assertEquals(2.0037508342789244E7, Spheroid.length(polygon),
FP_TOLERANCE2);
MultiPoint multiPoint = GEOMETRY_FACTORY.createMultiPoint(new Point[]
{point, point});
- assertEquals(0, Spheroid.length(multiPoint), 0.1);
+ assertEquals(0, Spheroid.length(multiPoint), FP_TOLERANCE2);
MultiLineString multiLineString =
GEOMETRY_FACTORY.createMultiLineString(new LineString[] {line, line});
- assertEquals(2.0037508342789244E7, Spheroid.length(multiLineString), 0.1);
+ assertEquals(2.0037508342789244E7, Spheroid.length(multiLineString),
FP_TOLERANCE2);
MultiPolygon multiPolygon =
GEOMETRY_FACTORY.createMultiPolygon(new Polygon[] {polygon, polygon});
- assertEquals(4.007501668557849E7, Spheroid.length(multiPolygon), 0.1);
+ assertEquals(4.007501668557849E7, Spheroid.length(multiPolygon),
FP_TOLERANCE2);
GeometryCollection geometryCollection =
GEOMETRY_FACTORY.createGeometryCollection(new Geometry[] {point, line,
multiLineString});
- assertEquals(3.0056262514183864E7, Spheroid.length(geometryCollection),
0.1);
+ assertEquals(3.0056262514183864E7, Spheroid.length(geometryCollection),
FP_TOLERANCE2);
+
+ Geometry polygonWithHole =
+ Constructors.geomFromWKT(
+ "POLYGON((-122.33 47.61, -122.32 47.62, -122.31 47.61, -122.30
47.62, -122.29 47.61, -122.30 47.60, -122.31 47.59, -122.32 47.60, -122.33
47.61), (-122.315 47.605, -122.305 47.615, -122.295 47.605, -122.305 47.595,
-122.315 47.605))",
+ 4326);
+ assertEquals(16106.506409488933, Spheroid.length(polygonWithHole),
FP_TOLERANCE2);
}
@Test