2

I am trying to add a feature layer to my map document as the output from my python script. The goal is to limit the number of fields in the attribute table to a pre-defined list. I am able to add the feature layer to my map document, but all of the fields display. However, when I use arcpy.Describe() on the layer my script added to the map, the Describe results show the desired field subset. I can't figure out what is going on.

def makeFeatureLayer(outputFC, fieldTable, input_FC, input_ID, mapLayers):
    outputFeatureLayer = "{0}".format(os.path.basename(outputFC))
    subField = "{0}".format(arcpy.Describe(outputFC).subtypeFieldName)
    displayFieldList = [input_ID, subField]
    with arcpy.da.SearchCursor(fieldTable, ["layer_name", "Attribute"]) as cursor:
        for row in cursor:
            if "{0}".format(row[0]) == "{0}".format(os.path.basename(input_FC)):
                displayFieldList.append("{0}".format(row[1]))

    outputFieldList = arcpy.ListFields(outputFC)
    fieldInfo = "{0}".format(input_ID) + " " + "{0}".format(input_ID) + " " +  "VISIBLE" + " " + "NONE;" + "{0}".format(subField) + " " + "{0}".format(subField) + " " +  "VISIBLE" + " " + "NONE;" 
    for f in outputFieldList:
        if f.name in displayFieldList:
            fieldInfo = fieldInfo + f.name + " " + f.name + " " + "VISIBLE" + " " + "NONE;"
        else:
            fieldInfo = fieldInfo + f.name + " " + f.name + " " + "HIDDEN" + " " + "NONE;"

    arcpy.management.MakeFeatureLayer(outputFC, outputFeatureLayer, "", "", fieldInfo)

    mapLayers.append(outputFeatureLayer)

    del subField, displayFieldList, outputFieldList, fieldInfo

def updateMap(mapLayers):
    mxd = arcpy.mapping.MapDocument("CURRENT")
    dataFrame = arcpy.mapping.ListDataFrames(mxd)[0]
    for layer in mapLayers:
        arcpy.mapping.AddLayer(dataFrame, arcpy.mapping.Layer(layer), "TOP")
        arcpy.RefreshActiveView()
        arcpy.RefreshTOC()
    del mxd, dataFrame

I tried leaving out arcpy.mapping.Layer in case this was undoing the fieldInfo settings/field selection, and just trying to add the feature layer to the map document directly, but that generates an assertion error. Also, if I run the code it actually results in two new layers to my map document: a visible layer that shows all the fields, and the original output of the MakeFeatureLayer tool, but it is not visible and cannot be added to the map display unless I export it to a .lyr file first.

Any ideas?

I was able to get MakeFeatureLayer to work from the Python window just fine. I tried to use ListLayers() and use that to get at the feature layer after creating it, but that didn't work either.


I can sort of work around this by saving the results of MakeFeatureLayer to a .lyr file, but this is not ideal as I do not want to write anything extra to disk just for the field display. When I add the .lyr file to the map document, though, it works the way I intend and only shows the subset of fields.

2

Working with layers can indeed be tricky, with the multiple steps of adding one to your map. Also confusion can arise with the in memory layer created by arcpy.MakeFeatureLayer_management and the mapping layer you add to your map via arcpy.mapping.AddLayer usually having the same name. These two 'layers' are similar objects but are not, in fact, the same, and having both the in memory layer and the mapping layer to deal with at the same time can cause frustration.

I've created a simplified code based off what you provided. It won't produce quite the same results as yours, as you add multiple layers from a list. Mine just adds one. But I hope that showing the steps to add a single layer and turn off undesired fields can still help.

In my script, I generate the list of fields to keep visible with roughly the same code you provide. I then create an in memory layer file, and add "_templyr" to the end of its name to distinguish it from the mapping layer that will later be added to the map. I then create the mapping layer object, and rename it to remove the "templyr" designation. After I add this mapping layer to the map, I delete the in memory layer. I then work with a fieldInfo object to set fields not in my displayFieldList to hidden.

I can't test the code, so there may need to be a little cleanup from a messup on my part.

subField = arcpy.Describe(outputFC).subtypeFieldName
displayFieldList = [input_ID, subField]
with arcpy.da.SearchCursor(fieldTable, ["layer_name", "Attribute"]) as cursor:
    for row in cursor:
        if row[0] == os.path.basename(input_FC):
            #List of fields to show
            displayFieldList.append(row[1]) 

outputFeatureLayer = os.path.basename(outputFC) + "_templyr"
#Create in memory layer with 'templyr' as designation
arcpy.MakeFeatureLayer_management (outputFC, outputFeatureLayer) 

mxd = arcpy.mapping.MapDocument("CURRENT")
dataFrame = arcpy.mapping.ListDataFrames(mxd)[0]

#Create mapping layer
lyr = arcpy.mapping.Layer(outputFeatureLayer)

#Remove "_templyr" from mapping layer name
lyr.name = outputFeatureLayer.replace ("_templyr", "")

#Add mapping layer to map
arcpy.mapping.AddLayer(dataFrame, lyr, "TOP")

#delete layer in memory to prevent confusion
arcpy.Delete_management (outputFeatureLayer)

#Get field info object
fieldInfo = arcpy.Describe (lyr).fieldInfo 

#Check if field is in list, if not set to hidden
index = 0
while index < fieldInfo.count:
    fldName = fieldInfo.getFieldName(index)
    if not fldName in displayFieldList:
        fldInfo.setVisible (index, "HIDDEN")
    index += 1

arcpy.RefreshActiveView()
arcpy.RefreshTOC()
del mxd, dataFrame

I hope this helps a little!

  • Thanks for your reply! This approach works great unless I keep using a list to add layers. Then I get the following error: "Object: CreateObject Layer invalid data source" at the point when the ArcMap attempts to add the layer to the data frame from the list. I can revise my code to avoid adding a layer from a list, but do you know why using a list to add layers would create this error? I tried removing the arcpy.mapping.AddLayer from the list iteration, but then I get an assertion error. I think I'm getting confused about the layer objects, but I can't seem to think through it. – Squinney Jan 7 '15 at 16:41
  • What line of code produces the "Object: CreateObject Layer invalid data source"? – Emil Brundage Jan 7 '15 at 20:13
  • This line generates the error: arcpy.mapping.AddLayer(dataFrame, arcpy.mapping.Layer(layer), "TOP") – Squinney Jan 7 '15 at 20:30
  • The problem is with your variable layer. arcpy.mapping.Layer takes as its input a feature class or a layer file (either an actual .lyr file or a temporary layer file created by MakeFeatureLayer_management). Try a print layer before to see what you are inputting. – Emil Brundage Jan 7 '15 at 20:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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