# Setting the Centroid of a Set of Polygons

I'm trying to shift a set of rectangle polygons over an area of interest (AOI). I thought it would be as easy as setting the SHAPE@TRUECENTROID of the polygon area of interest to the shapefile/featureclass of the rectangles. When multiple polygons are selected in Arcmap, the centroid of the collection of polygons appears.

When attempting to pass the shapefile in to an update cursor, each polygon overlaps over the AOI coordinates instead. Is there a simple, Arcpy, way of sifting the entire set of polygons in a shapefile to be centered over said area of interest? Or put another way, maintain the spatial relationship each rectangle has with one another while shifting the entire set over the AOI.

I should add that I am first rotating the polygons with Arcpy. When running the script it doesn't keep the rotation expected. I would expect setting the centroid would merely shift, not rotate.

EDIT.
Here is the rotate code (this was adapted from another post on here dealing with rotating polygons)

``````def RotateAxis(AnchorX,AnchorY,inputx,inputy, rAngle):
x = inputx - AnchorX
y = inputy - AnchorY
resultx = ((x * math.cos(rAngle)) + (y * math.sin(rAngle))) + AnchorX
resulty = ((x * math.sin(rAngle)) - (y * math.cos(rAngle))) + AnchorY
return (resultx,resulty)
``````

I update the geometry from this then finally after each polygon has been rotated I attempt to perform the shift.

XC and YC are the anchor points which are the SHAPE@XY from my AOI.

Updated Code to reflect bottom picture.

``````memFC = "in_memory\\dissolvedPoly"
arcpy.Dissolve_management(inFC, memFC,"PageNumber")

with arcpy.da.SearchCursor(memFC, ["SHAPE@XY"]) as oFeature:
for row in oFeature:
memX, memY = row[0]

xShift = float(XC) - float(memX)
yShift = float(YC) - float(memY)
print "Shift x " + str(xShift) + " ; Shift y " + str(yShift)

with arcpy.da.UpdateCursor(inFC, ["SHAPE@XY"]) as cfeature:
for row in cfeature:
print "Shifting polygons..."
print ""
print "x = " + str(x), " y = " + str(y)

cfeature.updateRow([[row[0][0] + (xShift), row[0][1] + (yShift)]])
``````

After Shifting Polygons (What I Want)

What I actually get.

EDIT 2:

What I get with the shift x, shift y code.

• the centroid is not the actual polygon object. It is a member that can be used to label. (outside of code) In the gui there is a truecentroid and a centroidwithin Jan 20, 2014 at 18:30
• I understand,however it seemed to be the best way to describe what I am trying to accomplish. Doing what I described above works fine for a single polygon even if its really a member for labeling. I simply set the SHAPE@TRUECENTROID OR SHAPE@XY of the AOI to the shapefile I want to move and I'm done. With multiple polygons, I need to come up with a different solution. Jan 20, 2014 at 18:56

If you want to shift the entire feature using python, and more specifically arcpy.da.updateCursor(), you should apply the shift to the SHAPE@XY token and not to the SHAPE@TRUECENTROID token. This would need you to update each polygon indepently in a loop, but shouldn't destroy your topology if you apply exactly the same shift.

EDIT : thanks for the additional information

from what I see, you should merge your two polygons (e.g. using arcpy.dissolve_management), then compute the shift needed to place the merged polygon at the right place (X of AOI - X of merged polygon, Y of AOI - Y of merge polygon) and finally apply this shift to each individual polygon.

cursor.updateRow([[row[0][0] + (x_shift), row[0][1] + (y_shift)]])

• I just tried the SHAPE@XY however it yields the same result has SHAPE@TRUECENTROID. Each polygon ends up overlapping instead of shifting but maintaining topology. Jan 20, 2014 at 19:10
• can you show a piece of your code and an image ? This would help ! Also, have you compared the shift of your polygons with the shift of your code ? Jan 20, 2014 at 19:18
• Edited original post to show code and images. Jan 20, 2014 at 19:47
• I did just realize something obvious, with my update cursor I am updating the SHAPE@XY for each row, and thus each polygon. However, I'm under the impression that this is the only way to perform and update cursor. The pictures should really help display what I'm after. Jan 20, 2014 at 19:53
• as you can see from my updated answer, you need to apply thesame shift to each polygon and not the same centroid value as you did Jan 20, 2014 at 20:01

I was finally able to get this working with the results I wanted.

It seems there is a discrepancy with the centroid (SHAPE@XY) and the center of the polygon I was looking for. My solution was to use the Minimum Bounding Geometry geoprocessor on the polygon layer. From there I can obtain the centroid of that newly created feature. Surprisingly its different from the centroid of the input feature.

Using the centroid of the new features, I was able to use the code above to center the grids as desired.