use of io.prestosql.spi.function.SqlNullable in project hetu-core by openlookeng.
the class GeoFunctions method stRelate.
@SqlNullable
@Description("Returns TRUE if this Geometry is spatially related to another Geometry")
@ScalarFunction("ST_Relate")
@SqlType(BOOLEAN)
public static Boolean stRelate(@SqlType(GEOMETRY_TYPE_NAME) Slice left, @SqlType(GEOMETRY_TYPE_NAME) Slice right, @SqlType(VARCHAR) Slice relation) {
OGCGeometry leftGeometry = deserialize(left);
OGCGeometry rightGeometry = deserialize(right);
verifySameSpatialReference(leftGeometry, rightGeometry);
return leftGeometry.relate(rightGeometry, relation.toStringUtf8());
}
use of io.prestosql.spi.function.SqlNullable in project hetu-core by openlookeng.
the class GeoFunctions method stSphericalDistance.
@SqlNullable
@Description("Returns the great-circle distance in meters between two SphericalGeography points.")
@ScalarFunction("ST_Distance")
@SqlType(DOUBLE)
public static Double stSphericalDistance(@SqlType(SPHERICAL_GEOGRAPHY_TYPE_NAME) Slice left, @SqlType(SPHERICAL_GEOGRAPHY_TYPE_NAME) Slice right) {
OGCGeometry leftGeometry = deserialize(left);
OGCGeometry rightGeometry = deserialize(right);
if (leftGeometry.isEmpty() || rightGeometry.isEmpty()) {
return null;
}
// TODO: support more SphericalGeography types.
validateSphericalType("ST_Distance", leftGeometry, EnumSet.of(POINT));
validateSphericalType("ST_Distance", rightGeometry, EnumSet.of(POINT));
Point leftPoint = (Point) leftGeometry.getEsriGeometry();
Point rightPoint = (Point) rightGeometry.getEsriGeometry();
// greatCircleDistance returns distance in KM.
return greatCircleDistance(leftPoint.getY(), leftPoint.getX(), rightPoint.getY(), rightPoint.getX()) * 1000;
}
use of io.prestosql.spi.function.SqlNullable in project hetu-core by openlookeng.
the class GeoFunctions method stSphericalArea.
@SqlNullable
@Description("Returns the area of a geometry on the Earth's surface using spherical model")
@ScalarFunction("ST_Area")
@SqlType(DOUBLE)
public static Double stSphericalArea(@SqlType(SPHERICAL_GEOGRAPHY_TYPE_NAME) Slice input) {
OGCGeometry geometry = deserialize(input);
if (geometry.isEmpty()) {
return null;
}
validateSphericalType("ST_Area", geometry, EnumSet.of(POLYGON, MULTI_POLYGON));
Polygon polygon = (Polygon) geometry.getEsriGeometry();
// See https://www.movable-type.co.uk/scripts/latlong.html
// and http://osgeo-org.1560.x6.nabble.com/Area-of-a-spherical-polygon-td3841625.html
// and https://www.element84.com/blog/determining-if-a-spherical-polygon-contains-a-pole
// for the underlying Maths
double sphericalExcess = 0.0;
int numPaths = polygon.getPathCount();
for (int i = 0; i < numPaths; i++) {
double sign = polygon.isExteriorRing(i) ? 1.0 : -1.0;
sphericalExcess += sign * Math.abs(computeSphericalExcess(polygon, polygon.getPathStart(i), polygon.getPathEnd(i)));
}
// isExteriorRing returns false for the exterior ring
return Math.abs(sphericalExcess * EARTH_RADIUS_M * EARTH_RADIUS_M);
}
use of io.prestosql.spi.function.SqlNullable in project hetu-core by openlookeng.
the class GeoFunctions method stStartPoint.
@SqlNullable
@Description("Returns the first point of a LINESTRING geometry as a Point")
@ScalarFunction("ST_StartPoint")
@SqlType(GEOMETRY_TYPE_NAME)
public static Slice stStartPoint(@SqlType(GEOMETRY_TYPE_NAME) Slice input) {
OGCGeometry geometry = deserialize(input);
validateType("ST_StartPoint", geometry, EnumSet.of(LINE_STRING));
if (geometry.isEmpty()) {
return null;
}
MultiPath lines = (MultiPath) geometry.getEsriGeometry();
SpatialReference reference = geometry.getEsriSpatialReference();
return serialize(createFromEsriGeometry(lines.getPoint(0), reference));
}
use of io.prestosql.spi.function.SqlNullable in project hetu-core by openlookeng.
the class Re2JRegexpReplaceLambdaFunction method regexpReplace.
@LiteralParameters("x")
@SqlType("varchar")
@SqlNullable
public Slice regexpReplace(@SqlType("varchar") Slice source, @SqlType(Re2JRegexpType.NAME) Re2JRegexp pattern, @SqlType("function(array(varchar), varchar(x))") UnaryFunctionInterface replaceFunction) {
// If there is no match we can simply return the original source without doing copy.
Matcher matcher = pattern.re2jPattern.matcher(source);
if (!matcher.find()) {
return source;
}
SliceOutput output = new DynamicSliceOutput(source.length());
// that will be passed to the lambda function.
if (pageBuilder.isFull()) {
pageBuilder.reset();
}
BlockBuilder blockBuilder = pageBuilder.getBlockBuilder(0);
int groupCount = matcher.groupCount();
int appendPosition = 0;
do {
int start = matcher.start();
int end = matcher.end();
// Append the un-matched part
if (appendPosition < start) {
output.writeBytes(source, appendPosition, start - appendPosition);
}
appendPosition = end;
// Append the capturing groups to the target block that will be passed to lambda
for (int i = 1; i <= groupCount; i++) {
Slice matchedGroupSlice = matcher.group(i);
if (matchedGroupSlice != null) {
VARCHAR.writeSlice(blockBuilder, matchedGroupSlice);
} else {
blockBuilder.appendNull();
}
}
pageBuilder.declarePositions(groupCount);
Block target = blockBuilder.getRegion(blockBuilder.getPositionCount() - groupCount, groupCount);
// Call the lambda function to replace the block, and append the result to output
Slice replaced = (Slice) replaceFunction.apply(target);
if (replaced == null) {
// replacing a substring with null (unknown) makes the entire string null
return null;
}
output.appendBytes(replaced);
} while (matcher.find());
// Append the rest of un-matched
output.writeBytes(source, appendPosition, source.length() - appendPosition);
return output.slice();
}
Aggregations