I am trying to update the geometry of some features (polygons) to allow stretching / shrinking in the X and Y planes, but am struggling to get this to work for multipart polygons and for those with an inner ring (donut polygons). I am struggling to find a solution online and with weak Python skills and suspect something simple is wrong in my code - possibly indentation in the final part of the program?
Two issues arise in this code- 1.) multipart polygons are only updated for their first part and therefore become single part, and 2.) the inner ring is lost in the donut polygon.
Attaching a before processing and after image to show the issue, shapefile and code. Looking at the after image (cyan polygons), my blue (multipart) polygons are not replicated properly, and my donut polygon (red) becomes a single area with no inner gap.
Is this just indentation, or do I need more looping to deal with the multipart & inner ring logic correctly?
Code:
import arcpy
def stretch_features(in_features, x_stretch=None, y_stretch=None):
with arcpy.da.UpdateCursor(in_features, ['OID@', 'SHAPE@XY', 'SHAPE@']) as cursor:
for row in cursor:
Xc = row[1][0]
Yc = row[1][1]
print("Feature {}, at {}, {}".format(row[0] ,Xc, Yc))
geometry = row[2]
partnum = 0
for part in geometry:
print("Part {}:".format(partnum))
pts = geometry.getPart(partnum)
pt_array = arcpy.Array()
for pnt in pts:
if pnt:
#print("old {}, {}, new {}, {}".format(pnt.X, pnt.Y, Xc-((Xc-pnt.X) * x_stretch or 1), Yc-((Yc-pnt.Y) * y_stretch or 1)))
pnt.X = Xc-((Xc-pnt.X) * x_stretch or 1)
pnt.Y = Yc-((Yc-pnt.Y) * y_stretch or 1)
pt_array.add(pnt)
else:
print("interior ring")
print("old inner {}".format(pnt))
pt_array.add(pnt)
#pt_array.add(None)
partnum += 1
new_polygon_geometry = arcpy.Polygon(pt_array)
row[2] = new_polygon_geometry
cursor.updateRow(row)
return
in_features = r"D:\ReShapeFeatures\TestPolygons.shp"
stretch_features(in_features, x_stretch=.75, y_stretch=.75)