Recently
Sean Gillies and
others have been looking at the concept of geometric
simplicity as implemented in
JTS/GEOS, specifically in the case of polygons. The
TL;DR is that JTS has a bug because it reports the following polygon as simple:
POLYGON ((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, 39.14513303 23.75100816))
This polygon is invalid, because the shell ring self-intersects. This means the ring is non-simple - but it's not so clear-cut for the polygon itself.
In fact, reporting the polygon as simple isn't a bug - it was a deliberate design decision. The original rationale was:
- the OGC Simple Features Specification in section 2.1.10 defining polygon geometries states that "Polygons are simple geometries". (This is consistent with the requirement that valid polygons contain no self-intersections).
- JTS usually follows the principle that computed results are only well-defined when the input geometries are valid. This is because it can be expensive to check for validity in order to handle invalid inputs gracefully. Validity testing is factored out into a separate method (isValid) in order to allow the client to decide when to incur the code of executing it.
For these reasons the initial JTS implementation of
isSimple returned
true for all polygonal inputs, thus avoiding the cost of checking for self-intersections.
However, perhaps it would be more useful to actually carry out some testing of simplicity. This raises the question of what exactly are the semantics of
isSimple for polygons? Looking to the SFS for guidance, it has the following somewhat imprecise general definition of simplicity:
the Geometry 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.
For polygons the spec simply states:
Polygons are simple geometries
(In contrast, for linear geometry the specification has a rigorous mathematical definition of simplicity.)
Apart from the "always simple" semantics, there are at least two other options:
- Polygons are simple if their component rings are simple (i.e. have no self-intersections)
- Polygons are simple if they have no topological anomalies. This is equivalent to checking whether the polygon is valid.
Because option #2 simply replicates the semantics of
isValid, it seems more useful to adopt option #1 to provide more possibilities for analyzing polygon topology (but I'm definitely open to suggestions about why #2 would be better!)
This change to the semantics of
isSimple has been implemented in JTS and will appear in the 1.13 release. The code will also be extended to handle GeometryCollections, with the semantics that they are simple if all their components are simple.