When you use a cursor to extract the shape outShape = row.shape it is not a geometry object unfortunately.You have to unpack the parts and then unpack the points inside the parts.Then you can rebuild a geometry object.Here is my FillDonut script as an example. (I have since found that it does not handle all cases of donuts, but I have not fixed it yet.)# fillDonut10.py
# frequent forum request to fill holes
# use an Update Cursor to edit polys with donuts
# 22 May 2010
# Kim Ollivier kimo@ollivier.co.nz
# (c) Creative Commons 3.0 (Attribution)
# Method
# ------
# Polygon features are stored as:
# [[pnt,pnt,pnt,pnt,,pnt,pnt,pnt,pnt][pnt,pnt,pnt,pnt]]
# Parts are separate lists inside the feature object array
# null point in a part indicates donut ring(s) follow
# So just step through and truncate at first null pnt per part,
# re-assemble parts into a polygon
# Update feature if a donut found, otherwise continue
# Input is a layer so can use selection in Arcmap
# could also put on menu at ArcMap 10
# can be back-ported to 9.3
# 4 June 2010
# added iter lambda function for part array because isn't interable
# cleared polyOuter buffer earlier to fix logic for multiple parts
# 7 Nov 2011
# handle double donut parts, if a second+ parts is enclosed
# then have to drop them as well.
import arcpy,sys
def filldonut(inlay) :
'''Edits a layer in-place
fills all features with donuts
requires a layer to honour
selected features
'''
desc = arcpy.Describe(inlay)
shapefield = desc.ShapeFieldName
rows = arcpy.UpdateCursor(inlay)
n = 0
m = 0
polyGeo = arcpy.Array() # to hold edited shape
polyOuter = arcpy.Array() # to hold outer ring
for row in rows:
feat = row.getValue(shapefield)
qInterior = False
id = row.objectid
msg1 = "%d has %d parts" % (row.objectid,feat.partCount)
arcpy.AddMessage(msg1)
for partNum in range(feat.partCount) :
part = feat.getPart(partNum)
for pt in iter(lambda:part.next(),None) : # iter stops on null pt
polyOuter.append(pt)
if part.count > len(polyOuter) :
qInterior = True
g = arcpy.Polygon(polyOuter)
if partNum == 0:
polyGeo.append(polyOuter) # reassemble first part
gOuter = arcpy.Polygon(polyGeo) # make a geometry object
else :
if g.disjoint(gOuter) :
polyGeo.append(polyOuter) # reassemble separate part
else :
m+=1
msg2 = "%d has island at part%d" % (row.objectid,partNum)
arcpy.AddMessage(msg2)
polyOuter.removeAll() # ready for next part
if qInterior : # in any part of this feature, otherwise skip update
n+=1
row.setValue(shapefield,polyGeo)
rows.updateRow(row)
polyGeo.removeAll()
del rows,row
msg = "Features with interior ring filled %d and %d with island donuts" % (n,m)
arcpy.AddMessage(msg)
#----------------------------------------------------
if __name__ == '__main__' :
inlay = sys.argv[1] # arcpy.GetParameterAsText(0)
desc = arcpy.Describe(inlay)
if desc.shapetype != 'Polygon' :
arcpy.AddError(inlay + " Not a polygon class")
else :
filldonut(inlay)
arcpy.RefreshActiveView()