Select to view content in your preferred language

Arcpy.mapping.AddLayer selection Funk (serious ESRI devs only)

5413
44
Jump to solution
02-05-2018 11:23 AM
JosephArmbruster
New Contributor III
Hey everyone,
It's been ages since i've had to resort to the forums, but the time has come...  This is issue is occurring with:
10.3.0.4322
AND
10.5.1.7333
Problem: When a layer is added to the TOC, just as you see in the snippet below, feature selections will no longer be respected (or at least detected) by geoprocessing tools.
Description: The symptom of the problem is that obtaining the feature selection count of a geoprocessing layer in a python toolbox is inconsistent.  I've pinned it down to some issue with the way Arc (or ArcPy) is handling layers by Name.  Here are some snippets:
# make this an absolute path to some feature class in a geodatabase, you only need a minimum of two features to reproduce the issue, i'm using polygons.

path = #path to your polygon feature class with at least two features in it.
mxd = arcpy.mapping.MapDocument('CURRENT')
new_layer_name = os.path.basename(path)
arcpy.MakeFeatureLayer_management(path, new_layer_name)
new_layer = arcpy.mapping.Layer(new_layer_name)
arcpy.mapping.AddLayer(mxd.activeDataFrame, new_layer_name, 'BOTTOM')
del new_layer
del mxd
Use the code above in a geoprocessing tool to add a layer to the map.

Now, use the code below in a separate geoprocessing tool, to report the number of features selected in the map.
desc = arcpy.Describe(input_feature_class)
if desc.FIDSet:
 messages.addMessage('selection made')
 # you'll never get here with the layer above!!
else:
 messages.addMessage('no selection made')
 # you'll always get here even with a selection 😞
# count will always be the entire feature class count, since no selection was registered
# to the layer....
feature_count = int(arcpy.GetCount_management(input_feature_class).getOutput(0)

Notes:
- If you use the code above to add the feature class to the map.  Remove it from the toc (right click, remove) and add it using arc catalog (drag-drop), the feature selection will STILL not work.  Hence why I suggest it has something to do with the internal name resolution.
- If you start a new ArcMap instance, add the layer by drag-dropping it from Arc Catalog, the selection WILL work.  If you remove this layer and add it using the code above, all subsequent selections will NOT be respected.

I look forward to hearing from ESRI support.
Let me know if you have any questions,
Joseph Armbruster
0Lat Inc, Orlando Florida.
0 Kudos
44 Replies
JamesCrandall
MVP Frequent Contributor

I missed where you described the selection process (assuming it was a manual process by the user performing a selection on the layer that was loaded).  Likely issue is that you'll have to reset the lyr reference after added to the TOC but I'll try to programmatically select some features after it's added to see if I can produce your issue.

0 Kudos
XanderBakker
Esri Esteemed Contributor

There is definitely something funky going on here. I said I was going to leave the thread for what it was, but since you attached the Python toolbox I decided to give it a shot (although I'm using 10.6).

I changed my setting to not add layers automatically. When I use the tool to add the layer (which works without problems) I notice in 10.6 that on doing the count, it will list 2 layers with the same name (although the TOC only has one):

When I make a selection in the layer, no matter which of the two I use in the second tool, it will always return no selection.

Since for some reason I have two layers with the name "myLines", I thought I would change my toolbox to have two parameters so I can select both layer in the same process to see if there is any difference:

... and see what resulted:

The first one does not have a FIDSet, feature count returns all 260 features

The second one does ave a FIDSet (a selection of 13 features) while the GetCount still returns all features (no selection). 

Strange things are happening. Good thing you reported this to Support.

JosephArmbruster
New Contributor III

I appreciate your persistence and patience 🙂  You know how it goes probably, deep in a million problems and just want to get something done.  My bad for posting a sample with a typo, that was a noob mistake.  Happy to know others can bask in my misfortune now!  Just imagine how strange it was to pin this down when it's working for some and not others because some analyst add layers directly from catalog (sometimes) while others use the tool (sometimes) and this will only fail consistently after the first time with the tool, that happens to use THIS code. . . .

Oh!  And, support did get back to me.  There is a bug and they want me to hack around it by allowing MakeFeatureLayer to add the layer, which is a total HACK and reasonably unacceptable in terms of having an API that claims to support an AddLayer function...

More to come!

0 Kudos
JosephArmbruster
New Contributor III

Also, turn that 'automatically add' geoprocessing outputs off for this... you shouldn't have to have that on.  It's more fun that way, trust me!

0 Kudos
JamesCrandall
MVP Frequent Contributor

Doesn't look like new_layer will be enough to perform the selection and needs to reset a reference to the desired layer in the dataframe to apply a SelectByAttribute_management on the feature class that is loaded programmatically.  Code below generates desired result on a single pass.

path = r'somepath\somfeaureclass'
mxd = arcpy.mapping.MapDocument('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd)[0]
new_layer_name = os.path.basename(path)
arcpy.MakeFeatureLayer_management(path, new_layer_name)
new_layer = arcpy.mapping.Layer(new_layer_name)
arcpy.mapping.AddLayer(mxd.activeDataFrame, new_layer, 'BOTTOM')
# reset the referenc to the "new_layer" by way of arcpy.mapping.ListLayers()
lyr = arcpy.mapping.ListLayers(mxd, "Adminbndy3_Clip", df)[0]
sql = 'OBJECTID=2'
arcpy.SelectLayerByAttribute_management(new_layer, "NEW_SELECTION", sql)
arcpy.RefreshActiveView()
del new_layer
JosephArmbruster
New Contributor III

The whole reference reset thing seems like a hack... but I can see how that code could be doing something relevant under the hood.  Yeah, my selection is non-programmatic, specifically by a user in the data view.  Then the next geoprocessing tool is suppose to 'pick up on' the selection.

I think one of the ESRI devs likely missed something when implementing the AddLayer function for a layer that was created via MakeFeatureLayer...  . .  mayyyybe someone from support is willing to chime in?

0 Kudos
JamesCrandall
MVP Frequent Contributor

Then wouldn't your initial reference to layer be out of scope if it's an entirely different gp tool processing what is selected?

0 Kudos
JosephArmbruster
New Contributor III

I have no clue how they implemented their C/C++/COM stuff, or how they wrapped it up in Python... So, who holds that reference is unknown to me.

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Run your first tool (For ESRI Add To Map), then goto the interactive Python window and type:

arcpy.Delete_management(‍  # type as is, so auto-complete of layers shows up)

I am guessing you will see you new layer twice, possibly both right next to each other at the top of the list.  Although your code is only adding one layer to the bottom of the TOC, it creates 2 feature layers with the exact same name.  I am guessing having two feature layer in memory with the same name is causing confusion for the Describe object.

Although your use of arcpy.mapping.Layer works, the method function is really designed to be used with layer files on disk:

Syntax

Layer (lyr_file_path)
ParameterExplanationData Type
lyr_file_path

A string that includes the full path and file name of an existing layer (.lyr) file.

String

This could also be contributing to the problem.

JosephArmbruster
New Contributor III

Nod.

Hence why I believe support suggested that I use the output from MakeFeatureLayer..

gar...

0 Kudos