I am staring at 5600 individual points and 60 polygons. I need to create a new field in the point fc called 'Basin Name' and populate the field with the name of the Basin that it lies in. I am trying to develop a reusable script that can be used weekly to accomplish newly inputed points. I have two features, SSO which are points and Basins which are polygons. I have tried to follow this thread (Assigning field value based on location without join) but I keep receiving an error on the SelectLayerByAttributes.
The error I receive is "Runtime error Traceback (most recent call last): File "", line 19, in File "j:\apps\arcgis\desktop10.3\arcpy\arcpy\management.py", line 7221, in SelectLayerByAttribute raise e ExecuteError: ERROR 000358: Invalid expression Failed to execute (SelectLayerByAttribute)."
import arcpy
arcpy.env.workspace = "Y:/SSO_BASINS/"
# Set overwrite option
arcpy.env.overwriteOutput = True
# KEEPING ORIGINAL LAYERS (NOT CREATING ADDITIONAL "JOINED" LAYER)
# Create FeatureLayers
arcpy.MakeFeatureLayer_management("Y:/SSO_BASINS/Basins.shp", "lyr_Basins")
arcpy.MakeFeatureLayer_management("Y:/SSO_BASINS/SSO.shp", "lyr_SSO")
# Add a "BASIN" field
arcpy.AddField_management("lyr_SSO", "BASIN", "TEXT")
# Create a search cursor for the states
rows = arcpy.SearchCursor("lyr_Basins")
for row in rows:
arcpy.SelectLayerByAttribute_management("lyr_Basins", "NEW_SELECTION",
"\"OBJECTID\" " + str(row.getValue("OBJECTID")))
arcpy.SelectLayerByLocation_management("lyr_SSO", "INTERSECT", "lyr_Basins",
"", "NEW_SELECTION")
arcpy.CalculateField_management("lyr_SSO", "BASIN",
"'{0}'".format(str(row.getValue("BASIN"))), "PYTHON_9.3", "")
2 Answers 2
Since you're using ArcMap 10.3 you should use the arcpy.da.SearchCursor
instead of the deprecated arcpy.SearchCursor
. Also, your arcpy.SelectLayerByLocation_management
syntax is backward. You are selecting within your lyr_SSO
layer when you want to be selecting within the lyr_Basins
feature. The SelectLayerByAttribute_management
step is unnecessary since you are already looping through the rows. You can use the SHAPE@
field as your selection location.
import arcpy
# Set overwrite option
arcpy.env.overwriteOutput = True
# KEEPING ORIGINAL LAYERS (NOT CREATING ADDITIONAL "JOINED" LAYER)
# Create FeatureLayers
lyr_basin = arcpy.MakeFeatureLayer_management("Y:/SSO_BASINS/Basins.shp", "lyr_Basins")
lyr_sso = arcpy.MakeFeatureLayer_management("Y:/SSO_BASINS/SSO.shp", "lyr_SSO")
# Add a "BASIN" field
arcpy.AddField_management(lyr_sso, "BASIN", "TEXT")
with arcpy.da.UpdateCursor(lyr_sso, ["BASIN", "SHAPE@"]) as ssoCursor:
for row in ssoCursor:
arcpy.SelectLayerByLocation_management(lyr_basin, "INTERSECT", row[1], "", "NEW_SELECTION")
with arcpy.da.SearchCursor(lyr_basin, ["BASIN"]) as basCursor:
for brow in basCursor:
row[0] = brow[0]
ssoCursor.updateRow(row)
The error indicates a bad SQL statement.
You want something like this:
"OBJECTID" = 7
Your code ("\"OBJECTID\" " + str(row.getValue("OBJECTID"))
) will yield this:
"OBJECTID" 7
Change your code to include the equal sign:
"\"OBJECTID\" = " + str(row.getValue("OBJECTID"))
I like .format
for a bit cleaner code:
'"OBJECTID" = {}'.format (row.getValue("OBJECTID"))
Also, your field calculate expression is going to produce an error because you use single quotes instead of double quotes.
Your code:
"'{0}'".format(str(row.getValue("BASIN")))
needs a quick fix:
'"{0}"'.format(str(row.getValue("BASIN")))
At the end of the day though, I'd skip the cursor and the iterating of rows and just use a Spatial Join.
-
I went with Jacob's answer and it worked. The spatial join is simple enough, but with it possibly being a reoccuring task, a script is ideal. Thanks, Emil!Wazzy24– Wazzy242017年11月30日 19:16:08 +00:00Commented Nov 30, 2017 at 19:16
-
You can script a spatial join, of course.Emil Brundage– Emil Brundage2017年11月30日 19:17:29 +00:00Commented Nov 30, 2017 at 19:17
Explore related questions
See similar questions with these tags.