use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class GeoFunctions method stGeometryN.
@SqlNullable
@Description("Returns the geometry element at the specified index (indices started with 1)")
@ScalarFunction("ST_GeometryN")
@SqlType(GEOMETRY_TYPE_NAME)
public static Slice stGeometryN(@SqlType(GEOMETRY_TYPE_NAME) Slice input, @SqlType(INTEGER) long index) {
OGCGeometry geometry = deserialize(input);
if (geometry.isEmpty()) {
return null;
}
GeometryType type = GeometryType.getForEsriGeometryType(geometry.geometryType());
if (!type.isMultitype()) {
if (index == 1) {
return input;
}
return null;
}
OGCGeometryCollection geometryCollection = ((OGCGeometryCollection) geometry);
if (index < 1 || index > geometryCollection.numGeometries()) {
return null;
}
OGCGeometry ogcGeometry = geometryCollection.geometryN((int) index - 1);
return serialize(ogcGeometry);
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class GeoFunctions method stTouches.
@SqlNullable
@Description("Returns TRUE if the geometries have at least one point in common, but their interiors do not intersect")
@ScalarFunction("ST_Touches")
@SqlType(BOOLEAN)
public static Boolean stTouches(@SqlType(GEOMETRY_TYPE_NAME) Slice left, @SqlType(GEOMETRY_TYPE_NAME) Slice right) {
if (!envelopes(left, right, Envelope::intersect)) {
return false;
}
OGCGeometry leftGeometry = deserialize(left);
OGCGeometry rightGeometry = deserialize(right);
verifySameSpatialReference(leftGeometry, rightGeometry);
return leftGeometry.touches(rightGeometry);
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class GeoFunctions method stLineString.
@Description("Returns a LineString from an array of points")
@ScalarFunction("ST_LineString")
@SqlType(GEOMETRY_TYPE_NAME)
public static Slice stLineString(@SqlType("array(" + GEOMETRY_TYPE_NAME + ")") Block input) {
MultiPath multipath = new Polyline();
OGCPoint previousPoint = null;
for (int i = 0; i < input.getPositionCount(); i++) {
Slice slice = GEOMETRY.getSlice(input, i);
if (slice.getInput().available() == 0) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, format("Invalid input to ST_LineString: null point at index %s", i + 1));
}
OGCGeometry geometry = deserialize(slice);
if (!(geometry instanceof OGCPoint)) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, format("ST_LineString takes only an array of valid points, %s was passed", geometry.geometryType()));
}
OGCPoint point = (OGCPoint) geometry;
if (point.isEmpty()) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, format("Invalid input to ST_LineString: empty point at index %s", i + 1));
}
if (previousPoint == null) {
multipath.startPath(point.X(), point.Y());
} else {
if (point.Equals(previousPoint)) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, format("Invalid input to ST_LineString: consecutive duplicate points at index %s", i + 1));
}
multipath.lineTo(point.X(), point.Y());
}
previousPoint = point;
}
OGCLineString linestring = new OGCLineString(multipath, 0, null);
return serialize(linestring);
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class GeoFunctions method stPointN.
@SqlNullable
@Description("Returns the vertex of a linestring at the specified index (indices started with 1) ")
@ScalarFunction("ST_PointN")
@SqlType(GEOMETRY_TYPE_NAME)
public static Slice stPointN(@SqlType(GEOMETRY_TYPE_NAME) Slice input, @SqlType(INTEGER) long index) {
OGCGeometry geometry = deserialize(input);
validateType("ST_PointN", geometry, EnumSet.of(LINE_STRING));
OGCLineString linestring = (OGCLineString) geometry;
if (index < 1 || index > linestring.numPoints()) {
return null;
}
return serialize(linestring.pointN(toIntExact(index) - 1));
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class GeoFunctions method lineLocatePoint.
@SqlNullable
@Description("Returns a float between 0 and 1 representing the location of the closest point on the LineString to the given Point, as a fraction of total 2d line length.")
@ScalarFunction("line_locate_point")
@SqlType(DOUBLE)
public static Double lineLocatePoint(@SqlType(GEOMETRY_TYPE_NAME) Slice lineSlice, @SqlType(GEOMETRY_TYPE_NAME) Slice pointSlice) {
Geometry line = JtsGeometrySerde.deserialize(lineSlice);
Geometry point = JtsGeometrySerde.deserialize(pointSlice);
if (line.isEmpty() || point.isEmpty()) {
return null;
}
GeometryType lineType = GeometryType.getForJtsGeometryType(line.getGeometryType());
if (lineType != GeometryType.LINE_STRING && lineType != GeometryType.MULTI_LINE_STRING) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, format("First argument to line_locate_point must be a LineString or a MultiLineString. Got: %s", line.getGeometryType()));
}
GeometryType pointType = GeometryType.getForJtsGeometryType(point.getGeometryType());
if (pointType != GeometryType.POINT) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, format("Second argument to line_locate_point must be a Point. Got: %s", point.getGeometryType()));
}
return new LengthIndexedLine(line).indexOf(point.getCoordinate()) / line.getLength();
}
Aggregations