use of com.facebook.presto.geospatial.SphericalGeographyUtils.CartesianPoint in project presto by prestodb.
the class SphericalGeoFunctions method stSphericalCentroid.
@SqlNullable
@Description("Returns the Point value that is the mathematical centroid of a Spherical Geography")
@ScalarFunction("ST_Centroid")
@SqlType(SPHERICAL_GEOGRAPHY_TYPE_NAME)
public static Slice stSphericalCentroid(@SqlType(SPHERICAL_GEOGRAPHY_TYPE_NAME) Slice input) {
OGCGeometry geometry = EsriGeometrySerde.deserialize(input);
if (geometry.isEmpty()) {
return null;
}
// TODO: add support for other types e.g. POLYGON
validateSphericalType("ST_Centroid", geometry, EnumSet.of(POINT, MULTI_POINT));
if (geometry instanceof OGCPoint) {
return input;
}
OGCGeometryCollection geometryCollection = (OGCGeometryCollection) geometry;
for (int i = 0; i < geometryCollection.numGeometries(); i++) {
OGCGeometry g = geometryCollection.geometryN(i);
validateSphericalType("ST_Centroid", g, EnumSet.of(POINT));
Point p = (Point) g.getEsriGeometry();
checkLongitude(p.getX());
checkLatitude(p.getY());
}
Point centroid;
if (geometryCollection.numGeometries() == 1) {
centroid = (Point) geometryCollection.geometryN(0).getEsriGeometry();
} else {
double x3DTotal = 0;
double y3DTotal = 0;
double z3DTotal = 0;
for (int i = 0; i < geometryCollection.numGeometries(); i++) {
CartesianPoint cp = new CartesianPoint((Point) geometryCollection.geometryN(i).getEsriGeometry());
x3DTotal += cp.getX();
y3DTotal += cp.getY();
z3DTotal += cp.getZ();
}
double centroidVectorLength = Math.sqrt(x3DTotal * x3DTotal + y3DTotal * y3DTotal + z3DTotal * z3DTotal);
if (centroidVectorLength == 0.0) {
throw new PrestoException(INVALID_FUNCTION_ARGUMENT, format("Unexpected error. Average vector length adds to zero (%f, %f, %f)", x3DTotal, y3DTotal, z3DTotal));
}
centroid = new CartesianPoint(x3DTotal / centroidVectorLength, y3DTotal / centroidVectorLength, z3DTotal / centroidVectorLength).asSphericalPoint();
}
return EsriGeometrySerde.serialize(new OGCPoint(centroid, geometryCollection.getEsriSpatialReference()));
}
Aggregations