ayushtkn commented on code in PR #6581:
URL: https://github.com/apache/hive/pull/6581#discussion_r3653186891


##########
ql/src/java/org/apache/hadoop/hive/ql/udf/esri/ST_GeodesicLengthWGS84.java:
##########
@@ -66,37 +70,100 @@ public DoubleWritable evaluate(BytesWritable geomref) {
       return null;
     }
 
-    OGCGeometry ogcGeometry = GeometryUtils.geometryFromEsriShape(geomref);
-    if (ogcGeometry == null) {
+    Geometry geom = GeometryUtils.geometryFromEsriShape(geomref);
+    if (geom == null) {
       LogUtils.Log_ArgumentsNull(LOG);
       return null;
     }
 
-    Geometry esriGeom = ogcGeometry.getEsriGeometry();
-    switch (esriGeom.getType()) {
-    case Point:
-    case MultiPoint:
-      resultDouble.set(0.);
-      break;
-    default:
-      MultiPath lines = (MultiPath) (esriGeom);
-      int nPath = lines.getPathCount();
-      double length = 0.;
-      for (int ix = 0; ix < nPath; ix++) {
-        int curPt = lines.getPathStart(ix);
-        int pastPt = lines.getPathEnd(ix);
-        Point fromPt = lines.getPoint(curPt);
-        Point toPt = null;
-        for (int vx = curPt + 1; vx < pastPt; vx++) {
-          toPt = lines.getPoint(vx);
-          length += GeometryEngine.geodesicDistanceOnWGS84(fromPt, toPt);
-          fromPt = toPt;
+    switch (geom.getGeometryType()) {
+      case "Point", "MultiPoint" -> resultDouble.set(0.0);
+      case "LineString", "LinearRing" -> 
resultDouble.set(lineStringLength((LineString) geom));
+      case "MultiLineString" -> {
+        MultiLineString mls = (MultiLineString) geom;
+        double total = 0.0;
+        for (int i = 0; i < mls.getNumGeometries(); i++) {
+          total += lineStringLength((LineString) mls.getGeometryN(i));
         }
+        resultDouble.set(total);
       }
-      resultDouble.set(length);
-      break;
+      default -> resultDouble.set(0.0);
     }
 
     return resultDouble;
   }
+
+  /**
+   * Computes the geodesic length of a single LineString by summing the 
ellipsoidal
+   * (WGS84) distances between consecutive vertices.  Iterates the 
CoordinateSequence
+   * directly to avoid per-vertex Point object allocation.
+   */
+  private static double lineStringLength(LineString line) {
+    CoordinateSequence seq = line.getCoordinateSequence();
+    int nPts = seq.size();
+    if (nPts < 2) {
+      return 0.0;
+    }
+    double length = 0.0;
+    for (int i = 1; i < nPts; i++) {
+      length += vincentyDistanceMeters(
+          seq.getX(i - 1), seq.getY(i - 1),
+          seq.getX(i), seq.getY(i));
+    }
+    return length;
+  }
+
+  /**
+   * Ellipsoidal geodesic distance between two lon/lat points on the WGS84 
spheroid,
+   * using Vincenty's inverse formula (the same ellipsoidal model the ESRI 
library used,
+   * so results match the previous implementation).  Coordinates are in 
degrees, result

Review Comment:
   Reverted the reimplementation. ST_GeodesicLengthWGS84 delegates to 
GeometryEngine.geodesicDistanceOnWGS84.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to