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-unsubscr...@calcite.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org