Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.geom.PrecisionModel;
import org.locationtech.jts.geom.util.GeometryFixer;
import org.locationtech.jts.geom.util.GeometryTransformer;

/**
Expand Down Expand Up @@ -183,11 +184,8 @@ protected Geometry transformMultiPolygon(MultiPolygon geom, Geometry parent) {

/**
* Creates a valid area geometry from one that possibly has bad topology
* (i.e. self-intersections). Since buffer can handle invalid topology, but
* always returns valid geometry, constructing a 0-width buffer "corrects"
* the topology. Note this only works for area geometries, since buffer
* always returns areas. This also may return empty geometries, if the input
* has no actual area.
* (i.e. self-intersections). GeometryFixer is used to correct the topology
* while preserving as much of the input geometry as possible.
*
* @param roughAreaGeom
* an area geometry possibly containing self-intersections
Expand All @@ -196,7 +194,7 @@ protected Geometry transformMultiPolygon(MultiPolygon geom, Geometry parent) {
private Geometry createValidArea(Geometry roughAreaGeom) {
// if valid no need to process to make valid
if (! isValidated || roughAreaGeom.isValid()) return roughAreaGeom;
return roughAreaGeom.buffer(0.0);
return GeometryFixer.fix(roughAreaGeom);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.locationtech.jts.geom.LinearRing;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.geom.util.GeometryFixer;
import org.locationtech.jts.geom.util.GeometryTransformer;

/**
Expand Down Expand Up @@ -190,14 +191,8 @@ protected Geometry transformMultiPolygon(MultiPolygon geom, Geometry parent) {
/**
* Creates a valid area geometry from one that possibly has
* bad topology (i.e. self-intersections).
* Since buffer can handle invalid topology, but always returns
* valid geometry, constructing a 0-width buffer "corrects" the
* topology.
* Note this only works for area geometries, since buffer always returns
* areas. This also may return empty geometries, if the input
* has no actual area.
* If the input is empty or is not polygonal,
* this ensures that POLYGON EMPTY is returned.
* GeometryFixer is used to correct the topology while preserving
* as much of the input geometry as possible.
*
* @param rawAreaGeom an area geometry possibly containing self-intersections
* @return a valid area geometry
Expand All @@ -207,7 +202,13 @@ private Geometry createValidArea(Geometry rawAreaGeom)
boolean isValidArea = rawAreaGeom.getDimension() == 2 && rawAreaGeom.isValid();
// if geometry is invalid then make it valid
if (isEnsureValidTopology && ! isValidArea)
return rawAreaGeom.buffer(0.0);
{
Geometry fixed = GeometryFixer.fix(rawAreaGeom);
// Preserve the historical result type for collapsed polygonal output.
if (fixed.isEmpty() && rawAreaGeom.getDimension() < 2)
return rawAreaGeom.getFactory().createPolygon();
return fixed;
}
return rawAreaGeom;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ public void testBoxNoValidate() {
10, "POLYGON ((10 10, 10 20, 10 30, 20 30, 30 30, 30 20, 30 10, 20 10, 10 10))");
}

public void testInvalidPolygonFixed() {
checkDensify(
"POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (20 20, 22 20, 22 22, 20 22, 20 20))",
100,
"MULTIPOLYGON (((0 0, 10 0, 10 10, 0 10, 0 0)), ((20 20, 22 20, 22 22, 20 22, 20 20)))");
}

public void testLineDensify3D() {
checkDensifyXYZ("POLYGON Z((10 30 10, 30 30 10, 30 10 15, 10 10 10, 10 30 20))",
10, "POLYGON Z((10 30 10, 20 30 10, 30 30 10, 30 20 12.5, 30 10 15, 20 10 12.5, 10 10 10, 10 20 15, 10 30 20))");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,14 @@ public void testGeometryCollection() {
/**
* Test that a polygon made invalid by simplification
* is fixed in a sensible way.
* Fixed by buffer(0) area-base orientation
* GeometryFixer preserves both lobes of the invalid ring.
* See https://github.com/locationtech/jts/issues/498
*/
public void testInvalidPolygonFixed() {
checkDP(
"POLYGON ((21.32686 47.78723, 21.32386 47.79023, 21.32186 47.80223, 21.31486 47.81023, 21.32786 47.81123, 21.33986 47.80223, 21.33886 47.81123, 21.32686 47.82023, 21.32586 47.82723, 21.32786 47.82323, 21.33886 47.82623, 21.34186 47.82123, 21.36386 47.82223, 21.40686 47.81723, 21.32686 47.78723))",
0.0036,
"POLYGON ((21.32686 47.78723, 21.31486 47.81023, 21.32786 47.81123, 21.33986 47.80223, 21.328068201892744 47.823286782334385, 21.33886 47.82623, 21.34186 47.82123, 21.40686 47.81723, 21.32686 47.78723))"
"MULTIPOLYGON (((21.31486 47.81023, 21.32786 47.81123, 21.33986 47.80223, 21.328068201892744 47.823286782334385, 21.33886 47.82623, 21.34186 47.82123, 21.40686 47.81723, 21.32686 47.78723, 21.31486 47.81023)), ((21.32586 47.82723, 21.328068201892744 47.823286782334385, 21.32786 47.82323, 21.32586 47.82723)))"
);
}

Expand Down
Loading