Search in sources :

Example 1 with Rectangle

use of io.prestosql.geospatial.Rectangle in project hetu-core by openlookeng.

the class TestSpatialPartitioningInternalAggregation method getSpatialPartitioning.

private String getSpatialPartitioning(Rectangle extent, List<OGCGeometry> geometries, int partitionCount) {
    ImmutableList.Builder<Rectangle> rectangles = ImmutableList.builder();
    for (OGCGeometry geometry : geometries) {
        Envelope envelope = new Envelope();
        geometry.getEsriGeometry().queryEnvelope(envelope);
        rectangles.add(new Rectangle(envelope.getXMin(), envelope.getYMin(), envelope.getXMax(), envelope.getYMax()));
    }
    return KdbTreeUtils.toJson(buildKdbTree(roundToInt(geometries.size() * 1.0 / partitionCount, CEILING), extent, rectangles.build()));
}
Also used : OGCGeometry(com.esri.core.geometry.ogc.OGCGeometry) ImmutableList(com.google.common.collect.ImmutableList) Rectangle(io.prestosql.geospatial.Rectangle) Envelope(com.esri.core.geometry.Envelope)

Example 2 with Rectangle

use of io.prestosql.geospatial.Rectangle in project hetu-core by openlookeng.

the class GeoFunctions method spatialPartitions.

private static Block spatialPartitions(KdbTree kdbTree, Rectangle envelope) {
    Map<Integer, Rectangle> partitions = kdbTree.findIntersectingLeaves(envelope);
    if (partitions.isEmpty()) {
        return EMPTY_ARRAY_OF_INTS;
    }
    // For input rectangles that represent a single point, return at most one partition
    // by excluding right and upper sides of partition rectangles. The logic that builds
    // KDB tree needs to make sure to add some padding to the right and upper sides of the
    // overall extent of the tree to avoid missing right-most and top-most points.
    boolean point = (envelope.getWidth() == 0 && envelope.getHeight() == 0);
    if (point) {
        for (Map.Entry<Integer, Rectangle> partition : partitions.entrySet()) {
            if (envelope.getXMin() < partition.getValue().getXMax() && envelope.getYMin() < partition.getValue().getYMax()) {
                BlockBuilder blockBuilder = IntegerType.INTEGER.createFixedSizeBlockBuilder(1);
                blockBuilder.writeInt(partition.getKey());
                return blockBuilder.build();
            }
        }
        throw new VerifyException(format("Cannot find half-open partition extent for a point: (%s, %s)", envelope.getXMin(), envelope.getYMin()));
    }
    BlockBuilder blockBuilder = IntegerType.INTEGER.createFixedSizeBlockBuilder(partitions.size());
    for (int id : partitions.keySet()) {
        blockBuilder.writeInt(id);
    }
    return blockBuilder.build();
}
Also used : VerifyException(com.google.common.base.VerifyException) Rectangle(io.prestosql.geospatial.Rectangle) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) MultiPoint(com.esri.core.geometry.MultiPoint) Point(com.esri.core.geometry.Point) OGCPoint(com.esri.core.geometry.ogc.OGCPoint) BlockBuilder(io.prestosql.spi.block.BlockBuilder)

Example 3 with Rectangle

use of io.prestosql.geospatial.Rectangle in project hetu-core by openlookeng.

the class GeoFunctions method spatialPartitions.

@ScalarFunction
@SqlNullable
@Description("Returns an array of spatial partition IDs for a geometry representing a set of points within specified distance from the input geometry")
@SqlType("array(integer)")
public static Block spatialPartitions(@SqlType(KdbTreeType.NAME) Object kdbTree, @SqlType(GEOMETRY_TYPE_NAME) Slice geometry, @SqlType(DOUBLE) double distance) {
    if (isNaN(distance)) {
        throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "distance is NaN");
    }
    if (isInfinite(distance)) {
        throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "distance is infinite");
    }
    if (distance < 0) {
        throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "distance is negative");
    }
    Envelope envelope = deserializeEnvelope(geometry);
    if (envelope == null) {
        return null;
    }
    Rectangle expandedEnvelope2D = new Rectangle(envelope.getXMin() - distance, envelope.getYMin() - distance, envelope.getXMax() + distance, envelope.getYMax() + distance);
    return spatialPartitions((KdbTree) kdbTree, expandedEnvelope2D);
}
Also used : Rectangle(io.prestosql.geospatial.Rectangle) PrestoException(io.prestosql.spi.PrestoException) GeometrySerde.deserializeEnvelope(io.prestosql.geospatial.serde.GeometrySerde.deserializeEnvelope) Envelope(com.esri.core.geometry.Envelope) SqlNullable(io.prestosql.spi.function.SqlNullable) ScalarFunction(io.prestosql.spi.function.ScalarFunction) Description(io.prestosql.spi.function.Description) SqlType(io.prestosql.spi.function.SqlType)

Example 4 with Rectangle

use of io.prestosql.geospatial.Rectangle in project hetu-core by openlookeng.

the class TestSpatialPartitioningInternalAggregation method test.

@Test(dataProvider = "partitionCount")
public void test(int partitionCount) {
    InternalAggregationFunction function = getFunction();
    List<OGCGeometry> geometries = makeGeometries();
    Block geometryBlock = makeGeometryBlock(geometries);
    Block partitionCountBlock = BlockAssertions.createRLEBlock(partitionCount, geometries.size());
    Rectangle expectedExtent = new Rectangle(-10, -10, Math.nextUp(10.0), Math.nextUp(10.0));
    String expectedValue = getSpatialPartitioning(expectedExtent, geometries, partitionCount);
    AccumulatorFactory accumulatorFactory = function.bind(Ints.asList(0, 1, 2), Optional.empty());
    Page page = new Page(geometryBlock, partitionCountBlock);
    Accumulator accumulator = accumulatorFactory.createAccumulator();
    accumulator.addInput(page);
    String aggregation = (String) BlockAssertions.getOnlyValue(accumulator.getFinalType(), getFinalBlock(accumulator));
    assertEquals(aggregation, expectedValue);
    GroupedAccumulator groupedAggregation = accumulatorFactory.createGroupedAccumulator();
    groupedAggregation.addInput(createGroupByIdBlock(0, page.getPositionCount()), page);
    String groupValue = (String) getGroupValue(groupedAggregation, 0);
    assertEquals(groupValue, expectedValue);
}
Also used : OGCGeometry(com.esri.core.geometry.ogc.OGCGeometry) Accumulator(io.prestosql.operator.aggregation.Accumulator) GroupedAccumulator(io.prestosql.operator.aggregation.GroupedAccumulator) AccumulatorFactory(io.prestosql.operator.aggregation.AccumulatorFactory) Rectangle(io.prestosql.geospatial.Rectangle) AggregationTestUtils.getFinalBlock(io.prestosql.operator.aggregation.AggregationTestUtils.getFinalBlock) Block(io.prestosql.spi.block.Block) AggregationTestUtils.createGroupByIdBlock(io.prestosql.operator.aggregation.AggregationTestUtils.createGroupByIdBlock) Page(io.prestosql.spi.Page) InternalAggregationFunction(io.prestosql.operator.aggregation.InternalAggregationFunction) GroupedAccumulator(io.prestosql.operator.aggregation.GroupedAccumulator) Test(org.testng.annotations.Test)

Example 5 with Rectangle

use of io.prestosql.geospatial.Rectangle in project hetu-core by openlookeng.

the class SpatialPartitioningInternalAggregateFunction method output.

@OutputFunction(StandardTypes.VARCHAR)
public static void output(SpatialPartitioningState state, BlockBuilder out) {
    if (state.getCount() == 0) {
        out.appendNull();
        return;
    }
    List<Rectangle> samples = state.getSamples();
    int partitionCount = state.getPartitionCount();
    int maxItemsPerNode = (samples.size() + partitionCount - 1) / partitionCount;
    Rectangle envelope = state.getExtent();
    // Add a small buffer on the right and upper sides
    Rectangle paddedExtent = new Rectangle(envelope.getXMin(), envelope.getYMin(), Math.nextUp(envelope.getXMax()), Math.nextUp(envelope.getYMax()));
    VARCHAR.writeString(out, KdbTreeUtils.toJson(buildKdbTree(maxItemsPerNode, paddedExtent, samples)));
}
Also used : Rectangle(io.prestosql.geospatial.Rectangle) OutputFunction(io.prestosql.spi.function.OutputFunction)

Aggregations

Rectangle (io.prestosql.geospatial.Rectangle)7 Envelope (com.esri.core.geometry.Envelope)3 OGCGeometry (com.esri.core.geometry.ogc.OGCGeometry)2 GeometrySerde.deserializeEnvelope (io.prestosql.geospatial.serde.GeometrySerde.deserializeEnvelope)2 MultiPoint (com.esri.core.geometry.MultiPoint)1 Point (com.esri.core.geometry.Point)1 OGCPoint (com.esri.core.geometry.ogc.OGCPoint)1 VerifyException (com.google.common.base.VerifyException)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 Accumulator (io.prestosql.operator.aggregation.Accumulator)1 AccumulatorFactory (io.prestosql.operator.aggregation.AccumulatorFactory)1 AggregationTestUtils.createGroupByIdBlock (io.prestosql.operator.aggregation.AggregationTestUtils.createGroupByIdBlock)1 AggregationTestUtils.getFinalBlock (io.prestosql.operator.aggregation.AggregationTestUtils.getFinalBlock)1 GroupedAccumulator (io.prestosql.operator.aggregation.GroupedAccumulator)1 InternalAggregationFunction (io.prestosql.operator.aggregation.InternalAggregationFunction)1 Page (io.prestosql.spi.Page)1 PrestoException (io.prestosql.spi.PrestoException)1 Block (io.prestosql.spi.block.Block)1 BlockBuilder (io.prestosql.spi.block.BlockBuilder)1