-1

I have a small list of points, testingPoints, that need their geometry (x and y points) transferred to points within a larger dataset, baseCentroids. The datasets share a common field POINTID to help identify one for the other. This is the code I have:

rowFields = ['POINTID','SHAPE@X', 'SHAPE@Y']
rows = arcpy.SearchCursor(testingPoints, rowFields)
for row in rows:
    whereClause1 = "POINTID = '" + row.getValue('POINTID') +"'"
    pointFields = ['POINTID','SHAPE@X', 'SHAPE@Y']
    points = arcpy.UpdateCursor(baseCentroids, whereClause1, pointFields)
    for point in points:
        point.setValue("SHAPE@X", row.getValue(SHAPE@X))
        point.setValue("SHAPE@Y", row.getValue(SHAPE@Y))

        #tried this method as well
        #point[1]=row[1]
        #point[2]=row[2]

        rows.updateRow(row)

While to me this looks correct it is not.

2
  • 2
    The first rule of cursors is to never use non-DA cursors. The second rule is to avoid nesting cursors (instead, search once into a dictionary, then use that for lookup). If you're copying points, just copy points (PointGeometry objects - with Shape@)
    – Vince
    Commented Jun 1, 2022 at 23:30
  • 2
    What happens when you run the code that you have presented? Better still what happens when you convert your cursors to arcpy.da cursors and use a dictionary to avoid nesting them?
    – PolyGeo
    Commented Jun 2, 2022 at 1:07

1 Answer 1

2

Using the three basic principles of ArcPy cursors

  1. Always use Data Access cursors
  2. Avoid nesting cursors (instead, search once into a dictionary, then use that for lookup)
  3. Use Geometry where possible

and assuming

  • The "small list" of point IDs is a small subset of the overall point set, and
  • The coordinate reference systems of the two feature classes are identical,

we get:

fieldNames = ['POINTID','Shape@']
pointById = {}
with arcpy.da.SearchCursor(testingPoints,fieldNames) as cursor:
    for row in cursor:
        pointById[row[0]] = row[1]

with arcpy.da.UpdateCursor(baseCentroids,fieldNames,
            "{:s} IN ('{:s}')".format('"POINTID"',"','".join(list(pointById)))) as cursor:
    for i,row in enumerate(cursor):
        row[1] = pointById[row[0]]
        cursor.updateRow(row)
print("{:d} feature{:s} updated".format(
        i,'' if i == 1 else 's'))

Further insights:

  • Never mix DA and non-DA cursor syntax
  • The field_names parameter always comes before where_clause
  • Never attempt to update SearchCursor rows
  • Never perform string math (use str.format() instead)
  • Leverage str.join() to construct lists (but keep track of the quotes)

Note: While this does look like it's correct, you should test it (and add print statements anywhere you're unsure of what is happening)

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.