I need to update the PrivateRoads 'Owner' field based on what city the private road is in. I have the following but it take for ever but doesn't populate the correct city. I know I can do a spatial join but I don't want to create a separate layer.
import sys, os, arcpy
import arcpy
## Works in file geodatabase
arcpy.env.overwriteOutput = True
workspace = "C:/temp/temp.gdb"
PR = "PrivateRoads"
CityLimits = 'City_Limits'
arcpy.MakeFeatureLayer_management(PR, "polyLyr")
arcpy.MakeFeatureLayer_management(CityLimits, "CitLyr")
with arcpy.da.UpdateCursor(PR, ['SHAPE@', 'OID@', 'Owner']) as cursor:
for row in cursor:
arcpy.management.SelectLayerByLocation("polyLyr", "HAVE_THEIR_CENTER_IN", "CitLyr", "", "NEW_SELECTION")
with arcpy.da.SearchCursor("CitLyr", ['CITY']) as cCursor:
for cRow in cCursor:
row[2] = cRow[0]
cursor.updateRow(row)
I would try to restructure the code roughly as follows:
import sys, os, arcpy
import arcpy
## Works in file geodatabase
arcpy.env.overwriteOutput = True
workspace = "C:/temp/temp.gdb"
PR = "PrivateRoads"
CityLimits = 'City_Limits'
arcpy.MakeFeatureLayer_management(PR, "polyLyr")
arcpy.MakeFeatureLayer_management(CityLimits, "CitLyr")
arcpy.management.SelectLayerByLocation("polyLyr", "HAVE_THEIR_CENTER_IN", "CitLyr", "", "NEW_SELECTION")
pr_oid_to_city_name = dict()
# Add code here to use a search cursor scan the polyLyr and
# populate the dict that maps the pr oid to the city name
with arcpy.da.UpdateCursor(PR, ['OID@', 'Owner']) as cursor:
for oid, owner in cursor:
if oid in pr_oid_to_city_name.keys():
cursor.updateRow([oid, pr_oid_to_city_name[oid])
I tried the following but the print only prints one of the cities and for some reason it's populates only a a few private roads that are not inside city limits. Some of these will not be in a city.
I honestly thought it would simple and wouldn't' involve .keys or dicts.
import sys, os, arcpy
arcpy.env.overwriteOutput = True
workspace = "C:/temp/temp.gdb"
PR = "PrivateRoads"
CityLimits = 'City_Limits'
arcpy.MakeFeatureLayer_management(PR, "polyLyr")
arcpy.MakeFeatureLayer_management(CityLimits, "CitLyr")
arcpy.management.SelectLayerByLocation("polyLyr", "HAVE_THEIR_CENTER_IN", "CitLyr", "", "NEW_SELECTION")
pr_oid_to_city_name = dict()
# Add code here to use a search cursor to scan the polyLyr and
# populate the dict that maps the pr OID to the city name
with arcpy.da.SearchCursor("CitLyr", ['OID@', 'CITY']) as search_cursor:
for oid, city_name in search_cursor:
pr_oid_to_city_name[oid] = city_name
print(pr_oid_to_city_name[oid])
# Start an edit session. Must provide the workspace.
edit = arcpy.da.Editor(workspace)
# Edit session is started without an undo/redo stack for versioned data
# (for the second argument, use False for unversioned data)
edit.startEditing(True)
# Start an edit operation
edit.startOperation()
fields = ['OID@', 'Owner']
with arcpy.da.UpdateCursor(PR, fields) as cursor:
for row in cursor:
oid = row[0]
if oid in pr_oid_to_city_name:
row[1] = pr_oid_to_city_name[oid]
cursor.updateRow(row)
edit.stopOperation()
# Stop the edit session and save the changes
edit.stopEditing(True)
I was able to accomplish what I needed with the following.
PR = "PrivateRoads"
CityLimits = 'City_Limits'
arcpy.MakeFeatureLayer_management(PR, "polyLyr")
arcpy.MakeFeatureLayer_management(CityLimits, "CitLyr")
unique_strings = []
with arcpy.da.SearchCursor("CitLyr", 'CITY') as cursor:
for row in cursor:
unique_strings.append(row[0])
#print (unique_strings)
for unique in unique_strings:
arcpy.SelectLayerByAttribute_management("CitLyr", 'NEW_SELECTION', "CITY = '{}'".format(unique))
arcpy.SelectLayerByLocation_management("polyLyr", 'HAVE_THEIR_CENTER_IN', "CitLyr", "", "NEW_SELECTION")
with arcpy.da.UpdateCursor(PR, 'Owner') as cursor:
for row in cursor:
row[0] = unique
cursor.updateRow(row)