Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@dbaston
Last active November 30, 2015 19:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dbaston/6b32fcb8c70d4d58775b to your computer and use it in GitHub Desktop.
Save dbaston/6b32fcb8c70d4d58775b to your computer and use it in GitHub Desktop.
ParallelCascadedPolygonUnion
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.util.GeometryCombiner;
import com.vividsolutions.jts.index.strtree.STRtree;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
public class ParallelCascadedPolygonUnion {
public static Geometry union(Collection<Geometry> geoms) {
// Construct an STRtree from the input geometries. If the number of geometries is
// small, we should probably skip this step or at least adjust the nodeCapacity.
int nodeCapacity = 16;
STRtree index = new STRtree(nodeCapacity);
geoms.forEach(g-> index.insert(g.getEnvelopeInternal(), g));
index.build();
// Pull out the internal representation of the tree (a list of lists)
// and perform the union operation.
return performUnion(index.itemsTree());
}
private static Geometry unionTwoGeometries(Geometry g1, Geometry g2) {
// This handles our base case when this function is used in a
// stream::reduce context.
if (g1 == null) {
return g2;
}
// Avoid doing the union if the geometries cannot intersect.
if (!g1.getEnvelopeInternal().intersects(g2.getEnvelopeInternal())) {
return GeometryCombiner.combine(g1, g2);
}
return g2.union(g1);
}
@SuppressWarnings("unchecked")
private static Geometry performUnion(List items) {
boolean isLeafNode = items.iterator().next() instanceof Geometry;
// If we're not on a leaf node, first perform the union operation in parallel on the child nodes. This will
// transform the current node into a leaf node of a shallower tree.
if (!isLeafNode)
items = ((List<List>) items).parallelStream().map(ParallelCascadedPolygonUnion::performUnion).collect(Collectors.toList());
// Now, union the geometry stored in the child nodes
return ((List<Geometry>) items).parallelStream().reduce(null, ParallelCascadedPolygonUnion::unionTwoGeometries);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment