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.

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)]])

Before Shifting Polygons(What I start with) Before Shift

After Shifting Polygons (What I Want)

After Shift

What I actually get.

What I Get


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

With Shift 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
    – Brad Nesom
    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.
    – amasephy
    Jan 20, 2014 at 18:56

2 Answers 2


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.
    – amasephy
    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 ?
    – radouxju
    Jan 20, 2014 at 19:18
  • Edited original post to show code and images.
    – amasephy
    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.
    – amasephy
    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
    – radouxju
    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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.