Can someone let me know how I can use a single feature from one layer as the "Select Features" when using the Make Feature Layer by Location tool with another layer as the input?
In the code below I have no idea what to put in place of BLAH to get this to run. Suggestions?
import arcpy
Practice_Sales1 = "Practice_Sales1"
Practice_Stops = "Practice_Stops"
import arcpy
fc = "y:/Practice_Sales1.shp"
field = "BOROUGH"
cursor = arcpy.SearchCursor(fc)
# Iterate through the rows in the cursor
for row in cursor:
#Create Layer from the current row in the Practice_Sales1 file
arcpy.MakeFeatureLayer_management("Practice_Sales.shp", "Sales_lyr", BLAH)
# Select all features in Practice_Stops within 1000 feet of the current row in Practice_Sales1
arcpy.SelectLayerByLocation_management(Practice_Stops, "WITHIN_A_DISTANCE", "Sales_lyr", "1000 Feet", "NEW_SELECTION", "NOT_INVERT")
# Returns the # of selected features
arcpy.GetCount_management(Practice_Stops)
# Replace row value in COUNT field with
row.setValue("COUNT", arcpy.GetCount_management(Practice_Stops))
2 Answers 2
Here i used generation of a list of paired tuple of OID and Result of select by location operation.Then i created an update cursor to to update a filed named COUNT by the select by layer location result. You need to just create a field in Practice_Stops feature class named COUNT which is a type of short integer.Here inF is the layer will be updated with count of locational search and selectF is the feature class that will be counted.
import arcpy
arcpy.env.workspace = r'C:\Users\USER_NAME\Desktop\gissta\workspace'
inF = r'C:\Users\USER_NAME\Desktop\gissta\workspace\grid.shp' #Practice_Stops
selectF = r'C:\Users\USER_NAME\Desktop\gissta\workspace\schools_p.shp' # "Practice_Sales.shp"
pair = []
pairID = []
pairCNT = []
def getCount(fc,countFc):
arcpy.MakeFeatureLayer_management(fc,"sel_loc")
arcpy.MakeFeatureLayer_management(countFc,"countF")
curS = arcpy.da.SearchCursor("sel_loc",("OID@","SHAPE@"))
for row in curS:
S = row[1]
arcpy.SelectLayerByLocation_management("countF","WITHIN_A_DISTANCE",S,"1000 Meters","NEW_SELECTION")
cnt = str(arcpy.GetCount_management("countF"))
pairID.append(row[0])
pairCNT.append(cnt)
print zip(pairID,pairCNT)
pair.append(zip(pairID,pairCNT))
del curS
return pair
getCount(inF, selectF)
curU = arcpy.da.UpdateCursor(inF,("OID@","COUNT"))
for row in curU:
for i in pair:
for x,y in i:
print type(x)
print type(row[0])
print type(row[1])
if (row[0] == x):
row[1]= y
curU.updateRow(row)
del curU
The way I always handle this kind of thing is by making the entire FC a layer before entering the "for" loop. Then once inside the loop I use SelectLayerByAttribute on the the row based on OBJECTID or some other unique identifier. The following code should do what you need with a few changes. You will need to make sure the paths are all correct for your file system.
Edit: I have made a few changes that should hopefully make this easier to implement. You need to make sure you are working out of a GDB with true feature classes instead of using shape files. The where clause is structured for a gdb and won't work correctly on .shp files. You could do a little research on how to construct where clauses for shape files. Specifically the, AddFieldDelimeters tool would be helpful for this. I made one mistake in the original code in which I referenced a layer called 'Units'. This has been removed since obviously your project does not involve a layer with this name. That's what I get for copying and pasting code from my own projects :)
import arcpy
import os
arcpy.MakeFeatureLayer_management(r'Replace this sentence with the path to the Practice_Stops FC', 'Practice_Stops_lyr')
#You're original dataset
fc = r'Replace this senetence with the path to the Practice_Sales FC' #you should import this into an FGDB to make it a true FC instead of using a .shp
#Create a scratch data workspace
try:
arcpy.CreateFileGDB_management(r'Replace this sentence with a path to a location where you can store scratch data.', "ScratchFGD")
except:
pass
#Create an object that stores the location for the scratch data
scratchFGD = r'Replace this sentence with the full path to the scratch geodatabase created in the previous step, make sure to include .gdb at the end'
#Make a layer out of the the original FC
arcpy.MakeFeatureLayer_management(fc, 'Sales_lyr')
#Use an update cursor when there is a value you need to change in the attribute table
with arcpy.da.UpdateCursor('Sales_lyr', ["BOROUGH", "OBJECTID", "COUNT"]) as cursor:
#For every row in the cursor, do the following
for row in cursor:
#Select the current row in the UpdateCursor
arcpy.SelectLayerByAttribute_management('Sales_lyr', "NEW_SELECTION", "OBJECTID IN(" + str(row[1]) + ")")
arcpy.AddMessage("Selection by attributes complete")
print ("Selection by attributes complete")
#Copy the selection to a new temporary feature
arcpy.CopyFeatures_management('Sales_lyr', os.path.join(scratchFGD, "tempFeat"))
arcpy.AddMessage("Copy complete")
print ("Copy complete")
#Make the temp feature a layer
arcpy.MakeFeatureLayer_management(os.path.join(scratchFGD, "tempFeat"), "singleSalesRecord_lyr")
arcpy.AddMessage("Feature layer created")
print ("Feature layer created")
# Select all features in Practice_Stops within 1000 feet of the current row in Practice_Sales1
arcpy.SelectLayerByLocation_management('Practice_Stops_lyr', "WITHIN_A_DISTANCE", "singleSalesRecord_lyr", "1000 Feet", "NEW_SELECTION")
arcpy.AddMessage("Select by Location complete")
print ("Select by Location complete")
# Returns the # of selected features
practiceStopsCount = int(arcpy.GetCount_management('Practice_Stops_lyr').getOutput(0))
arcpy.AddMessage("# of features within 1000 feet = " + str(practiceStopsCount))
print ("# of features within 1000 feet = " + str(practiceStopsCount))
# Replace row value in COUNT field with
row[2] = practiceStopsCount
cursor.updateRow(row)
arcpy.AddMessage("Row Updated in Sales FC")
print ("Row Updated in Sales FC"")
#Clean up the temporary data
arcpy.Delete_management(os.path.join(scratchFGD, "tempFeat"))
arcpy.Delete_management('singleSalesRecord_lyr')
arcpy.AddMessage("Deleted temp data")
print ("Deleted temp data")
del row
del cursor
-
Thanks for the help with this. I still have one issue with line 25: "FID IN(" + str(row[1]) + ")". That appears to raise the error " File "<string>", line 25, in <module> does not exist". I am having a tough time rectifying this, so if you see something immediately that would lead to this error I would appreciate your input.Matthew Friedman– Matthew Friedman2015年06月06日 16:44:49 +00:00Commented Jun 6, 2015 at 16:44
-
I continue to get this error: Runtime error Traceback (most recent call last): File "<string>", line 9, in <module> File "c:\program files (x86)\arcgis\desktop10.3\arcpy\arcpy\management.py", line 7211, in SelectLayerByAttribute raise e ExecuteError: ERROR 000358: Invalid expression Failed to execute (SelectLayerByAttribute). The issue seems to be related to the fact that this tool is being used in a loop: gis.stackexchange.com/questions/83442/…Matthew Friedman– Matthew Friedman2015年06月06日 20:13:49 +00:00Commented Jun 6, 2015 at 20:13
-
@Matthew Friedman - I have made a couple corrections/changes that should allow for easier implementation. Check my Edit and copy the new code. I have tested it and it seems to work fine. I think the key here is making sure you are using a geodatabase. You could do this with shape files but I just feel that it is good practice to go ahead and convert your data to an FC.GeoJohn– GeoJohn2015年06月08日 15:15:17 +00:00Commented Jun 8, 2015 at 15:15
Explore related questions
See similar questions with these tags.