Opened 9 years ago

Closed 6 years ago

Last modified 13 months ago

#712 closed defect (fixed)

Single-sided buffer gives unexpected result

Reported by: pmeems Owned by: geos-devel@…
Priority: major Milestone: 3.6.3
Component: Default Version: 3.4.2
Severity: Unassigned Keywords:
Cc: jrkleemann


I have this linestring: LINESTRING(6.59607872405104612 53.00390260763848715, 6.5970405434596513 53.00362892273712845, 6.59798287063396227 53.00336078433459619, 6.59864650169724065 53.00303357725661613, 6.59938686388177764 53.00283982209050748, 6.60119220843164101 53.00211012469529948, 6.60112679624460608 53.00208460961093948, 6.60026057476097616 53.00174672587350244, 6.58878962886061181 52.99727229739764311)

I create a single-sided buffer of -9E-10 (-70m) with flat endcaps and round joinstyle. This should create a polygon left of the line. But it creates a buffer as in the attached image. You can see that in the right corner the polygon is also at the right of the line. This happens only at sharp corners.

I've mentioned this on the mailing list already. I tried searching for an existing ticket but couldn't find it. I don't know if this is also a problem with JTS, probably it is.

Attachments (3)

single-sided-buffer.png (39.3 KB ) - added by pmeems 9 years ago.
Screenshot of the result of single-sided buffer.
712.PNG (16.7 KB ) - added by jrkleemann 7 years ago.
712_2.PNG (14.7 KB ) - added by jrkleemann 7 years ago.

Download all attachments as: .zip

Change History (12)

by pmeems, 9 years ago

Attachment: single-sided-buffer.png added

Screenshot of the result of single-sided buffer.

comment:1 by strk, 8 years ago


Ticket retargeted after milestone deleted

comment:2 by strk, 7 years ago


Ticket retargeted after milestone closed

comment:3 by strk, 7 years ago


Ticket retargeted after milestone closed

comment:4 by jrkleemann, 7 years ago

Cc: jrkleemann added
Priority: minormajor

I have the same problem right now. I have analysed the GEOS code a bit and here is my conclusion so far: These "wings" seem to be the intended behaviour. This happens, when the input linestring has an inside turn with too short segments (relative to the angle of the turn). More specifically this happens, when the offset segments (the original segment offseted by distance) don't intersect.

The wings are created by inserting the start-/endpoints of the offset segments into the offset curve. I will attach an image showing the internal curve (blue) used for building the polygon. The arrow show the direction of the curve. Red is the resulting Polygon.

I tried tuning the GEOS code, so instead of the closing segments (wings) the intersection points of the offset segments and the original segmets are inserted (green circles in the image). This leaves us with the internal curve (blue) in the second image. In (my) theory this should remove the wings and leave us with the correct polygon. Instead this results in an util::TopologyException in void DirectedEdgeStar::computeDepths(DirectedEdge *de). The method is called from the class BufferSubgraph;

I have not looked into the BufferSubgraph class so far. Maybe there is a way to workaround the crash.

I'll upgrade the ticket to major priority. Maybe someone with a deeper knowledge of the algorithm can look into this.

by jrkleemann, 7 years ago

Attachment: 712.PNG added

by jrkleemann, 7 years ago

Attachment: 712_2.PNG added

comment:5 by mdavis, 7 years ago

Pretty likely that JTS gives the same result.

There's a lot of heuristics in the buffer code, intended to give stable and correct results for all of the various ways in which it can be parameterized (but with priority given to the primary use case of round buffers). It might be possible to improve the heuristics to get better results in this situation, but it will require either extensive testing to ensure no regression in all other buffer situations, or a different code path provided for just Single-Sided Buffer.

comment:6 by jrkleemann, 7 years ago

JTS has pretty much the same code, so it should provide the same result.

comment:7 by robe, 6 years ago

Resolution: wontfix
Status: newclosed

comment:9 by Sandro Santilli <strk@…>, 13 months ago

Resolution: wontfixfixed

In 091f6d9/git:

Only keep biggest polygon from single-sided buffer

Closes GH-665
Closes #810
Closes #712

Includes unit test

Note: See TracTickets for help on using tickets.