Select to view content in your preferred language

For a polygon with a hole, why both partCount and isMultipart same to 1(True) ?

636
5
09-11-2023 06:36 PM
pyfans
by
Emerging Contributor

As the isMultipart means " True if the count of the geometry's part greater than 1", I think it equals to "partCount > 1", but for a polygon geometry with a hole, isMultipart is True but partCount is 1, so how to understand? thank you. 

Tags (2)
0 Kudos
5 Replies
DanPatterson
MVP Esteemed Contributor

From the related links

Is a polygon with a hole a multipart polygon? - Esri Community


... sort of retired...
0 Kudos
pyfans
by
Emerging Contributor

Thank you, so I should use partCount to judge a shape is a true multi-part geometry, not isMultipart ?  

0 Kudos
DanPatterson
MVP Esteemed Contributor

To quote esri, for a polygon example

Multipart polygon features are polygons that contain more than one part or have a hole. For example, if the state of Hawaii was modeled as one feature in the database, it would be a multipart polygon. The geodatabase allows for multipart polygons, but some data models do not.


... sort of retired...
0 Kudos
VinceAngelo
Esri Esteemed Contributor

What are you quoting there, Dan? Because "multi-part" and "multi-ring" get conflated. 

The rules in the underlying SgShape API are clear: A polygon is defined by one or more (non-self-intersecting) rings.  One ring is clearly not multi-part, but an island with a lake (or a county with a contained city) is multi-ring, but still single-part (the underlying API calls internal rings "subparts").

What we have here is two different definitions in the same API (which can happen when three different models are merged):

  1. The arcpy.Polygon.isMultipart method uses the Boolean for "has multiple rings"
  2. The arcpy.Polygon.partCount method uses parts and subparts definition for parts

This script:

 

import arcpy

sr = arcpy.SpatialReference(4326)
sr.setFalseOriginAndUnits(-400.0,-400.0,1000)

p1r1_wkt = 'POLYGON ((0 0, 9 0, 9 9, 0 9, 0 0))'
p1r2_wkt = 'POLYGON ((0 0, 9 0, 9 9, 0 9, 0 0), (4 4, 6 4, 6 6, 4 6, 4 4))'
p2r2_wkt = 'MULTIPOLYGON (((0 0, 4 0, 4 4, 0 4, 0 0)), ((5 5, 9 5, 9 9, 5 9, 5 5)))'
p2r3_wkt = 'MULTIPOLYGON (((0 0, 4 0, 4 4, 0 4, 0 0), (1 1, 3 1, 3 3, 1 3, 3 3)), ((5 5, 9 5, 9 9, 5 9, 5 5)))'

for wkt in [p1r1_wkt,p1r2_wkt,p2r2_wkt,p2r3_wkt]:
    geom = arcpy.FromWKT(wkt,sr)

    isMulti   = geom.isMultipart
    partCount = geom.partCount
    ringCount = geom.boundary().partCount
    
    print(f"{wkt}\nMultipart: {isMulti}, Part Count: {partCount}, Ring Count: {ringCount}\n")

 

returns:

 

POLYGON ((0 0, 9 0, 9 9, 0 9, 0 0))
Multipart: False, Part Count: 1, Ring Count: 1

POLYGON ((0 0, 9 0, 9 9, 0 9, 0 0), (4 4, 6 4, 6 6, 4 6, 4 4))
Multipart: True, Part Count: 1, Ring Count: 2

MULTIPOLYGON (((0 0, 4 0, 4 4, 0 4, 0 0)), ((5 5, 9 5, 9 9, 5 9, 5 5)))
Multipart: True, Part Count: 2, Ring Count: 2

MULTIPOLYGON (((0 0, 4 0, 4 4, 0 4, 0 0), (1 1, 3 1, 3 3, 1 3, 3 3)), ((5 5, 9 5, 9 9, 5 9, 5 5)))
Multipart: True, Part Count: 2, Ring Count: 3

so we can see the dichotomy.

If you want to use the OGC definition of Polygon, then you have to deal with three conditions:

  • Zero rings ("POLYGON EMPTY") [In the Esri lexicon, this is a Nil-type geometry, not a Polygon]
  • One ring
  • One external ring and one or more internal rings

So, at this point it becomes rote: 

  • geom.isMultipart really means "Has multiple rings" and,
  • geom.partCount == 1 is really "Is single part?"
  • If you really want to know how many rings are present, use geom.boundary().partCount

- V

 

DanPatterson
MVP Esteemed Contributor
0 Kudos