I am trying to write a loop in arcpy that will first make a selection by attribute in one feature class and then make a selection by location on another. Then I want to copy the selected features into a gdb and move to the next row in the table.
This works just fine when I use a numeric uniqueID, but I want to have the output filename retrieve a value from the attribute table (A string with the feature's name) instead of giving me "Pand + string_x" which is just a number.
This is the script:
x=1
while x < 389:
string_x = str(x)
x_input = "UniqueID = " + string_x
x_output = r"C:\temp\BaseMap\working_data\BAG.gdb\Pand_" + string_x
arcpy.SelectLayerByAttribute_management("gemeente2017","NEW_SELECTION", x_input)
arcpy.SelectLayerByLocation_management("Pand","HAVE_THEIR_CENTER_IN","gemeente2017","","NEW_SELECTION","NOT_INVERT")
arcpy.CopyFeatures_management("Pand",x_output, "")
x += 1
I'm guessing the solution will have something to do with Field delimiters, but I'm quite new at this and have no idea how to incorporate that into my code. Using ArcGIS 10.5 and Python 2.7.12.
3 Answers 3
You need to create a loop using the Arcpy.da.SearchCursor on your featureclass. This will accomplish this without using a for/while loop on numbers.
- Create Feature Layers so you can apply selections
- Create a Search Cursor on your main feature layer
- Apply an expression to select your row
- Use SelectbyLocation to identify the intersected features
- Export this to a new featureclass
Try the following:
fc = r"path/to/fc"
fc_fl = arcpy.MakeFeatureLayer_management(fc, "fc_fl")
intersect_dataset = r"path/to/fc"
int_fl = arcpy.MakeFeatureLayer_management(intersect_dataset, "int_fl")
OID = arcpy.Describe(fc_fl).OIDFieldName
#update the "field_with_feature_name" to a field that has the output name
with arcpy.da.SearchCursor(fc_fl, OID + ["field_with_feature_name"]) as cursor:
for row in cursor:
#create an expression to identify the objectid in the density grid
expression = '"{}" = {}'.format(OID, row[0])
#create a selection on that row
arcpy.SelectLayerByAttribute_management(fc_fl, "NEW_SELECTION", expression)
#identify the intersect features
arcpy.SelectLayerByLocation_management(int_fl, "INTERSECT", fc_fl)
#export to new fc
arcpy.CopyFeatures_management(int_fl, "Pand_{}".format(row[1]))
#remove selections
arcpy.SelectLayerByAttribute_management(fc_fl, "CLEAR_SELECTION")
arcpy.SelectLayerByAttribute_management(int_fl, "CLEAR_SELECTION")
-
Thanks for the comment! But when I try your code I get the following error message: "Runtime error Traceback (most recent call last): File "<string>", line 2, in <module> RuntimeError: A column was specified that does not exist." I think I'm not creating the search cursor properly.Posad– Posad2017年09月26日 08:39:24 +00:00Commented Sep 26, 2017 at 8:39
-
it may be that the OID field isnt the correct one. ill update the code to include a way to identify this field.MacroZED– MacroZED2017年09月26日 08:42:05 +00:00Commented Sep 26, 2017 at 8:42
-
Now I get this error - "NameError: name 'OID' is not defined". I also tried to replace the OID with the UniqueID column which I created in the attribute table and got the same error. And what exactly do you mean by: ["field_with_feature_name"]?Thanks againPosad– Posad2017年09月26日 09:11:28 +00:00Commented Sep 26, 2017 at 9:11
-
You dont need to use a unique ID field in the attribute table. Your dataset should already have an ObjectID field. This is the unique ID. In your original question, you say you want the new featureclass to have a name in it - i assume this is present in a field - therefore update the "field_with_feature_name" with this field name.MacroZED– MacroZED2017年09月26日 09:15:03 +00:00Commented Sep 26, 2017 at 9:15
-
Yes, that's what I thought (regarding the field with feature name). Still have the issue with OID not defined though.Posad– Posad2017年09月26日 09:28:15 +00:00Commented Sep 26, 2017 at 9:28
By Creating a instance of your selection in a new variable with the result of arcpy.selectionByLocation_management([your request]) , it could be more efficient Afet look for the right field.name value with SearchCursor
[...]
FC=arcpy.SelectLayerByLocation_management("Pand","HAVE_THEIR_CENTER_IN","gemeente2017","","NEW_SELECTION","NOT_INVERT")
field_name = 'yourFiedName'
SC = arcpy.da.SearchCursor(FC, field_name)
for row in SC:
for cell in row: #Iterate through row, which is a Python list
print cell #Print value of item in row list
fieldNameValue = cell
del SC
x_output = r"C:\temp\BaseMap\working_data\BAG.gdb\Pand_" + fieldNameValue
[...]
-
I get the following error msg: " Runtime error Traceback (most recent call last): File "<string>", line 10, in <module> File "c:\program files(x86)\arcgis\desktop10.5\arcpy\arcpy\arcobjects\arcobjects.py", line 1108, in getValue return convertArcObjectToPythonObject(self._arc_object.GetValue(*gp_fixargs(args))) RuntimeError: ERROR 999999: Error executing function.Posad– Posad2017年09月26日 08:43:00 +00:00Commented Sep 26, 2017 at 8:43
-
what is the line 10 of your script ?Hugo Roussaffa– Hugo Roussaffa2017年09月26日 10:54:15 +00:00Commented Sep 26, 2017 at 10:54
-
I made some corrections to the code. Please try to used it inside your code and tell me. I can't test it now.Hugo Roussaffa– Hugo Roussaffa2017年09月26日 11:11:37 +00:00Commented Sep 26, 2017 at 11:11
-
I tested it and tweaked it a bit so it fits and posted it as a separate answer here below. Thanks for the help!Posad– Posad2017年10月11日 15:39:44 +00:00Commented Oct 11, 2017 at 15:39
Thanks Hugo it worked! This is how the code looks like now:
x =1
while x < 389:
string_x = str(x)
x_input = "UniqueID = "+ string_x
fc = arcpy.SelectLayerByAttribute_management("gemeente2017", "NEW_SELECTION", x_input)
field_name = "Gemeentena"
sc = arcpy.da.SearchCursor(fc, field_name)
for row in sc:
for cell in row:
print cell
fieldNameValue = cell
del sc
arcpy.SelectLayerByLocation_management("Pand", "HAVE_THEIR_CENTER_IN","gemeente2017, "", "NEW_SELECTION", "NOT_INVERT")
x_output = r"c:\temp\Basemap\working_data\BAG.gdb\Pand_"+ fieldNameValue
arcpy.CopyFeatures_management("Pand", x_output, "")
x += 1
{}
button), so it's formatted in the preview as code. Please also specify the exact ArcGIS product in use, the version of Python, and try using string formatting instead of string math. It doesn't seem as if you are doing anything with your selection, so it's more than a little confusing.