You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by GitBox <gi...@apache.org> on 2022/11/03 20:41:37 UTC

[GitHub] [calcite] bchapuis opened a new pull request, #2962: [CALCITE-5362] Geometry measurement functions

bchapuis opened a new pull request, #2962:
URL: https://github.com/apache/calcite/pull/2962

   This PR adds support for the following spatial measurement functions:
   - ST_Area
   - ST_ClosestCoordinate
   - ST_ClosestPoint
   - ST_FurthestCoordinate
   - ST_Length
   - ST_LocateAlong
   - ST_LongestLine
   - ST_MaxDistance
   - ST_Perimeter
   - ST_ProjectPoint


-- 
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: commits-unsubscribe@calcite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [calcite] bchapuis commented on a diff in pull request #2962: [CALCITE-5362] Geometry measurement functions

Posted by GitBox <gi...@apache.org>.
bchapuis commented on code in PR #2962:
URL: https://github.com/apache/calcite/pull/2962#discussion_r1038610731


##########
core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java:
##########
@@ -1318,6 +1322,195 @@ public static Geometry ST_Translate(Geometry geom, BigDecimal x, BigDecimal y) {
     return transformation.transform(geom);
   }
 
+  // Geometry measurement functions
+
+  /**
+   * Returns the area of the {@code geom}.
+   */
+  public static @Nullable Double ST_Area(Geometry geom) {
+    return geom.getArea();

Review Comment:
   This is a good point, I fixed these two methods. I started adding test cases for null values after realizing that they were supported by postgis. I will open an issue to ensure that we are consistent when it come to null values in the other methods.



-- 
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: commits-unsubscribe@calcite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [calcite] bchapuis commented on a diff in pull request #2962: [CALCITE-5362] Geometry measurement functions

Posted by GitBox <gi...@apache.org>.
bchapuis commented on code in PR #2962:
URL: https://github.com/apache/calcite/pull/2962#discussion_r1038610731


##########
core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java:
##########
@@ -1318,6 +1322,195 @@ public static Geometry ST_Translate(Geometry geom, BigDecimal x, BigDecimal y) {
     return transformation.transform(geom);
   }
 
+  // Geometry measurement functions
+
+  /**
+   * Returns the area of the {@code geom}.
+   */
+  public static @Nullable Double ST_Area(Geometry geom) {
+    return geom.getArea();

Review Comment:
   This is a good point, I fixed these two methods. I started adding test cases for null values while working on this PR after realizing that they were supported by postgis. I opened [CALCITE-5419](https://issues.apache.org/jira/browse/CALCITE-5419) to ensure that we are consistent when it comes to null values in all the spatial functions.



-- 
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: commits-unsubscribe@calcite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [calcite] bchapuis commented on a diff in pull request #2962: [CALCITE-5362] Geometry measurement functions

Posted by GitBox <gi...@apache.org>.
bchapuis commented on code in PR #2962:
URL: https://github.com/apache/calcite/pull/2962#discussion_r1038610731


##########
core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java:
##########
@@ -1318,6 +1322,195 @@ public static Geometry ST_Translate(Geometry geom, BigDecimal x, BigDecimal y) {
     return transformation.transform(geom);
   }
 
+  // Geometry measurement functions
+
+  /**
+   * Returns the area of the {@code geom}.
+   */
+  public static @Nullable Double ST_Area(Geometry geom) {
+    return geom.getArea();

Review Comment:
   This is a good point, I fixed these two methods. I started adding test cases for null values after realizing that they were supported by postgis. I opened [CALCITE-5419](https://issues.apache.org/jira/browse/CALCITE-5419) to ensure that we are consistent when it comes to null values in all the spatial functions.



-- 
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: commits-unsubscribe@calcite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [calcite] bchapuis commented on a diff in pull request #2962: [CALCITE-5362] Geometry measurement functions

Posted by GitBox <gi...@apache.org>.
bchapuis commented on code in PR #2962:
URL: https://github.com/apache/calcite/pull/2962#discussion_r1039889386


##########
core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java:
##########
@@ -1318,6 +1322,195 @@ public static Geometry ST_Translate(Geometry geom, BigDecimal x, BigDecimal y) {
     return transformation.transform(geom);
   }
 
+  // Geometry measurement functions
+
+  /**
+   * Returns the area of the {@code geom}.
+   */
+  public static @Nullable Double ST_Area(Geometry geom) {
+    return geom.getArea();

Review Comment:
   Thanks a lot for the clarification and the pointers.



-- 
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: commits-unsubscribe@calcite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [calcite] bchapuis commented on a diff in pull request #2962: [CALCITE-5362] Geometry measurement functions

Posted by GitBox <gi...@apache.org>.
bchapuis commented on code in PR #2962:
URL: https://github.com/apache/calcite/pull/2962#discussion_r1038610731


##########
core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java:
##########
@@ -1318,6 +1322,195 @@ public static Geometry ST_Translate(Geometry geom, BigDecimal x, BigDecimal y) {
     return transformation.transform(geom);
   }
 
+  // Geometry measurement functions
+
+  /**
+   * Returns the area of the {@code geom}.
+   */
+  public static @Nullable Double ST_Area(Geometry geom) {
+    return geom.getArea();

Review Comment:
   This is a good point, I fixed these two methods. I started adding test cases for null values after realizing that they were supported by postgis. I opened [CALCITE-5419](https://issues.apache.org/jira/browse/CALCITE-5419) to ensure that we are consistent when it comes to null values in the methods not covered by this PR.



-- 
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: commits-unsubscribe@calcite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [calcite] rubenada commented on a diff in pull request #2962: [CALCITE-5362] Geometry measurement functions

Posted by GitBox <gi...@apache.org>.
rubenada commented on code in PR #2962:
URL: https://github.com/apache/calcite/pull/2962#discussion_r1037941963


##########
core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java:
##########
@@ -1318,6 +1322,195 @@ public static Geometry ST_Translate(Geometry geom, BigDecimal x, BigDecimal y) {
     return transformation.transform(geom);
   }
 
+  // Geometry measurement functions
+
+  /**
+   * Returns the area of the {@code geom}.
+   */
+  public static @Nullable Double ST_Area(Geometry geom) {
+    return geom.getArea();

Review Comment:
   Just curious: why `ST_Area` and  `ST_Length` don't have a null-check and the other methods do?



-- 
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: commits-unsubscribe@calcite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [calcite] bchapuis commented on a diff in pull request #2962: [CALCITE-5362] Geometry measurement functions

Posted by GitBox <gi...@apache.org>.
bchapuis commented on code in PR #2962:
URL: https://github.com/apache/calcite/pull/2962#discussion_r1038614126


##########
core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java:
##########
@@ -1318,6 +1322,195 @@ public static Geometry ST_Translate(Geometry geom, BigDecimal x, BigDecimal y) {
     return transformation.transform(geom);
   }
 
+  // Geometry measurement functions
+
+  /**
+   * Returns the area of the {@code geom}.
+   */
+  public static @Nullable Double ST_Area(Geometry geom) {
+    return geom.getArea();
+  }
+
+  /**
+   * Returns the coordinate(s) of {@code geom} closest to {@code point}.
+   */
+  public static @Nullable Geometry ST_ClosestCoordinate(Geometry point, Geometry geom) {
+    if (point == null || geom == null) {
+      return null;
+    }
+    List<Coordinate> closestCoordinates = new ArrayList<>();
+    double minDistance = Double.MAX_VALUE;
+    for (Coordinate coordinate : geom.getCoordinates()) {
+      double distance = point.getCoordinate().distance(coordinate);
+      if (distance < minDistance) {
+        minDistance = distance;
+        closestCoordinates.clear();
+        closestCoordinates.add(coordinate);
+      } else if (distance == minDistance && !closestCoordinates.contains(coordinate)) {
+        closestCoordinates.add(coordinate);
+      }
+    }
+    if (closestCoordinates.size() == 1) {
+      return GEOMETRY_FACTORY.createPoint(closestCoordinates.get(0));
+    } else {
+      Coordinate[] coordinates = closestCoordinates.toArray(new Coordinate[0]);
+      return GEOMETRY_FACTORY.createMultiPointFromCoords(coordinates);
+    }
+  }
+
+  /**
+   * Returns the point of {@code geom1} closest to {@code geom2}.
+   */
+  public static @Nullable Geometry ST_ClosestPoint(Geometry geom1, Geometry geom2) {
+    if (geom1 == null || geom2 == null) {
+      return null;
+    }
+    return GEOMETRY_FACTORY.createPoint(DistanceOp.nearestPoints(geom1, geom2)[0]);
+  }
+
+  /**
+   * Returns the coordinate(s) of {@code geom} furthest from {@code point}.
+   */
+  public static @Nullable Geometry ST_FurthestCoordinate(Geometry point, Geometry geom) {
+    if (point == null || geom == null) {
+      return null;
+    }
+    List<Coordinate> closestCoordinates = new ArrayList<>();
+    double maxDistance = Double.MIN_VALUE;
+    for (Coordinate coordinate : geom.getCoordinates()) {
+      double distance = point.getCoordinate().distance(coordinate);
+      if (distance > maxDistance) {
+        maxDistance = distance;
+        closestCoordinates.clear();
+        closestCoordinates.add(coordinate);
+      } else if (distance == maxDistance && !closestCoordinates.contains(coordinate)) {
+        closestCoordinates.add(coordinate);
+      }
+    }
+    if (closestCoordinates.size() == 1) {
+      return GEOMETRY_FACTORY.createPoint(closestCoordinates.get(0));
+    } else {
+      Coordinate[] coordinates = closestCoordinates.toArray(new Coordinate[0]);
+      return GEOMETRY_FACTORY.createMultiPointFromCoords(coordinates);
+    }
+  }
+
+  /**
+   * Returns the length of the {@code geom}.
+   */
+  public static @Nullable Double ST_Length(Geometry geom) {
+    return geom.getLength();
+  }
+
+  /**
+   * Returns a MULTIPOINT containing points along the line segments of {@code geom}
+   * at {@code segmentLengthFraction} and {@code offsetDistance}.
+   */
+  public static @Nullable Geometry ST_LocateAlong(Geometry geom, BigDecimal segmentLengthFraction,
+      BigDecimal offsetDistance) {
+    if (geom == null) {
+      return null;
+    }
+    if (segmentLengthFraction == null) {
+      segmentLengthFraction = BigDecimal.ZERO;
+    }
+    if (offsetDistance == null) {
+      offsetDistance = BigDecimal.ZERO;
+    }
+    List<Coordinate> coordinates = new ArrayList<>();
+    for (int i = 0; i < geom.getNumGeometries(); i++) {
+      Geometry geometry = geom.getGeometryN(i);
+      Coordinate[] geometryCoordinates = geometry.getCoordinates();
+      for (int j = 0; j < geometryCoordinates.length - 1; j++) {
+        Coordinate c1 = geometryCoordinates[j];
+        Coordinate c2 = geometryCoordinates[j + 1];
+        LineSegment lineSegment = new LineSegment(c1, c2);
+        coordinates.add(
+            lineSegment.pointAlongOffset(
+            segmentLengthFraction.doubleValue(),
+            offsetDistance.doubleValue()));
+      }
+    }
+    Coordinate[] coordinateArray = coordinates.toArray(new Coordinate[0]);
+    return GEOMETRY_FACTORY.createMultiPointFromCoords(coordinateArray);
+  }
+
+  /**
+   * Returns the 2-dimensional longest line-string between the points
+   * of {@code geom1} and {@code geom2}.
+   */
+  public static @Nullable Geometry ST_LongestLine(Geometry geom1, Geometry geom2) {
+    if (geom1 == null || geom2 == null) {
+      return null;
+    }
+    double maxDistance = Double.MIN_VALUE;
+    Coordinate c1 = null;
+    Coordinate c2 = null;
+    for (Coordinate coordinate1 : geom1.getCoordinates()) {
+      for (Coordinate coordinate2 : geom2.getCoordinates()) {
+        double distance = coordinate1.distance(coordinate2);
+        if (distance > maxDistance) {
+          maxDistance = distance;
+          c1 = coordinate1;
+          c2 = coordinate2;
+        }
+      }
+    }
+    if (c1 == null || c2 == null) {
+      return null;
+    }
+    return GEOMETRY_FACTORY.createLineString(new Coordinate[] {c1, c2});
+  }
+
+  /**
+   * Computes the maximum distance between {@code geom1} and {@code geom2}.
+   */
+  public static @Nullable Double ST_MaxDistance(Geometry geom1, Geometry geom2) {
+    if (geom1 == null || geom2 == null) {
+      return null;
+    }
+    double maxDistance = Double.MIN_VALUE;
+    for (Coordinate coordinate1 : geom1.getCoordinates()) {
+      for (Coordinate coordinate2 : geom2.getCoordinates()) {
+        double distance = coordinate1.distance(coordinate2);
+        if (distance > maxDistance) {
+          maxDistance = distance;
+        }
+      }
+    }
+    return maxDistance;
+  }
+
+  /**
+   * Returns the length of the perimeter of *polygon* (which may be a MULTIPOLYGON).
+   */
+  public static @Nullable Double ST_Perimeter(Geometry geom) {
+    if (geom == null) {
+      return null;
+    }
+    double perimeter = 0;
+    for (int i = 0; i < geom.getNumGeometries(); i++) {
+      Geometry geometry = geom.getGeometryN(i);
+      if (geometry instanceof Polygon) {
+        perimeter += geometry.getLength();
+      }
+    }
+    return perimeter;
+  }
+
+  public static @Nullable Geometry ST_ProjectPoint(Geometry point, Geometry line) {

Review Comment:
   Thank you, I added the javadoc.



-- 
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: commits-unsubscribe@calcite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [calcite] bchapuis commented on a diff in pull request #2962: [CALCITE-5362] Geometry measurement functions

Posted by GitBox <gi...@apache.org>.
bchapuis commented on code in PR #2962:
URL: https://github.com/apache/calcite/pull/2962#discussion_r1038610731


##########
core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java:
##########
@@ -1318,6 +1322,195 @@ public static Geometry ST_Translate(Geometry geom, BigDecimal x, BigDecimal y) {
     return transformation.transform(geom);
   }
 
+  // Geometry measurement functions
+
+  /**
+   * Returns the area of the {@code geom}.
+   */
+  public static @Nullable Double ST_Area(Geometry geom) {
+    return geom.getArea();

Review Comment:
   This is a good point, I fixed these two methods. I started adding test cases for null values after realizing that they were supported by postgis. I will open an issue to ensure that we are consistent when it come to null values in the methods not covered by this PR.



-- 
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: commits-unsubscribe@calcite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [calcite] rubenada commented on a diff in pull request #2962: [CALCITE-5362] Geometry measurement functions

Posted by GitBox <gi...@apache.org>.
rubenada commented on code in PR #2962:
URL: https://github.com/apache/calcite/pull/2962#discussion_r1039714696


##########
core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java:
##########
@@ -1318,6 +1322,195 @@ public static Geometry ST_Translate(Geometry geom, BigDecimal x, BigDecimal y) {
     return transformation.transform(geom);
   }
 
+  // Geometry measurement functions
+
+  /**
+   * Returns the area of the {@code geom}.
+   */
+  public static @Nullable Double ST_Area(Geometry geom) {
+    return geom.getArea();

Review Comment:
   Yes, you're right.
   If I am not mistaken, the "magic" happens because the `SpatialTypeFunctions.java` class uses `@Strict` annotation, which means all its methods will have [NullPolicy.STRICT](https://github.com/apache/calcite/blob/33ca193095fcd0db46b88a270bca8d8cd569b31a/core/src/main/java/org/apache/calcite/adapter/enumerable/NullPolicy.java#L31) via [ScalaFunctionImpl#getNullPolicy](https://github.com/apache/calcite/blob/33ca193095fcd0db46b88a270bca8d8cd569b31a/core/src/main/java/org/apache/calcite/schema/impl/ScalarFunctionImpl.java#L171) and this null policy means that the function "Returns null if and only if one of the arguments are null", so with this information Calcite will generate the null-check-related code before actually reaching the specific SpatialTypeFunctions.ST_* implementation.
   To sum up, yes, I think the current code (without null check) is correct.



-- 
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: commits-unsubscribe@calcite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [calcite] bchapuis merged pull request #2962: [CALCITE-5362] Geometry measurement functions

Posted by GitBox <gi...@apache.org>.
bchapuis merged PR #2962:
URL: https://github.com/apache/calcite/pull/2962


-- 
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: commits-unsubscribe@calcite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [calcite] rubenada commented on a diff in pull request #2962: [CALCITE-5362] Geometry measurement functions

Posted by GitBox <gi...@apache.org>.
rubenada commented on code in PR #2962:
URL: https://github.com/apache/calcite/pull/2962#discussion_r1037942435


##########
core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java:
##########
@@ -1318,6 +1322,195 @@ public static Geometry ST_Translate(Geometry geom, BigDecimal x, BigDecimal y) {
     return transformation.transform(geom);
   }
 
+  // Geometry measurement functions
+
+  /**
+   * Returns the area of the {@code geom}.
+   */
+  public static @Nullable Double ST_Area(Geometry geom) {
+    return geom.getArea();
+  }
+
+  /**
+   * Returns the coordinate(s) of {@code geom} closest to {@code point}.
+   */
+  public static @Nullable Geometry ST_ClosestCoordinate(Geometry point, Geometry geom) {
+    if (point == null || geom == null) {
+      return null;
+    }
+    List<Coordinate> closestCoordinates = new ArrayList<>();
+    double minDistance = Double.MAX_VALUE;
+    for (Coordinate coordinate : geom.getCoordinates()) {
+      double distance = point.getCoordinate().distance(coordinate);
+      if (distance < minDistance) {
+        minDistance = distance;
+        closestCoordinates.clear();
+        closestCoordinates.add(coordinate);
+      } else if (distance == minDistance && !closestCoordinates.contains(coordinate)) {
+        closestCoordinates.add(coordinate);
+      }
+    }
+    if (closestCoordinates.size() == 1) {
+      return GEOMETRY_FACTORY.createPoint(closestCoordinates.get(0));
+    } else {
+      Coordinate[] coordinates = closestCoordinates.toArray(new Coordinate[0]);
+      return GEOMETRY_FACTORY.createMultiPointFromCoords(coordinates);
+    }
+  }
+
+  /**
+   * Returns the point of {@code geom1} closest to {@code geom2}.
+   */
+  public static @Nullable Geometry ST_ClosestPoint(Geometry geom1, Geometry geom2) {
+    if (geom1 == null || geom2 == null) {
+      return null;
+    }
+    return GEOMETRY_FACTORY.createPoint(DistanceOp.nearestPoints(geom1, geom2)[0]);
+  }
+
+  /**
+   * Returns the coordinate(s) of {@code geom} furthest from {@code point}.
+   */
+  public static @Nullable Geometry ST_FurthestCoordinate(Geometry point, Geometry geom) {
+    if (point == null || geom == null) {
+      return null;
+    }
+    List<Coordinate> closestCoordinates = new ArrayList<>();
+    double maxDistance = Double.MIN_VALUE;
+    for (Coordinate coordinate : geom.getCoordinates()) {
+      double distance = point.getCoordinate().distance(coordinate);
+      if (distance > maxDistance) {
+        maxDistance = distance;
+        closestCoordinates.clear();
+        closestCoordinates.add(coordinate);
+      } else if (distance == maxDistance && !closestCoordinates.contains(coordinate)) {
+        closestCoordinates.add(coordinate);
+      }
+    }
+    if (closestCoordinates.size() == 1) {
+      return GEOMETRY_FACTORY.createPoint(closestCoordinates.get(0));
+    } else {
+      Coordinate[] coordinates = closestCoordinates.toArray(new Coordinate[0]);
+      return GEOMETRY_FACTORY.createMultiPointFromCoords(coordinates);
+    }
+  }
+
+  /**
+   * Returns the length of the {@code geom}.
+   */
+  public static @Nullable Double ST_Length(Geometry geom) {
+    return geom.getLength();
+  }
+
+  /**
+   * Returns a MULTIPOINT containing points along the line segments of {@code geom}
+   * at {@code segmentLengthFraction} and {@code offsetDistance}.
+   */
+  public static @Nullable Geometry ST_LocateAlong(Geometry geom, BigDecimal segmentLengthFraction,
+      BigDecimal offsetDistance) {
+    if (geom == null) {
+      return null;
+    }
+    if (segmentLengthFraction == null) {
+      segmentLengthFraction = BigDecimal.ZERO;
+    }
+    if (offsetDistance == null) {
+      offsetDistance = BigDecimal.ZERO;
+    }
+    List<Coordinate> coordinates = new ArrayList<>();
+    for (int i = 0; i < geom.getNumGeometries(); i++) {
+      Geometry geometry = geom.getGeometryN(i);
+      Coordinate[] geometryCoordinates = geometry.getCoordinates();
+      for (int j = 0; j < geometryCoordinates.length - 1; j++) {
+        Coordinate c1 = geometryCoordinates[j];
+        Coordinate c2 = geometryCoordinates[j + 1];
+        LineSegment lineSegment = new LineSegment(c1, c2);
+        coordinates.add(
+            lineSegment.pointAlongOffset(
+            segmentLengthFraction.doubleValue(),
+            offsetDistance.doubleValue()));
+      }
+    }
+    Coordinate[] coordinateArray = coordinates.toArray(new Coordinate[0]);
+    return GEOMETRY_FACTORY.createMultiPointFromCoords(coordinateArray);
+  }
+
+  /**
+   * Returns the 2-dimensional longest line-string between the points
+   * of {@code geom1} and {@code geom2}.
+   */
+  public static @Nullable Geometry ST_LongestLine(Geometry geom1, Geometry geom2) {
+    if (geom1 == null || geom2 == null) {
+      return null;
+    }
+    double maxDistance = Double.MIN_VALUE;
+    Coordinate c1 = null;
+    Coordinate c2 = null;
+    for (Coordinate coordinate1 : geom1.getCoordinates()) {
+      for (Coordinate coordinate2 : geom2.getCoordinates()) {
+        double distance = coordinate1.distance(coordinate2);
+        if (distance > maxDistance) {
+          maxDistance = distance;
+          c1 = coordinate1;
+          c2 = coordinate2;
+        }
+      }
+    }
+    if (c1 == null || c2 == null) {
+      return null;
+    }
+    return GEOMETRY_FACTORY.createLineString(new Coordinate[] {c1, c2});
+  }
+
+  /**
+   * Computes the maximum distance between {@code geom1} and {@code geom2}.
+   */
+  public static @Nullable Double ST_MaxDistance(Geometry geom1, Geometry geom2) {
+    if (geom1 == null || geom2 == null) {
+      return null;
+    }
+    double maxDistance = Double.MIN_VALUE;
+    for (Coordinate coordinate1 : geom1.getCoordinates()) {
+      for (Coordinate coordinate2 : geom2.getCoordinates()) {
+        double distance = coordinate1.distance(coordinate2);
+        if (distance > maxDistance) {
+          maxDistance = distance;
+        }
+      }
+    }
+    return maxDistance;
+  }
+
+  /**
+   * Returns the length of the perimeter of *polygon* (which may be a MULTIPOLYGON).
+   */
+  public static @Nullable Double ST_Perimeter(Geometry geom) {
+    if (geom == null) {
+      return null;
+    }
+    double perimeter = 0;
+    for (int i = 0; i < geom.getNumGeometries(); i++) {
+      Geometry geometry = geom.getGeometryN(i);
+      if (geometry instanceof Polygon) {
+        perimeter += geometry.getLength();
+      }
+    }
+    return perimeter;
+  }
+
+  public static @Nullable Geometry ST_ProjectPoint(Geometry point, Geometry line) {

Review Comment:
   Minor: javadoc seems to be missing here.



-- 
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: commits-unsubscribe@calcite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [calcite] bchapuis commented on a diff in pull request #2962: [CALCITE-5362] Geometry measurement functions

Posted by GitBox <gi...@apache.org>.
bchapuis commented on code in PR #2962:
URL: https://github.com/apache/calcite/pull/2962#discussion_r1039023021


##########
core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java:
##########
@@ -1318,6 +1322,195 @@ public static Geometry ST_Translate(Geometry geom, BigDecimal x, BigDecimal y) {
     return transformation.transform(geom);
   }
 
+  // Geometry measurement functions
+
+  /**
+   * Returns the area of the {@code geom}.
+   */
+  public static @Nullable Double ST_Area(Geometry geom) {
+    return geom.getArea();

Review Comment:
   After reading a the javadoc for [SqlFunctions](https://javadoc.io/doc/org.apache.calcite/calcite-core/1.26.0/org/apache/calcite/runtime/SqlFunctions.html), it looks like checks for nulls are performed by Calcite before calling the functions. From what I understand, the default behavior is as follow: the functions always return null if one or more of its arguments are null. As this behavior looks similar to what postgis does, I removed all my null checks. Can you confirm that this is the right approach?



##########
core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java:
##########
@@ -1318,6 +1322,195 @@ public static Geometry ST_Translate(Geometry geom, BigDecimal x, BigDecimal y) {
     return transformation.transform(geom);
   }
 
+  // Geometry measurement functions
+
+  /**
+   * Returns the area of the {@code geom}.
+   */
+  public static @Nullable Double ST_Area(Geometry geom) {
+    return geom.getArea();

Review Comment:
   @rubenada After reading a the javadoc for [SqlFunctions](https://javadoc.io/doc/org.apache.calcite/calcite-core/1.26.0/org/apache/calcite/runtime/SqlFunctions.html), it looks like checks for nulls are performed by Calcite before calling the functions. From what I understand, the default behavior is as follow: the functions always return null if one or more of its arguments are null. As this behavior looks similar to what postgis does, I removed all my null checks. Can you confirm that this is the right approach?



-- 
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: commits-unsubscribe@calcite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [calcite] bchapuis commented on a diff in pull request #2962: [CALCITE-5362] Geometry measurement functions

Posted by GitBox <gi...@apache.org>.
bchapuis commented on code in PR #2962:
URL: https://github.com/apache/calcite/pull/2962#discussion_r1038610731


##########
core/src/main/java/org/apache/calcite/runtime/SpatialTypeFunctions.java:
##########
@@ -1318,6 +1322,195 @@ public static Geometry ST_Translate(Geometry geom, BigDecimal x, BigDecimal y) {
     return transformation.transform(geom);
   }
 
+  // Geometry measurement functions
+
+  /**
+   * Returns the area of the {@code geom}.
+   */
+  public static @Nullable Double ST_Area(Geometry geom) {
+    return geom.getArea();

Review Comment:
   This is a good point, I fixed these two methods. I started adding test cases for null values after realizing that they were supported by postgis. I opened [CALCITE-5419](https://issues.apache.org/jira/browse/CALCITE-5419) to ensure that we are consistent when it come to null values in the methods not covered by this PR.



-- 
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: commits-unsubscribe@calcite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org