Unexpected output from OffsetCurve.getCurve() since jts-version 1.20.0
Hi! I recently updated my jts-version from 1.19.0 to 1.20.0 and stumbled across some unexpected output from the OffsetCurve.getCurve() method. I use this method to create lines with a constant distance, but after updating to 1.20.0, the output changed. This code was used to create the images below:
GeometryFactory geometryFactory1 = new GeometryFactory();
LineString testLineString = geometryFactory1.createLineString(new Coordinate[]{
new Coordinate(-477.9727884893793, 726.8346522633758),
new Coordinate(-278.5761790410716, 469.3177193695431),
new Coordinate(-79.17956959276393, 211.80078647571045),
new Coordinate(-74.10825983114643, 205.2512862651522),
new Coordinate(-61.59032155710979, 183.66416102497575),
new Coordinate(-56.17516937041343, 177.39645645603244),
new Coordinate(-45.87664216572637, 163.28009296700202),
new Coordinate(-32.80606824944878, 140.06145723770865),
new Coordinate(-26.625732783814613, 132.27313760006422),
new Coordinate(-20.81619693653508, 123.16499838643774),
new Coordinate(-15.495636510039938, 116.78652899133516),
new Coordinate(-9.117773193378609, 108.03384392886659),
new Coordinate(9.065051143785869, 79.15745454413279),
new Coordinate(25.818482523651234, 55.05549100891343),
new Coordinate(211.71012482617877, -212.37351996146882),
new Coordinate(397.60176712870623, -479.8025309318511)});
for (int i = 1; i < 100; i++) {
LineString offsetCurve = (LineString) (OffsetCurve.getCurve(testLineString,
-i * 0.775).getGeometryN(0));
}
Using this code with jts-version 1.19.0, I got this image (zoomed in into the "interesting" part):
With 1.20.0, I got this:
Zoomed in:
I hope, you can see the gaps between some of the offset curves. Since I need the output of version 1.19.0, I wanted to ask if this is some kind of bug or if the behaviour of getCurve() changed. Is there a way to get the output of 1.19.0 by calling the method with different parameters?
(Additional note: I checked the output of the code above for older versions and the behaviour changed with the commit "Improve Buffer ring simplfication" (22.11.2023).)
Thanks in advance!
As you suggest, this is a behaviour change between 1.19 and 1.20, due to the code change in #1022. Input line simplification was introduced to improve performance and robustness. For many use cases the slight decrease in accuracy is worth the tradeoff.
The good news is that OffsetCurve can be called with a BufferParameters object, and that exposes the setSimplifyFactor method to specify the simplification factor used. Using a smaller factor will cause less simplification, and increase the accuracy of the result. For this case using a factor of 0.001 works well (the default is 0.01).
Here's how to use the parameter:
BufferParameters params = new BufferParameters();
params.setSimplifyFactor(simplifyFactor);
OffsetCurve oc = new OffsetCurve(geom, distance, params);
Geometry result = oc.getCurve();
SimplifyFactor = 0.01
SimplifyFactor = 0.001
Some bad news is that there is a bug in 1.20 which means OffsetCurve doesn't respect the simplifyFactor parameter.
More good news is that this is fixed by #1151.
Thank you very much for the explanation and the quick fix! That was very helpful!