kopia lustrzana https://github.com/onthegomap/planetiler
Fix buffer union unbuffer exceptions (#713)
rodzic
65935461e3
commit
517851435d
|
@ -29,6 +29,7 @@ import org.locationtech.jts.geom.LinearRing;
|
|||
import org.locationtech.jts.geom.Polygon;
|
||||
import org.locationtech.jts.geom.Polygonal;
|
||||
import org.locationtech.jts.geom.TopologyException;
|
||||
import org.locationtech.jts.geom.util.GeometryFixer;
|
||||
import org.locationtech.jts.index.strtree.STRtree;
|
||||
import org.locationtech.jts.operation.buffer.BufferOp;
|
||||
import org.locationtech.jts.operation.buffer.BufferParameters;
|
||||
|
@ -323,7 +324,7 @@ public class FeatureMerge {
|
|||
// spinning for a very long time on very dense tiles.
|
||||
// TODO use some heuristic to choose bufferUnbuffer vs. bufferUnionUnbuffer based on the number small
|
||||
// polygons in the group?
|
||||
merged = bufferUnionUnbuffer(buffer, polygonGroup);
|
||||
merged = bufferUnionUnbuffer(buffer, polygonGroup, stats);
|
||||
} else {
|
||||
merged = buffer(buffer, GeoUtils.createGeometryCollection(polygonGroup));
|
||||
}
|
||||
|
@ -411,7 +412,7 @@ public class FeatureMerge {
|
|||
* Merges nearby polygons by expanding each individual polygon by {@code buffer}, unioning them, and contracting the
|
||||
* result.
|
||||
*/
|
||||
private static Geometry bufferUnionUnbuffer(double buffer, List<Geometry> polygonGroup) throws GeometryException {
|
||||
static Geometry bufferUnionUnbuffer(double buffer, List<Geometry> polygonGroup, Stats stats) {
|
||||
/*
|
||||
* A simpler alternative that might initially appear faster would be:
|
||||
*
|
||||
|
@ -433,10 +434,11 @@ public class FeatureMerge {
|
|||
try {
|
||||
merged = union(merged);
|
||||
} catch (TopologyException e) {
|
||||
throw new GeometryException("buffer_union_failure", "Error unioning buffered polygons", e)
|
||||
.addGeometryDetails("original", GeoUtils.createGeometryCollection(polygonGroup))
|
||||
.addDetails(() -> "buffer: " + buffer)
|
||||
.addGeometryDetails("buffered", GeoUtils.createGeometryCollection(buffered));
|
||||
// buffer result is sometimes invalid, which makes union throw so fix
|
||||
// it and try again (see #700)
|
||||
stats.dataError("buffer_union_unbuffer_union_failed");
|
||||
merged = GeometryFixer.fix(merged);
|
||||
merged = union(merged);
|
||||
}
|
||||
merged = unbuffer(buffer, merged);
|
||||
return merged;
|
||||
|
|
|
@ -10,7 +10,9 @@ import com.onthegomap.planetiler.collection.Hppc;
|
|||
import com.onthegomap.planetiler.geo.GeometryException;
|
||||
import com.onthegomap.planetiler.geo.GeometryType;
|
||||
import com.onthegomap.planetiler.mbtiles.Mbtiles;
|
||||
import com.onthegomap.planetiler.stats.Stats;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -20,11 +22,14 @@ import java.util.function.UnaryOperator;
|
|||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import org.locationtech.jts.geom.GeometryCollection;
|
||||
import org.locationtech.jts.geom.LineString;
|
||||
import org.locationtech.jts.geom.Point;
|
||||
import org.locationtech.jts.geom.Polygon;
|
||||
import org.locationtech.jts.io.ParseException;
|
||||
import org.locationtech.jts.io.WKBReader;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -853,4 +858,27 @@ class FeatureMergeTest {
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"/issue_700/exception_1.wkb",
|
||||
"/issue_700/exception_2.wkb",
|
||||
"/issue_700/exception_3.wkb",
|
||||
"/issue_700/exception_4.wkb",
|
||||
"/issue_700/exception_5.wkb",
|
||||
"/issue_700/exception_6.wkb",
|
||||
"/issue_700/exception_7.wkb",
|
||||
"/issue_700/exception_8.wkb",
|
||||
"/issue_700/exception_9.wkb",
|
||||
})
|
||||
void testIssue700BufferUnionUnbufferFailure(String path) throws IOException, ParseException {
|
||||
try (var is = getClass().getResource(path).openStream()) {
|
||||
GeometryCollection collection = (GeometryCollection) new WKBReader().read(is.readAllBytes());
|
||||
List<Geometry> geometries = new ArrayList<>();
|
||||
for (int i = 0; i < collection.getNumGeometries(); i++) {
|
||||
geometries.add(collection.getGeometryN(i));
|
||||
}
|
||||
FeatureMerge.bufferUnionUnbuffer(0.5, geometries, Stats.inMemory());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
Ładowanie…
Reference in New Issue