in baremaps-core/src/main/java/org/apache/baremaps/database/algorithm/UnionStream.java [49:111]
public Stream<Geometry> union() {
// Use a bitmap to keep track of the geometries that have been visited
var visited = new Roaring64Bitmap();
// Create a spatial index of the geometries
HPRtree tree = new HPRtree();
for (int i = 0; i < list.size(); i++) {
tree.insert(list.get(i).getEnvelopeInternal(), i);
}
tree.build();
// Create a stream of geometry unions that are spatially connected
var stream = IntStream.range(0, list.size()).mapToObj(i -> {
// Skip the geometries that have already been visited
if (visited.contains(i)) {
return null;
}
visited.add(i);
// Initialize an accumulator and a stack to visit neighbors
var accumulator = new ArrayList<Geometry>();
var stack = new ArrayDeque<Geometry>();
// Add the current geometry to the accumulator and the stack
var g = list.get(i);
accumulator.add(g);
stack.push(g);
// Visit all neighbors that are spatially connected
while (!stack.isEmpty()) {
var g1 = stack.pop();
tree.query(g1.getEnvelopeInternal(), o -> {
var j = (int) o;
if (visited.contains(j)) {
return;
}
visited.add(j);
var g2 = list.get(j);
try {
// If the geometries are not spatially disjoint, add them to the accumulator and the
// stack,
// so that their neighbors can be visited
if (g1.intersects(g2)) {
accumulator.add(g2);
stack.push(g2);
}
} catch (TopologyException e) {
// This should occur only if the geometries are invalid,
// or in the case of a bug in JTS.
logger.warn("Failed to union geometries", e);
logger.warn("Geometry 1: {}", g1);
logger.warn("Geometry 2: {}", g2);
}
});
}
// Union the geometries in the accumulator
return new UnaryUnionOp(accumulator).union();
});
// Filter out the null values
return stream.filter(Objects::nonNull);
}