Skip to content
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

Fix buffer to use largest enclosed area for invalid rings #655

Merged
merged 3 commits into from
Dec 22, 2020

Conversation

dr-jts
Copy link
Contributor

@dr-jts dr-jts commented Dec 21, 2020

The buffer algorithm has a long-standing issue where a polygon with a small self-intersecting lobe at the top of the polygon gets reduced to just the small lobe, rather than the small lobe being removed. See for example #629. This issue can also occur in hole rings.

image

This issue also affects JTS algorithms which use the buffer(0) trick to produce valid polygons (such as DouglasPeuckerSimplifier, VWSimplifier and Densifier). For example, #498.

The issue occurs because buffer has to determine the interior of a ring to know which side to build the buffer offset curve on (which in the case of a zero-width buffer is just the ring linework). Currently buffer uses the Orientation.isCCW test to do this. For efficiency this algorithm determines ring orientation by checking only the line segments incident on the uppermost vertex of the ring. For a valid ring (where the linework does not cross itself) this works fine. However, in a self-crossing ring (aka a "bow-tie") which lobe is chosen as the interior is not well-defined. The uppermost vertex approach can end up choosing a very small lobe to be the "interior" of the polygon.

The fix is to use an orientation test which takes into account the entire ring. This is provided by the Signed-Area Orientation test. This effectively determines the orientation based on the largest area enclosed by the ring. This corresponds much more closely to user expectation based on visual assessment. It also minimizes the change in area and (usually) extent.
image

Signed-off-by: Martin Davis <mtnclimb@gmail.com>
Signed-off-by: Martin Davis <mtnclimb@gmail.com>
Signed-off-by: Martin Davis <mtnclimb@gmail.com>
@dr-jts dr-jts self-assigned this Dec 22, 2020
@dr-jts dr-jts changed the title Fix buffer(0) to return largest area Fix buffer to use largest enclosed area for invalid rings Dec 22, 2020
@dr-jts
Copy link
Contributor Author

dr-jts commented Dec 22, 2020

Fixes #629.
Fixes #498.

@dr-jts dr-jts merged commit 71cde70 into locationtech:master Dec 22, 2020
@dr-jts dr-jts deleted the fix-buffer-0 branch December 22, 2020 01:00
jagill added a commit to jagill/presto that referenced this pull request Dec 24, 2020
Relevant parts:
* Vastly improved overlay operations (intersection, union, etc).  This
  will allow us to use JTS operations (currently using ESRI).
  + TopologicalExceptions have been mostly eliminated.
  + Performance is improved.  For geometries that intersect in a small
    fraction of their area, performance is greatly improved.
  + More accurate in some cases.
  + https://locationtech.github.io/jts/javadoc/org/locationtech/jts/operation/overlayng/package-summary.html
* Fix for `buffer` and `DouglasPeuckerSimplifier`: in some cases, the
   majority of the polygon would be dropped:
  + locationtech/jts#655
  + locationtech/jts#498
* `WKBWriter` writes empty polygons in a fashion consistent with other
  libraries/tools.

More details: https://github.com/locationtech/jts/releases/tag/jts-1.18.0
pramsey added a commit to pramsey/geos that referenced this pull request Dec 30, 2020
strk pushed a commit to libgeos/geos that referenced this pull request Dec 30, 2020
strk pushed a commit to libgeos/geos that referenced this pull request Dec 30, 2020
mbasmanova pushed a commit to prestodb/presto that referenced this pull request Jan 4, 2021
Relevant parts:
* Vastly improved overlay operations (intersection, union, etc).  This
  will allow us to use JTS operations (currently using ESRI).
  + TopologicalExceptions have been mostly eliminated.
  + Performance is improved.  For geometries that intersect in a small
    fraction of their area, performance is greatly improved.
  + More accurate in some cases.
  + https://locationtech.github.io/jts/javadoc/org/locationtech/jts/operation/overlayng/package-summary.html
* Fix for `buffer` and `DouglasPeuckerSimplifier`: in some cases, the
   majority of the polygon would be dropped:
  + locationtech/jts#655
  + locationtech/jts#498
* `WKBWriter` writes empty polygons in a fashion consistent with other
  libraries/tools.

More details: https://github.com/locationtech/jts/releases/tag/jts-1.18.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant