2

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

5

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
4

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 
3
  • 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. Commented 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/… Commented 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
    Commented Jun 8, 2015 at 15:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.