in baremaps-dem/src/main/java/org/apache/baremaps/dem/ContourTracer.java [110:171]
private List<Geometry> polygonize(List<Geometry> geometries) {
var polygons = new ArrayList<>(geometries.stream()
.map(Geometry::getCoordinates)
.map(GEOMETRY_FACTORY::createPolygon)
.map(polygon -> new GeometryFixer(polygon).getResult())
.map(Polygon.class::cast)
.sorted((a, b) -> Double.compare(b.getArea(), a.getArea()))
.toList());
List<Geometry> polygonized = new ArrayList<>();
for (int i = 0; i < polygons.size(); i++) {
// Skip null polygons
if (polygons.get(i) == null) {
continue;
}
// Extract the shell and holes
Polygon shell = polygons.get(i);
List<Polygon> holes = new ArrayList<>();
for (int j = i + 1; j < polygons.size(); j++) {
// Skip null polygons
if (polygons.get(j) == null) {
continue;
}
Polygon polygon = polygons.get(j);
if (shell.contains(polygon)) {
// Check if the hole is within a previously found hole
boolean within = false;
for (Polygon hole : holes) {
if (hole.contains(polygon)) {
within = true;
break;
}
}
if (within) {
continue;
}
// Add the hole to the list
holes.add(polygon);
// Set the used polygon to null
polygons.set(j, null);
}
}
// Combine the shell and holes
Polygon combinedPolygon = GEOMETRY_FACTORY.createPolygon(
shell.getExteriorRing(),
holes.stream()
.map(Polygon::getExteriorRing)
.toArray(LinearRing[]::new));
polygonized.add(combinedPolygon);
// Set the used polygon to null
polygons.set(i, null);
}
return polygonized;
}