use of com.facebook.presto.geospatial.Rectangle in project presto by prestodb.
the class TestSpatialPartitioningInternalAggregation method getSpatialPartitioning.
private String getSpatialPartitioning(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), rectangles.build()));
}
use of com.facebook.presto.geospatial.Rectangle in project presto by prestodb.
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(int)")
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.isEmpty()) {
return null;
}
Rectangle expandedEnvelope2D = new Rectangle(envelope.getXMin() - distance, envelope.getYMin() - distance, envelope.getXMax() + distance, envelope.getYMax() + distance);
return spatialPartitions((KdbTree) kdbTree, expandedEnvelope2D);
}
use of com.facebook.presto.geospatial.Rectangle in project presto by prestodb.
the class PagesRTreeIndex method testReferencePoint.
private boolean testReferencePoint(Rectangle probeEnvelope, Rectangle buildEnvelope, int partition) {
Rectangle intersection = buildEnvelope.intersection(probeEnvelope);
if (intersection == null) {
return false;
}
Rectangle extent = partitions.get(partition);
double x = intersection.getXMin();
double y = intersection.getYMin();
return x >= extent.getXMin() && x < extent.getXMax() && y >= extent.getYMin() && y < extent.getYMax();
}
use of com.facebook.presto.geospatial.Rectangle in project presto by prestodb.
the class PagesRTreeIndex method findJoinPositions.
/**
* Returns an array of addresses from {@link PagesIndex#getValueAddresses()} corresponding
* to rows with matching geometries.
* <p>
* The caller is responsible for calling {@link #isJoinPositionEligible(int, int, Page)}
* for each of these addresses to apply additional join filters.
*/
@Override
public int[] findJoinPositions(int probePosition, Page probe, int probeGeometryChannel, Optional<Integer> probePartitionChannel) {
Block probeGeometryBlock = probe.getBlock(probeGeometryChannel);
if (probeGeometryBlock.isNull(probePosition)) {
return EMPTY_ADDRESSES;
}
int probePartition = probePartitionChannel.map(channel -> toIntExact(INTEGER.getLong(probe.getBlock(channel), probePosition))).orElse(-1);
Slice slice = probeGeometryBlock.getSlice(probePosition, 0, probeGeometryBlock.getSliceLength(probePosition));
OGCGeometry probeGeometry = deserialize(slice);
verify(probeGeometry != null);
if (probeGeometry.isEmpty()) {
return EMPTY_ADDRESSES;
}
IntArrayList matchingPositions = new IntArrayList();
Rectangle queryRectangle = getExtent(probeGeometry);
boolean probeIsPoint = queryRectangle.isPointlike();
rtree.findIntersections(queryRectangle, geometryWithPosition -> {
OGCGeometry buildGeometry = geometryWithPosition.getGeometry();
Rectangle buildEnvelope = geometryWithPosition.getExtent();
if (partitions.isEmpty() || (probePartition == geometryWithPosition.getPartition() && (probeIsPoint || buildEnvelope.isPointlike() || testReferencePoint(queryRectangle, buildEnvelope, probePartition)))) {
OptionalDouble radius = radiusChannel == -1 ? OptionalDouble.empty() : OptionalDouble.of(getRadius(geometryWithPosition.getPosition()));
if (spatialRelationshipTest.apply(buildGeometry, probeGeometry, radius)) {
matchingPositions.add(geometryWithPosition.getPosition());
}
}
});
return matchingPositions.toIntArray();
}
Aggregations