question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Intersection and difference of polygons leads to (almost) self-touching polygon

See original GitHub issue

First of all, thank you very much for Shapely, it’s an awesome library!

Expected behavior and actual behavior.

I am intersecting and differencing polygons, expecting a valid, non-self-touching polygon. I often get almost-self touching polygons, which are a problem when I want to offset the contour of my intersection.

Steps to reproduce the problem.

Minimal example:

import numpy as np
import shapely.geometry
import shapely.wkt
import matplotlib.pyplot as plt


def plot_line(ob, clr='k', alpha=1.0):
    x, y = ob.boundary.xy
    ax.plot(x, y, color=clr, alpha=alpha)


container = shapely.geometry.Polygon(np.array([[20, 0],
                                               [35, 0],
                                               [35, -4],
                                               [20, -4],
                                               [20, 0]]))

pol = shapely.wkt.loads('POLYGON ((20.96 -2.168465542645916, 20.96 -1.189012617488881, 21.45875 -1.243766028311074, 22.62625 -1.364459833901519, 23.82 -1.480114679188134, 25.04 -1.590616286024315, 26.28625 -1.695512902750364, 27.5575 -1.794581333999776, 28.85375 -1.887359106259452, 30.175 -1.973623024162885, 31.52125 -2.053149892343578, 32.89125 -2.125596876361725, 34.28375 -2.18947836031152, 35.7 -2.244108675313356, 37.14 -2.290391324686642, 38.60124999999999 -2.328342391211475, 40.08375 -2.357831513961157, 41.58875 -2.37452684521826, 43.115 -2.381274616794401, 44.6625 -2.378874775715786, 46.23 -2.365052480903801, 47.8175 -2.336940056840027, 49.04 -2.308339084072406, 49.04 -3.307403246304138, 47.74722712561048 -3.337648286610996, 46.18464384097614 -3.365319470190588, 44.64476964447845 -3.378898159260675, 43.11990828613942 -3.381262892654494, 41.61527865723328 -3.37461070786003, 40.13672701151798 -3.358208774633484, 38.67965497406949 -3.329225451754934, 37.23932976613535 -3.291817836505181, 35.82084591271953 -3.246226731762603, 34.4280288046949 -3.192500315274461, 33.05991692034544 -3.129737645700606, 31.71239101679935 -3.058479114606998, 30.38724893438113 -2.980199151963237, 29.08723955504806 -2.895322026231939, 27.81243913152114 -2.804079485541084, 26.56253324382854 -2.706674399599603, 25.33767818412468 -2.603578590778966, 24.13915400788448 -2.49502215856048, 22.96699171228969 -2.381458808656548, 21.82119777103192 -2.263008931831816, 20.96 -2.168465542645916))')
pol = pol.intersection(container)
container = container.difference(pol)

rectangle1 = shapely.geometry.Polygon(np.array([[22, -1.4],
                                               [31, -1.4],
                                               [31, -2],
                                               [22, -2],
                                               [22, -1.4]]))
intersection1 = container.intersection(rectangle1)
container = container.difference(intersection1)

rectangle2 = shapely.geometry.Polygon(np.array([[29, -1.8],
                                                [31.5, -1.8],
                                                [31.5, -2.5],
                                                [29, -2.5],
                                                [29, -1.8]]))
intersection2 = container.intersection(rectangle2)

ax = plt.gca()
plot_line(ob=container, clr='r', alpha=0.5)
plot_line(ob=pol, alpha=0.5)
plot_line(ob=intersection1, alpha=0.5)
plot_line(ob=intersection2, clr='b')
plt.show()

With this code I get: issue04 Note the almost self-touching part of the polygon.

Illustration

On another intersection, I got: issue02 And by zooming (a lot): issue03

Attempted solutions

The buffer(0) trick or this stackoverflow answer do not seem to solve my issue. I’ve been able to work around this issue until now but it has become a real problem. In this case, I need a clean polygon in order to obtain a linear_ring from an offset of my final intersection, but in general it would be very good to obtain clean intersections. Any idea where this issue comes from? Thanks for your help

Operating system

Windows 7 Python 3.6.7

Shapely version and provenance

Shapely-1.6.4.post1-cp36-cp36m-win_amd64.whl

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
dr-jtscommented, Mar 25, 2019

Happy to help. I’m going to try and port this to JTS code, since it’s a fine example of why a precision model is needed. Improving JTS/GEOS support for this is the number one goal of development for this year. So maybe that will provide some motivation to do some Shapely development.

0reactions
Arkanguscommented, Apr 1, 2019

Thank you @sgillies and especially @dr-jts for the answers. I get a clean cut with your answer 😃

issue#2 solved

Read more comments on GitHub >

github_iconTop Results From Across the Web

polygon/ring self-intersection correct · Issue #868 - GitHub
I have developed a polygon correct approach (remove self-intersection, correct order, correct inners), based on boost geometry:
Read more >
GEOS_ERROR: TopologyException: Input geom 1 is invalid
The self-intersection error you get is probably due to an invalid geometry. The recursive union in you loop might return invalid geometries ...
Read more >
Polygons - George W. Hart
A polygon can be self-intersecting, meaning edges cross other edges. (The points of intersection are not vertices.) Regular polygons which are not self- ......
Read more >
How Intersect works—ArcGIS Pro | Documentation
The Intersect tool calculates the geometric intersection of any number of feature classes and feature layers. The features, or portion of features, ...
Read more >
An Almost Optimal Bound on the Number of Intersections of ...
If exactly one polygon, say the n-gon, has an odd number of sides, it can intersect each side of the m-gon polygon at...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found