-
Notifications
You must be signed in to change notification settings - Fork 372
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SingleSided buffer shows artifacts #665
Comments
Please check out the OffsetCurve functionality in the current main, the SingleSidedBuffer is deprecated and will disappear at some point in the future. |
For the record: deprecation of SingleSidedBuffer happened in 2011: d48b19a |
As the deprecating commit was mine, and it mentioned "use OffsetCurve instead", I guess the idea was to be able to re-implement SingleSided buffer in terms of OffsetCurve, so that part would still be good to do in GEOS itself, re-implementing SingleSidedBuffer that way, or the deprecation message would be false advertising. I'm re-opeining this ticket to give that re-implementation a try. |
This is a picture of how OffsetCurve (in green) compares with SingleSidedBuffer (in pink) for a distance of 21 on the original input (arrowed line): In this case connecting the endpoints of offset curve to the endpoints of the input line would give what we're after, but I'm afraid an offset curve is not always a single line then the input line is complex, so the goal of a "single sided buffer" is probably still one that would be good to aim at with a specific API. |
It looks like the BufferBuilder::bufferLineSingleSided contained an heuristic code that would fix this case, namely it would drop from the edge list those edges that would not intersect with the edges of a full buffer, effectively removing those forming the artifacts. The current code is NOT using that method, which first appeared in GEOS, but is instead using code being a port of code subsequently added in JTS. |
I've just realized that the deprecated GEOSSingleSidedBuffer C-API function never returned an area, but was really just always returning effectively an offset curve, which explains the deprecation hint (and the confusion). What is referred to by "Single-Sided buffer" was never implemented natively in GEOS. |
Includes unit test Fixes libgeosGH-665
Includes unit test Fixes libgeosGH-665
Includes unit test Fixes libgeosGH-665
Port of the heuristic in BufferBuilder::bufferSingleSidedBuffer was ported to the current code with #891 -- fixing the small case in the original description of this code. It should be tested against a wider set of cases. |
Includes unit test Fixes libgeosGH-665
@dr-jts here's a view of a PostGIS topology built from the input line and its right buffer: Here's a detail: In the detail you can see that by removing faces that are on the left side instead of the right side of the edges forming the input line we should be able (in this case) to obtain what the user wants. |
When I want to create a single sided buffer, GEOS shows strange result even for easy line inputs.
This is my input (
geom
):LINESTRING (50 50, 150 150, 150 100, 150 0)
This is my implementation:
with
d = -21.0
The resulting output shows artifacts from the seconds line segment:
POLYGON ((50 50, 129 129, 129 150, 129.25925925925927 150, 143.92517768386912 143.92517768386912, 150 150, 150 141.408903891521, 164.66591842460988 135.33408157539012, 164.8492424049175 135.1507575950825, 150 120.30151519016499, 150 100, 150 0, 129 0, 129 99.30151519016499, 64.8492424049175 35.1507575950825, 50 50))
If I am removing the vertex in the vertical line (
geom
=LINESTRING (50 50,150 150, 150 0)
) the output is valid:POLYGON ((50 50, 150 150, 150 0, 129 0, 129 99.30151519016499, 64.8492424049175 35.1507575950825, 50 50))
If I am changing to
d = -20.0
, the output is valid as well:POLYGON ((50 50, 150 150, 150 100, 150 0, 130 0, 130 101.7157287525381, 64.14213562373095 35.85786437626905, 50 50))
I am using GEOS 3.11.0.
Why do tiny changes result in a big change in the output?
I can imagine, that it is difficult to implement a single sided buffer algorithm for any strange input line. But this one is not strange, is it?
Some reference I found on the Internet:
https://trac.osgeo.org/geos/ticket/712 (closed with wontfix)
https://trac.osgeo.org/geos/ticket/810 (still open)
http://lin-ear-th-inking.blogspot.com/2010/11/single-sided-buffers-in-jts.html (from Dr JTS)
I was thinking of fixing this issue, with the following approach:
Unfortunately I do not know, how to implement the polygon split in GEOS.
But doing this QGIS or OpenJump result in much better single-sided buffer (even if still not perfect). I tested this with a 50.000 buffer on the coastline from
https://trac.osgeo.org/geos/ticket/810
With cleanup approach:
vs. raw single-sided buffer output
The text was updated successfully, but these errors were encountered: