The Single Multipart:  Polygons With Interior Boundaries

Blog Post created by bixb0012 on Feb 20, 2016

The ArcPy Geometry classes have been around since ArcPy was introduced in ArcGIS 10.0.  ArcGIS 10.1 brought some noticeable enhancements to ArcPy, including additional properties and methods to the Geometry classes.  There have been bug fixes and enhancements with newer releases, as well as a Call for More Pythonic ArcPy Geometries, but the classes haven't changed much over the past 4 years.  This is why I was a bit surprised when I ran into an issue with the ArcPy Polygon class recently.  The surprise wasn't that I ran into an issue, but more that I hadn't run into it or noticed it earlier than now.

The ArcPy Polygon isMultipart and partCount properties have been around since ArcGIS 10.0.  Interestingly enough, the documentation for them hasn't changed one word in that time.

The issue I ran into can be demonstrated by two square polygons, one of which has a hole in it:

>>> # Create the 2 polygons
>>> poly = arcpy.FromWKT('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))')
>>> poly_hole = arcpy.FromWKT('POLYGON((12 0, 22 0, 22 10, 12 10, 12 0),'
...                                   '(15 3, 15 7, 19 7, 19 3, 15 3))')
...
>>> # Check the number of parts
>>> poly.partCount
1
>>> poly_hole.partCount
1
>>>
>>> # Check the multipart property
>>> poly.isMultipart
False
>>> poly_hole.isMultipart
True
>>>

Wait a second, something doesn't add up here.  Both polygons have 1 part, but the polygon with a hole in it is a multipart?  It seems we are witnessing the multi-part single-part polygon, a sideshow favorite that you don't even have to visit the circus to see.

The facile explanation is that the polygon with a hole in it is a multipart because it has an exterior and interior boundary, as opposed to the other polygon that only has an exterior boundary.  Multiple parts, see, simple.  The explanation does make sense, but it also implies that partCount has been broken since ArcGIS 10.0.  Well, maybe partCount has been working all along and the documentation has been wrong for 6 years.  Then again, maybe isMultipart has been broken for 6 years.  Who knows, not me, but I just can't believe I haven't been bitten by this bug long before now.

In terms of what next, assuming Esri Development acknowledges this is either a software or documentation bug, my money is on the documentation getting updated, eventually.  It is always easier to add additional footnotes and asterisks to documentation than it is to update code.  That said, I think there is actually a larger problem with the ArcPy Geometry classes.

I spent some time trying the example above in different spatial systems, even other Esri software components outside of ArcPy, and I have come to the conclusion the real problem is in the labels themselves.  Specifically, the problem lies in the use of "part" to talk about geometries.  Take a look at the List of SQL functions for Esri's ST_Geometry data type, the OGC Methods on Geometry Instances for Microsoft's geometry data type, or the PostGIS Reference; you will not find a single function, method, or property with the word "part" in it.  There are accessor functions for counting geometries, but they count "geometries" and not "parts."  There are accessor functions for counting interior rings, but they count "interior rings" and not "parts."  You see where this is going.

The problem with the ArcPy Geometry classes, at least one of them, is that Esri replaced multiple, specific geometry components with a single generic one, the "part."  By abstracting geometries and rings with parts, not only did they deviate from geospatial standards and norms, they created the sideshow-worthy multi-part single-part polygon.