Search in sources :

Example 1 with CartesianPoint

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()));
}
Also used : OGCGeometry(com.esri.core.geometry.ogc.OGCGeometry) OGCPoint(com.esri.core.geometry.ogc.OGCPoint) OGCGeometryCollection(com.esri.core.geometry.ogc.OGCGeometryCollection) CartesianPoint(com.facebook.presto.geospatial.SphericalGeographyUtils.CartesianPoint) PrestoException(com.facebook.presto.spi.PrestoException) CartesianPoint(com.facebook.presto.geospatial.SphericalGeographyUtils.CartesianPoint) OGCPoint(com.esri.core.geometry.ogc.OGCPoint) Point(com.esri.core.geometry.Point) CartesianPoint(com.facebook.presto.geospatial.SphericalGeographyUtils.CartesianPoint) OGCPoint(com.esri.core.geometry.ogc.OGCPoint) Point(com.esri.core.geometry.Point) SqlNullable(com.facebook.presto.spi.function.SqlNullable) ScalarFunction(com.facebook.presto.spi.function.ScalarFunction) Description(com.facebook.presto.spi.function.Description) SqlType(com.facebook.presto.spi.function.SqlType)

Aggregations

Point (com.esri.core.geometry.Point)1 OGCGeometry (com.esri.core.geometry.ogc.OGCGeometry)1 OGCGeometryCollection (com.esri.core.geometry.ogc.OGCGeometryCollection)1 OGCPoint (com.esri.core.geometry.ogc.OGCPoint)1 CartesianPoint (com.facebook.presto.geospatial.SphericalGeographyUtils.CartesianPoint)1 PrestoException (com.facebook.presto.spi.PrestoException)1 Description (com.facebook.presto.spi.function.Description)1 ScalarFunction (com.facebook.presto.spi.function.ScalarFunction)1 SqlNullable (com.facebook.presto.spi.function.SqlNullable)1 SqlType (com.facebook.presto.spi.function.SqlType)1