locationtech/jts

VariableBuffer fails when vertex distance = 0

WindingWinter opened this issue · 3 comments

Does VariableBuffer support 0 buffer distance at one of the vertex? Here's what I found from NetTopologySuite library, and I suspect that the same issue is presented on the JTS library also.

The code is in NTS, but it's trivial to convert it to Java.

The code below is working fine, even though it has a 0 buffer distance

using NetTopologySuite.Geometries;
using NetTopologySuite.Operation.Buffer;

namespace tryNetTopo
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var polylineCoordinates = new Coordinate[]
              {
                    new Coordinate(2216883.9690149571, 5312555.8022460323),
                    new Coordinate(2216880.7776965303, 5312561.9943400519),
                    new Coordinate(2216874.5057125678, 5312574.1638290221),
                    new Coordinate(2216873.0320880935, 5312576.8179701111),
                    new Coordinate(2216872.0585015123, 5312578.3818236338),
                    new Coordinate(2216871.4142499096, 5312579.3486044565)
              };

            double[] arr = new double[polylineCoordinates.Length];
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = 1;
            }

            arr[3] = 0;

            var line = new LineString(polylineCoordinates);

            var result = VariableBuffer.Buffer(line, arr);
        }
    }
}

BUT, the following code doesn't work, even though it just contains an extra coordinate, which shouldn't matter?

using NetTopologySuite.Geometries;
using NetTopologySuite.Operation.Buffer;

namespace tryNetTopo
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var polylineCoordinates = new Coordinate[]
              {
                    new Coordinate(2216883.9690149571, 5312555.8022460323),
                    new Coordinate(2216880.7776965303, 5312561.9943400519),
                    new Coordinate(2216874.5057125678, 5312574.1638290221),
                    new Coordinate(2216873.0320880935, 5312576.8179701111),
                    new Coordinate(2216872.0585015123, 5312578.3818236338),
                    new Coordinate(2216871.4142499096, 5312579.3486044565),
                    new Coordinate(2216863.677298767 , 5312590.6634067535),         // adding this coordinate will cause the error
              };

            double[] arr = new double[polylineCoordinates.Length];
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = 1;
            }

            arr[3] = 0;

            var line = new LineString(polylineCoordinates);

            var result = VariableBuffer.Buffer(line, arr);
        }
    }
}
dr-jts commented

This is probably because the VariableBuffer code doesn't explicitly handle zero distances. It ends up creating invalid buffer lines at the point with zero distance.

This is probably an easy fix, to just check for a zero distance at a vertex and create a valid buffer around it.

(I'm actually not sure why the first case works at all - it should exhibit the same problem.)

I think it's better if JTS can just handle buffer distance=0. To me there is an easy way to do it.

Break the polyline internally at buffer distance =0, and subject the individual polyline to the existing algorithm, problem solved.