AnsweredAssumed Answered

DA Cursor Transfer of Shape Field Geometry is Not Working Correctly

Question asked by rfairhur24 Champion on Dec 13, 2019
Latest reply on Dec 13, 2019 by rfairhur24

If I use a relate to select the features in the feature class I want to update and delete them, and then use the Append tool to insert the features from the source feature class, the geometry matches exactly. However, this changes the original ObjectIDs of the features in the updated feature class, which I wanted to avoid.


The features shown below that are semi-transparent blue with red outlines have the source geometry I want to transfer and features that are orange with grey outlines are the features I want to change before I have done any update.

The features shown below are the result of deleting the original features and using the Append tool.  The geometry matches exactly, but the ObjectIDs have changed.

I have written several versions of a script designed to preserve the ObjectIDs and transfer the geometry in the Shape field of one feature class using an da.UpdateCursor from the Shape field in another that match on the values of another field using both a Dictionary populated by a da.SearchCursor and directly from a da.SearchCursor, but the geometry that is transferred is not the same as the source geometry.  I have tried variations of the script that used or did not use the Spatial Reference parameter of one or both cursors, but that does not fix the problem.


The features shown below are the result of using a da.UpdateCursor to transfer the geometry.  The ObjectIDs have not changed and the geometries have changed, but the transferred geometries are not identical to the source geometry.


Has anyone else experienced this and come up with a solution that both preserves the original OBJECTIDs and correctly transfers geometry that is identical with the source geometry?


Here is one of the scripts I tried.  The script completes without error and the geometry of the updated feature class is being changed, but the output geometry is not identical to the source geometry as shown above.

from time import strftime  
print("Start script: " + strftime("%Y-%m-%d %H:%M:%S")  )
import arcpy 

desc = arcpy.Describe(r"Y:\GISData\rfairhur\Layers\Transform_Parcel_Layers\Transform_Parcel_Layers.gdb/ZONING_POST_DESERT_EXTRACT")
sourceFC = r"Y:\GISData\rfairhur\Layers\Transform_Parcel_Layers\Transform_Parcel_Layers.gdb/ZONING_POST_DESERT_EXTRACT"

sourceFieldsList = ['OIDLIST','SHAPE']
# Use list comprehension to build a dictionary from a da SearchCursor 
valueDict = {r[0]:r[1] for r in arcpy.da.SearchCursor(sourceFC, sourceFieldsList, spatial_reference=desc.spatialReference)} 
updateFC = r"Y:\GISData\rfairhur\Layers\Transform_Parcel_Layers\Transform_Parcel_Layers.gdb/ZONING_POST_DESERT_CURSOR" 
updateFieldsList = ['OIDLIST','SHAPE'] 

count = 0 

desc = arcpy.Describe(r"Y:\GISData\rfairhur\Layers\Transform_Parcel_Layers\Transform_Parcel_Layers.gdb/ZONING_POST_DESERT_CURSOR")
with arcpy.da.UpdateCursor(updateFC, updateFieldsList, spatial_reference=desc.spatialReference) as updateRows: 
    desc = arcpy.Describe(r"Y:\GISData\rfairhur\Layers\Transform_Parcel_Layers\Transform_Parcel_Layers.gdb/ZONING_POST_DESERT_EXTRACT")
    for updateRow in updateRows: 
        # store the Join value of the row being updated in a keyValue variable 
        keyValue = updateRow[0] 
         # verify that the keyValue is in the Dictionary 
        if keyValue in valueDict:
            expression = "OIDLIST = '" + keyValue + "'"
            with arcpy.da.SearchCursor(sourceFC, sourceFieldsList, where_clause=expression, spatial_reference=desc.spatialReference) as sourceRows:
                for sourceRow in sourceRows:
                     # transfer the value stored under the keyValue from the dictionary to the updated field. 
                    updateRow[1] = sourceRow[1]
                    count += 1
            if count % 50 == 0:
                print("Fixed " +str(count) + " Zone Features: " + strftime("%Y-%m-%d %H:%M:%S") )

print("Fixed " +str(count) + " Zone Features: " + strftime("%Y-%m-%d %H:%M:%S") )
del valueDict 
print( "Finished script: " + strftime("%Y-%m-%d %H:%M:%S") )