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.LineString;
import org.locationtech.jts.geom.MultiPoint; import org.locationtech.jts.geom.MultiPoint;
import org.locationtech.jts.geom.Point; 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.impl.PackedCoordinateSequence;
import org.locationtech.jts.geom.util.GeometryTransformer; import org.locationtech.jts.geom.util.GeometryTransformer;
import org.locationtech.jts.io.WKBReader; import org.locationtech.jts.io.WKBReader;
import org.locationtech.jts.precision.GeometryPrecisionReducer;
public class GeoUtils { public class GeoUtils {
@ -196,19 +197,24 @@ public class GeoUtils {
return JTS_FACTORY.createMultiLineString(lineStrings.toArray(EMPTY_LINE_STRING_ARRAY)); 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 { try {
int attempts; return GeometryPrecisionReducer.reduce(geom, tilePrecision);
for (attempts = 0; attempts < maxAttempts && !geom.isValid(); attempts++) { } 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); 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.PrecisionModel;
import org.locationtech.jts.geom.impl.PackedCoordinateSequence; import org.locationtech.jts.geom.impl.PackedCoordinateSequence;
import org.locationtech.jts.geom.util.AffineTransformation; import org.locationtech.jts.geom.util.AffineTransformation;
import org.locationtech.jts.precision.GeometryPrecisionReducer;
import org.locationtech.jts.simplify.DouglasPeuckerSimplifier; import org.locationtech.jts.simplify.DouglasPeuckerSimplifier;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -172,17 +171,11 @@ public class FeatureRenderer {
Geometry geom; Geometry geom;
if (feature.area()) { if (feature.area()) {
geom = CoordinateSequenceExtractor.reassemblePolygons(geoms); geom = CoordinateSequenceExtractor.reassemblePolygons(geoms);
geom = GeoUtils.fixPolygon(geom, 2); geom = GeoUtils.snapAndFixPolygon(geom, tilePrecision);
} else { } else {
geom = CoordinateSequenceExtractor.reassembleLineStrings(geoms); geom = CoordinateSequenceExtractor.reassembleLineStrings(geoms);
} }
try {
geom = GeometryPrecisionReducer.reduce(geom, tilePrecision);
} catch (IllegalArgumentException e) {
throw new GeometryException("Error reducing precision");
}
if (!geom.isEmpty()) { if (!geom.isEmpty()) {
// JTS utilities "fix" the geometry to be clockwise outer/CCW inner // JTS utilities "fix" the geometry to be clockwise outer/CCW inner
if (feature.area()) { if (feature.area()) {