Re: Select Layer by Location works in ArcGIS Pro Python window but not standalone

558
11
Jump to solution
11-03-2021 12:35 PM
curtvprice
MVP Esteemed Contributor

I'm assuming there is a feature class Test_Points in the gdb. This is a feature class, not a layer.

If you want to do selections on it, you need to create a new layer in memory from it using the Make Feature Layer tool. 

When running the script in Pro I am assuming there is a layer in the currently active map named Test_Points and also a feature class in your gdb; the layer takes precedence which is why it works in a pro window.

By the way I also recommend using the arcpy.da cursors instead, they are dramatically more efficient than the (older) arcpy cursors.

NOTE: original post is below in the thread

0 Kudos
1 Solution

Accepted Solutions
JonathonRobert
New Contributor II

I believe I have found the problem.   It actually does not seem that it is necessary to convert the feature class to a feature layer.  However, what @JoeBorgione mentioned about needing to do what ArcGIS does was in fact the problem.  

It appears that, when running the script inside ArcGIS, ArcGIS was using the on-the-fly projection of one of the classes.  I neglected to check that the spatial references were all the same before running the standalone script, which does not use on-the-fly projection.

tldr; I had to project all classes to the same spatial reference before selecting by location

View solution in original post

0 Kudos
11 Replies
JoeBorgione
MVP Esteemed Contributor

@curtvprice Curtis- where is the rest of this post?

That should just about do it....
0 Kudos
JonathonRobert
New Contributor II

I have run into a weird problem where a bit of code I have will run correctly in the ArcGIS Pro Python window, but not as standalone code. 

arcpy.env.workspace = r'C:\Users\jsint\UTAProject\Get_UTA_Buffers\Get_UTA_Buffers.gdb'
arcpy.env.overwriteOutput = True 

all_points = arcpy.management.SelectLayerByAttribute('Test_Points', 'NEW_SELECTION')

cursor1 = arcpy.SearchCursor(all_points)
for row1 in cursor1:
    print("Point ",row1.getValue("OBJECTID"))
    intersecting_nodes = arcpy.management.SelectLayerByLocation('Test_Breakpoints','INTERSECT',row1.getValue('Shape'),'','NEW_SELECTION')
    a,b,c = intersecting_nodes

    # c should not = 0 if intersection works correctly
    print(a,b,c,sep = ', ')

    cursor2 = arcpy.UpdateCursor(intersecting_nodes)
    for row2 in cursor2:
        print("Iterating selected nodes")
        row2.setValue('Is_Bus_Stop',1)
        row2.setValue('Dist_to_Bus',0)
        cursor2.updateRow(row)

    print()

 

I have followed the ArcGIS instructions on running standalone scripts given here: https://pro.arcgis.com/en/pro-app/latest/arcpy/get-started/using-conda-with-arcgis-pro.htm.  Despite this, the output does not give what I would expect.  I believe I have narrowed down the issue to something related to the Select Layer by Location function: as you can see, each iteration returns 0 selected items, giving cursor2 nothing to read.

C:\Users\jsint\UTA Project\Get_UTA_Buffers>c:\Progra~1\ArcGIS\Pro\bin\Python\scripts\propy.bat Make_Buffers_v2.py
Point  1
Test_Breakpoints_Layer2, Test_Breakpoints_Layer2, 0

Point  2
Test_Breakpoints_Layer5, Test_Breakpoints_Layer5, 0

Point  3
Test_Breakpoints_Layer8, Test_Breakpoints_Layer8, 0

Point  4
Test_Breakpoints_Layer11, Test_Breakpoints_Layer11, 0

 Is there a reason why this would work in the ArcGIS Python window, but not standalone?  Thank you!

0 Kudos
JonathonRobert
New Contributor II

@curtvpriceThank you for the suggestions.  I've tried using the Make Feature Layer tool like you mentioned, but I am still having the same issue

arcpy.env.workspace = r'C:\Users\jsint\UTA Project\Get_UTA_Buffers\Get_UTA_Buffers.gdb'
arcpy.env.overwriteOutput = True

point_lyr = arcpy.management.MakeFeatureLayer('Test_Points','Test_Points_lyr') 
breakpoint_lyr = arcpy.management.MakeFeatureLayer('Test_Breakpoints','Test_Breakpoints_lyr') 

# all_points = arcpy.management.SelectLayerByAttribute('Test_Points_lyr', 'NEW_SELECTION')
all_points = arcpy.management.SelectLayerByAttribute(point_lyr, 'NEW_SELECTION')

cursor1 = arcpy.da.SearchCursor(all_points)
for row1 in cursor1:
    print("Point ",row1.getValue("OBJECTID"))
    
    intersecting_nodes = arcpy.management.SelectLayerByLocation(breakpoint_lyr,'INTERSECT',row1.getValue("Shape"),'','NEW_SELECTION')
    a,b,c = intersecting_nodes
    print(a,b,c,sep = ', ')

    cursor2 = arcpy.da.UpdateCursor(intersecting_nodes)
    for row2 in cursor2:
        print("Iterating selected nodes")
        row2.setValue('Is_Bus_Stop',1)
        row2.setValue('Dist_to_Bus',0)
        cursor2.updateRow(row)

I have tried using both a variable for the new layer and the string name (e.g. 'Test_Points_lyr') but the output is the exact same.  Is there an issue with how I am calling the MakeFeatureLayer method?

0 Kudos
JoeBorgione
MVP Esteemed Contributor

I think @curtvprice addressed that above;  when you are working in a stand alone script, you need to use the make feature layer method in arcpy.  ArcGIS Pro presents the data in that form for you so you are able to interact with it, hence, when you refer to the data in you TOC it's a feature layer.  But when you run a stand alone script, you need to do what ArcGIS Pro does.

import arcpy
arcpy.env.workspace = r'C:/path/to/data.gdb'
fc = 'MyFeatureClass'
arcpy.MakeFeatureLayer_management(fc, "MyLayer")
select = 'OBJECTID = 1'
arcpy.management.SelectLayerByAttribute('MyLayer', 'NEW_SELECTION', select)
That should just about do it....
curtvprice
MVP Esteemed Contributor

I also think that the setup is incorrect for arcpy.da cursors -- the syntax setup is different, usually using a "with" statement. See the help.

0 Kudos
JoeBorgione
MVP Esteemed Contributor

I wish the old search/update/insert cursors would just go away so you get a syntax error instead of some jacked up result.

That should just about do it....
0 Kudos
JonathonRobert
New Contributor II

I believe I have found the problem.   It actually does not seem that it is necessary to convert the feature class to a feature layer.  However, what @JoeBorgione mentioned about needing to do what ArcGIS does was in fact the problem.  

It appears that, when running the script inside ArcGIS, ArcGIS was using the on-the-fly projection of one of the classes.  I neglected to check that the spatial references were all the same before running the standalone script, which does not use on-the-fly projection.

tldr; I had to project all classes to the same spatial reference before selecting by location

0 Kudos
JoeBorgione
MVP Esteemed Contributor

@JonathonRobert - I'm confused here: are you saying you did or did not use MakeFeatureLayer() in your stand alone script?

That should just about do it....
0 Kudos
JonathonRobert
New Contributor II

After making sure everything was projected to the same spatial reference, I did run it with the MakeFeatureLayer() method in the standalone script, and it worked.  I then ran it again without calling the MakeFeatureLayer() method, and got the same (working) output.  So it appears to me that the issue was non-matching spatial references