locationtech / jts

The JTS Topology Suite is a Java library for creating and manipulating vector geometry.
Other
1.94k stars 442 forks source link

VariableBuffer fails when vertex distance = 0 #995

Closed WindingWinter closed 1 year ago

WindingWinter commented 1 year ago

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 1 year ago

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.)

WindingWinter commented 1 year ago

But let's say that the correct buffer distance is indeed 0 for that particular segment of line?

On Wed, Aug 9, 2023 at 12:57 PM Martin Davis @.***> wrote:

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.)

— Reply to this email directly, view it on GitHub https://github.com/locationtech/jts/issues/995#issuecomment-1670655548, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADENIZS4S453MHAFAWZWDULXUMKC5ANCNFSM6AAAAAA3HYLL5Y . You are receiving this because you authored the thread.Message ID: @.***>

WindingWinter commented 1 year ago

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.