Is a polygon with a hole a multipart polygon?

5885
25
01-09-2018 10:47 AM
EidurEidsson
New Contributor II

Consider the following script, the polygon is a simple one with a hole inside:

import arcpy

poly1 = arcpy.FromWKT("POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))")

print(poly1.isMultipart)
print(poly1.partCount)‍‍‍‍‍‍

The result I get is

>>>
True
1

So is a polygon "multipart" if it has holes? ArcGIS Data Reviewer does not agree.

Thanks

ArcGIS Desktop 10.5.1

Tags (1)
25 Replies
EidurEidsson
New Contributor II

I suspect isMultipart (and its description) is inherited from Geometry, hence the problem (it works fine with multipoints and polylines! why not polygons too?).

A soft landing would be:

1) Keep partCount as it is

2) Keep isMultipart but change the description.and mark as deprecated

3) Add 0...* replacements

Hard landing (if I'm right about the inheritance):

 Override isMultipart to exclude interior rings; keep the description

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Xander Bakker‌, I love the Freudian slip

"parts" of an inferior geometry dimension (like rings or lines)

DanPatterson_Retired
MVP Emeritus

missed that one... very good Xander

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Xander Bakker‌, from what you have written, Jim B. appears open to changing the documentation, not the software/code itself.  At this point I would be surprised to see any core updates/changes to the ArcPy Geometry classes themselves.  ArcPy has been around long enough that changing the behavior of any existing property or method would create a backwards compatibility nightmare for them.

One of my biggest laments with ArcGIS Pro is that Esri didn't use it as an opportunity to really move ArcPy forward, ArcPy Pro if you will.  Sure, the mapping module was redone because it had to be given the massive GUI changes, but so much of the rest of ArcPy was just forklifted over.  Instead of ArcPy Pro, we got ArcGIS API for Python.  Given the ever-growing overlap in functionality, it would be nice if Esri would share a coherent plan for both APIs moving forward, but we all know that is a bridge too far.

Even on the documentation front, it is a bit of a mess.  I suspect the ArcPy isMultiPart property came from IGpDescribeGeometry.IsMultipart Property (ArcObjects .NET 10.5 SDK).  Looking at the entire description for that property, it is as ambiguous and vague as ArcPy's documentation for that property:

Indicates whether the geometry object contains more than one part.

The IPolygon Interface (ArcObjects .NET 10.5 SDK) is fairly robust and includes properties like ExteriorRingCount and InteriorRingCount; but for whatever reasons, the level of nuance was lost in the ArcPy Geometry classes and we ended up with "parts."  I think there are some flaws deep in the ArcPy concept/model and code on this one.  Since I don't see Esri addressing the root issue(s), I think the best we can hope for is a footnote of sort that explains the edge case results.

XanderBakker
Esri Esteemed Contributor

Hi Joshua Bixby , thanks for the extensive response and links provided. You are right, Jim did not mention that the software can be easily adjusted. For now an additional note in the help page to indicate that a polygon with one part (partCount=1) may be a multi-part (isMultipart=True) when the polygon contains one or more holes, since it will be based on more than one ring. At least that way it will reduce the confusion for end-users. I would like to see properties like ExteriorRingCount and InteriorRingCount later on in the API. That would be a great addition.

So, any suggestions for a text that could be added to the help of the isMultipart property of the polygon object as an additional note?

VinceAngelo
Esri Esteemed Contributor

isMultipart appears to be broken for polygons (or at least using a different definition of "multipart polygon" than any other Esri component has ever used). At a minimum, this difference needs to be documented, with a workaround for obtaining the conventional meaning in a reliable manner (using partCount or WKT type). Unfortunately, large polygons (e.g., 1:100k Canada/US/Russia/Australia/Brazil) are very slow in generating Well-Known Text, so using the .WKT method to test for POLYGON/MULTIPOLYGON is a really inefficient means if determining "multi-ness". 

- V

XanderBakker
Esri Esteemed Contributor

Not sure how it performs on a large "multi-part" geometry with many vertices, but on the small example above one could do this to count the rings:

ring_count = len((eval(poly1.JSON.replace(u'null', u'0')))["rings"])
0 Kudos
DanPatterson_Retired
MVP Emeritus

let's not forget, that there are bigger problems with the geometry model... a null point has X and Y coordinates of 

import arcpy

arcpy.Point()
<Point (0.0, 0.0, #, #)>

maybe the basics before rings

0 Kudos
VinceAngelo
Esri Esteemed Contributor

That's not a null point so much as a nominal Point.  A null point would be a PointGeometry with value of None.

Point corresponds to SE_POINT3D in the 'C' API, which is a simple struct type

0 Kudos
DanPatterson_Retired
MVP Emeritus

I know it is nominally null I just prefer Point(nan, nan, nan, nan)

0 Kudos