use of com.esri.core.geometry.ListeningGeometryCursor in project presto by prestodb.
the class GeoFunctions method stUnion.
private static Slice stUnion(Iterable<Slice> slices) {
// The current state of Esri/geometry-api-java does not allow support for multiple dimensions being
// fed to the union operator without dropping the lower dimensions:
// https://github.com/Esri/geometry-api-java/issues/199
// When operating over a collection of geometries, it is more efficient to reuse the same operator
// for the entire operation. Therefore, split the inputs and operators by dimension, and then union
// each dimension's result at the end.
ListeningGeometryCursor[] cursorsByDimension = new ListeningGeometryCursor[NUMBER_OF_DIMENSIONS];
GeometryCursor[] operatorsByDimension = new GeometryCursor[NUMBER_OF_DIMENSIONS];
setAll(cursorsByDimension, i -> new ListeningGeometryCursor());
setAll(operatorsByDimension, i -> OperatorUnion.local().execute(cursorsByDimension[i], null, null));
Iterator<Slice> slicesIterator = slices.iterator();
if (!slicesIterator.hasNext()) {
return null;
}
while (slicesIterator.hasNext()) {
Slice slice = slicesIterator.next();
// Ignore null inputs
if (slice.getInput().available() == 0) {
continue;
}
for (OGCGeometry geometry : flattenCollection(EsriGeometrySerde.deserialize(slice))) {
int dimension = geometry.dimension();
cursorsByDimension[dimension].tick(geometry.getEsriGeometry());
operatorsByDimension[dimension].tock();
}
}
List<OGCGeometry> outputs = new ArrayList<>();
for (GeometryCursor operator : operatorsByDimension) {
OGCGeometry unionedGeometry = createFromEsriGeometry(operator.next(), null);
if (unionedGeometry != null) {
outputs.add(unionedGeometry);
}
}
if (outputs.size() == 1) {
return EsriGeometrySerde.serialize(outputs.get(0));
}
return EsriGeometrySerde.serialize(new OGCConcreteGeometryCollection(outputs, null).flattenAndRemoveOverlaps().reduceFromMulti());
}
Aggregations