cheaper snap and fix

pull/1/head
Mike Barry 2021-05-23 14:36:02 -04:00
rodzic 4e126fd1d6
commit d990784606
2 zmienionych plików z 18 dodań i 19 usunięć

Wyświetl plik

@ -11,10 +11,11 @@ import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.MultiPoint;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.TopologyException;
import org.locationtech.jts.geom.PrecisionModel;
import org.locationtech.jts.geom.impl.PackedCoordinateSequence;
import org.locationtech.jts.geom.util.GeometryTransformer;
import org.locationtech.jts.io.WKBReader;
import org.locationtech.jts.precision.GeometryPrecisionReducer;
public class GeoUtils {
@ -196,19 +197,24 @@ public class GeoUtils {
return JTS_FACTORY.createMultiLineString(lineStrings.toArray(EMPTY_LINE_STRING_ARRAY));
}
public static Geometry fixPolygon(Geometry geom, int maxAttempts) throws GeometryException {
public static Geometry snapAndFixPolygon(Geometry geom, PrecisionModel tilePrecision) throws GeometryException {
try {
int attempts;
for (attempts = 0; attempts < maxAttempts && !geom.isValid(); attempts++) {
return GeometryPrecisionReducer.reduce(geom, tilePrecision);
} catch (IllegalArgumentException e) {
// precision reduction fails if geometry is invalid, so attempt
// to fix it then try again
geom = geom.buffer(0);
try {
return GeometryPrecisionReducer.reduce(geom, tilePrecision);
} catch (IllegalArgumentException e2) {
// give it one last try, just in case
geom = geom.buffer(0);
try {
return GeometryPrecisionReducer.reduce(geom, tilePrecision);
} catch (IllegalArgumentException e3) {
throw new GeometryException("Error reducing precision");
}
}
if (attempts == maxAttempts) {
throw new GeometryException("Geometry still invalid after 2 buffers");
}
return geom;
} catch (TopologyException e) {
throw new GeometryException("Unable to fix polygon: " + e);
}
}

Wyświetl plik

@ -26,7 +26,6 @@ import org.locationtech.jts.geom.Polygonal;
import org.locationtech.jts.geom.PrecisionModel;
import org.locationtech.jts.geom.impl.PackedCoordinateSequence;
import org.locationtech.jts.geom.util.AffineTransformation;
import org.locationtech.jts.precision.GeometryPrecisionReducer;
import org.locationtech.jts.simplify.DouglasPeuckerSimplifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -172,17 +171,11 @@ public class FeatureRenderer {
Geometry geom;
if (feature.area()) {
geom = CoordinateSequenceExtractor.reassemblePolygons(geoms);
geom = GeoUtils.fixPolygon(geom, 2);
geom = GeoUtils.snapAndFixPolygon(geom, tilePrecision);
} else {
geom = CoordinateSequenceExtractor.reassembleLineStrings(geoms);
}
try {
geom = GeometryPrecisionReducer.reduce(geom, tilePrecision);
} catch (IllegalArgumentException e) {
throw new GeometryException("Error reducing precision");
}
if (!geom.isEmpty()) {
// JTS utilities "fix" the geometry to be clockwise outer/CCW inner
if (feature.area()) {