Within a Python script, I would like to replace the geometry of all features in Layer A with the geometry of features in Layer B if their ID fields match.
I am not sure how to do this, but the closest I have gotten (conceptually) is by using updateCursor and the SHAPE@ token. The following code kind of makes sense to me, but is not updating the geometry. Does anyone have any suggestions for fixing this code or another method that would work better?
def burnCPP(sgcn_layer, cpp_layer):
# create cursors for Layer A and Layer B
sgcn = arcpy.da.UpdateCursor(sgcn_layer, ["DataSource", "DataID", "SHAPE@"])
cpp = arcpy.da.SearchCursor(cpp_layer, ["EO_ID", "SHAPE@"])
# create list and fill with IDs from Layer A
sgcn_list = []
if row[0] == "PNHP":
sgcn_list.append(str(row[1]))
# create list and fill with matching IDs and geometry of Layer B
match = []
if str(row[0]) in sgcn_list:
match.append([row[0], row[1]])
# start iteration through rows in Layer A
with sgcn as cursor:
for row in cursor:
# for each row in Layer A, start iteration through each list in match
for lists in match:
# if ID in row in Layer A matches ID in list in match fill geometry in Layer A with geometry stored in match list
if row[1] == lists[0]:
row[2] = lists[1]
cursor.updateRow(row)
1 Answer 1
It looks like you're never actually stepping into your SearchCursor on cpp
. It will be more performant if you build a dictionary of cpp_layer first, then use that for the ID lookups.
cpp = {}
with arcpy.da.SearchCursor(cpp_layer, ["EO_ID", "SHAPE@"]) as sCursor:
for row in sCursor:
cpp[row[0]] = row[1]
Then in your UpdateCursor you can just test for the id
match in cpp
.
with arcpy.da.UpdateCursor(sgcn_layer, ["DataSource", "DataID", "SHAPE@"]) as uCursor:
for row in uCursor:
# Update the geometry if it's in cpp.
recordId = row[1]
if recordId in cpp:
row[2] = cpp[recordId]
uCursor.updateRow(row)
-
1This should be the accepted answer, using lookup dictionary will be much faster.crmackey– crmackey2016年09月02日 15:18:29 +00:00Commented Sep 2, 2016 at 15:18
-
This makes sense! However, I am getting a StopIteration: iteration not started error on line 12.mmoore– mmoore2016年09月02日 15:41:15 +00:00Commented Sep 2, 2016 at 15:41
-
-
-
1Change it to
uCursor.updateRow(row)
. I fixed the code example to reflect this.Evan– Evan2016年09月02日 16:03:07 +00:00Commented Sep 2, 2016 at 16:03