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

polygon is_simple is wrong #16

Closed
sfornengo opened this issue Jul 5, 2012 · 15 comments
Closed

polygon is_simple is wrong #16

sfornengo opened this issue Jul 5, 2012 · 15 comments
Milestone

Comments

@sfornengo
Copy link

using version 1.2.14 on ubuntu 12.04/64 bits, and the following points:
pts=[[ 39.14513303, 23.75100816],
[ 97.05372209, 40.54550088],
[ 105.26527014, 48.13302213],
[ 100.91752685, 58.43336815],
[ 71.56081448, 83.55114801],
[ 60.71189168, 86.25316099],
[ 62.00469808, 75.1478176 ],
[ 83.16310007, 42.82071673],
[ 92.82305862, 37.19175582],
[ 95.99401129, 26.47051246],
[ 106.22054482, 15.51975192]]
print Polygon(pts).is_simple
says "True" while it clearly is not:
import pylab
x=map(lambda v:v[0],pts)
y=map(lambda v:v[1],pts)
pylab.plot(x,y)
pylab.plot(x,y,'or')
pylab.show()

@olt
Copy link
Contributor

olt commented Aug 29, 2012

It's a tie-bow (self-intersection). See WKT geometry:

POLYGON ((39.1451330299999967 23.7510081600000014, 97.0537220899999937 40.5455008799999987, 105.2652701399999984 48.1330221300000005, 100.9175268500000016 58.4333681499999997, 71.5608144800000048 83.5511480100000057, 60.7118916800000008 86.2531609899999978, 62.0046980799999972 75.1478175999999962, 83.1631000699999987 42.8207167300000009, 92.8230586199999976 37.1917558199999974, 95.9940112900000031 26.4705124599999984, 106.2205448200000006 15.5197519199999991, 39.1451330299999967 23.7510081600000014))

To visualize: http://dev.openlayers.org/sandbox/docs/examples/wkt.html

Sounds like a bug in GEOS for me. is_simple returns True, but is_valid False.
I can confirm that with GEOS 3.3.2, will have to check that with a more recent version.

@sgillies
Copy link
Contributor

I'm not sure what the intent is in GEOS, but it may be that its simplicity test is not reliable for polygons. Check out this case of a square polygon with a hole occupying all of its lower left quadrant. The rings themselves are simple, but they touch and therefore make an "invalid" polygon:

q.wkt
POLYGON ((0.0000000000000000 0.0000000000000000, 0.0000000000000000 2.0000000000000000, 2.0000000000000000 2.0000000000000000, 2.0000000000000000 0.0000000000000000, 0.0000000000000000 0.0000000000000000), (0.0000000000000000 0.0000000000000000, 0.0000000000000000 1.0000000000000000, 1.0000000000000000 1.0000000000000000, 1.0000000000000000 0.0000000000000000, 0.0000000000000000 0.0000000000000000))
q.is_valid
False
q.is_simple
True

I'm asking Sandro for clarification.

@rburhum
Copy link

rburhum commented Aug 29, 2012

Looks like a GEOS bug for sure. This is what the OGC Simple Features spec says: "IsSimple ( ): Integer — Returns 1 (TRUE) if this geometric object has no anomalous geometric points, such as self intersection or self tangency. The description of each instantiable geometric class will include the specific conditions that cause an instance of that class to be classified as not simple. The return type is integer, but is interpreted as Boolean, TRUE=1, FALSE=0."

The tie-bow self-intersects.

@sgillies
Copy link
Contributor

@sgillies
Copy link
Contributor

I've checked JTS 1.8 too, with Clojure because it has a REPL :)

krusty-2:c0 seang$ ./clj
Clojure 1.3.0
user=> (def wkt
    "POLYGON ((0 0, 0 2, 2 2, 2 0, 0 0), (0 0, 0 1, 1 1, 1 0, 0 0))")
#'user/wkt
user=> wkt
"POLYGON ((0 0, 0 2, 2 2, 2 0, 0 0), (0 0, 0 1, 1 1, 1 0, 0 0))"
user=> (def p (.read (com.vividsolutions.jts.io.WKTReader.) wkt))
#'user/p
user=> p
#<Polygon POLYGON ((0 0, 0 2, 2 2, 2 0, 0 0), (0 0, 0 1, 1 1, 1 0, 0 0))>
user=> (.getArea p)
3.0
user=> (.isValid p)
false
user=> (.isSimple p)
true

Same situation.

@rburhum
Copy link

rburhum commented Aug 31, 2012

Ah, might as well ask Martin in the JTS list then.

@sgillies
Copy link
Contributor

This would seem to be the final word:

"Returns true, since by definition LinearRings are always simple."

http://www.vividsolutions.com/jts/javadoc/com/vividsolutions/jts/geom/LinearRing.html#isSimple()

Rings are always simple, therefore Polygons will always be simple. I'll make sure this is noted in the Shapely manual.

@rburhum
Copy link

rburhum commented Aug 31, 2012

The fact that the operation is being passed to the ring is an implementation detail. A polygon that self intersects is not simple. I tested in ESRI-land and it returns "not simple" correctly.

@rburhum
Copy link

rburhum commented Aug 31, 2012

In all fairness, it is not your bug, it is on JTS :-)

@sgillies sgillies reopened this Aug 31, 2012
@sgillies
Copy link
Contributor

Agreed. I reopened the bug. I think we should break with JTS and GEOS in this case.

@rburhum
Copy link

rburhum commented Sep 6, 2012

Based on this conversation on IRC, it seems it is open to interpretation and it will not be changed http://irclogs.geoapt.com/gdal/%23gdal.2012-09-06.log Just an FYI so you can close the ticket

@sgillies
Copy link
Contributor

RBURHUM, what do you do with the results of is_simple?

@rburhum
Copy link

rburhum commented Sep 13, 2012

On an ESRI stack, I usually use it to check for self-intersection of the internal components. On other implementations, nothing, I use isValid() instead. See this ESRI doc http://help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/index.html#/IsSimple_Property/002m000003vv000000/

@sgillies
Copy link
Contributor

What I've done for Shapely 1.2.16 is note in the manual that is_simple isn't meaningful for polygons, but i've changed the implementation for the LinearRing class so that in the case of olt's bowtie (above), we get

>>> p = loads(wkt) 
>>> p.is_simple
True
>>> p.exterior.is_simple
False

@rburhum
Copy link

rburhum commented Sep 16, 2012

Makes a lot of sense until/if JTS decides to change their implementation.

On Sun, Sep 16, 2012 at 12:18 PM, Sean Gillies notifications@github.comwrote:

What I've done for Shapely 1.2.16 is note in the manual that is_simple
isn't meaningful for polygons, but i've changed the implementation for the
LinearRing class so that in the case of olt's bowtie (above), we get

p = loads(wkt)
p.is_simple
True
p.exterior.is_simple
False


Reply to this email directly or view it on GitHubhttps://github.com//issues/16#issuecomment-8597916.

jorisvandenbossche pushed a commit to jorisvandenbossche/shapely that referenced this issue Nov 6, 2021
Refactor functions into separate modules
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants