0

I am providing an alternative to the accepted answer posted here. I pose as new question as the script I use is resulting in error and I've been unable to resolve.

Esri help documentation states that the UpdateLayer function, when altering all of a feature classes symbology properties, may be used as an alternative to the RemoveLayer and AddLayer functions. The script below is intended to meet the same end as the question posted above, but it uses this UpdateLayer function, which seems like it would be a more elegant solution than using the RemoveLayer and AddLayer functions.

When I run this script:

import os
from os import listdir
from os.path import isfile, join
import arcpy

# Creates list of MXDs
mxdList = [f for f in listdir(r'C:\MXDs')
             if isfile(join(r'C:\MXDs', f))]

for doc in mxdList:
    mxd = arcpy.mapping.MapDocument(os.path.join(r'C:\MXDs', doc))

    # FCs for which there are .lyr files
    fcList = ['FC1', 'FC2', '...']

    # Iterate through dataframes
    for df in arcpy.mapping.ListDataFrames(mxd)[0]:         
        print df
        workSpaceType = "FILEGDB_WORKSPACE"

        for item in fcList:
            for lyr in arcpy.mapping.ListLayers(mxd, item):
                desc = arcpy.Describe(lyr)
                geometryType = desc.shapeType

                # Use geometry to match lyr file name
                if geometryType == 'Point':
                    # Access and define the lyr file
                    newLyr = arcpy.mapping.Layer(os.path.join(r'C:\lyrFiles', item + '_P.lyr'))
                    print 'Layer Object:   ' + str(newLyr)
                    arcpy.mapping.UpdateLayer(df, lyr, newLyr, False)
                    print 'Updated:  ' + str(newLyr)
                    del newLyr

                elif geometryType == 'Polyline':                
                    # Access and define the lyr file
                    newLyr = arcpy.mapping.Layer(os.path.join(r'C:\lyrFiles', item + '_L.lyr'))
                    print 'Layer Object:   ' + str(newLyr)
                    arcpy.mapping.UpdateLayer(df, lyr, newLyr, False)
                    print 'Updated:  ' + str(newLyr)
                    del newLyr

                elif geometryType == 'Polygon':
                    # Access and define the lyr file
                    newLyr = arcpy.mapping.Layer(os.path.join(r'C:\lyrFiles', item + '_A.lyr'))
                    print 'Layer Object:   ' + str(newLyr)
                    arcpy.mapping.UpdateLayer(df, lyr, newLyr, False) 
                    print 'Updated:  ' + str(newLyr)
                    del newLyr


    mxd.saveACopy(r'C:\MXDsUpdated' + doc)
    del mxd

it results in error:

assert isinstance(data_frame, DataFrame)
    AssertionError

for line 58, for the UpdateLayer function for the Polygon geometry, the geometry of the first item in the fcList list for the first MXD that is accessed.

I have ensured I have defined the Layer as described here. Also, inserting the print df statement within the ListDataFrames for loop prints feature class names and not dataframe names. Any ideas?

reevesii
  • 1,519
  • 1
  • 12
  • 29

2 Answers2

0

This line will produce a double backslash:

mxd = arcpy.mapping.MapDocument(r'C:\MXDs\\' + doc)

From the Python shell:

>>> print r'C:\MXDs\\'
C:\MXDs\\

Instead, use:

mxd = arcpy.mapping.MapDocument(os.path.join (r'C:\MXDs' + doc))

This is wrong too:

newLyr = arcpy.mapping.Layer(r'C:\lyrFiles/' + item + '_P.lyr')

From the Python shell:

>>> item = "FC1"
>>> print r'C:\lyrFiles\/' + item + '_P.lyr'
C:\lyrFiles\/FC1_P.lyr

Try:

newLyr = arcpy.mapping.Layer(os.path.join (r'C:\lyrFiles', item + '_P.lyr'))

All your paths need to be rewritten.

Emil Brundage
  • 13,859
  • 3
  • 26
  • 62
0

Some of my paths were defined incorrectly as Emil Brundage pointed out. I believe the assertion error, however, was due to my use of mxd as opposed to df in line 22 (for lyr in arcpy.mapping.ListLayers(mxd, item):) Upon correcting this line the assertion error no longer appeared.

Thus, this section of the working script now appears like this:

for df in arcpy.mapping.ListDataFrames(mxd)[0]: 
    workSpaceType = "FILEGDB_WORKSPACE"    
    for item in fcList:
        for lyr in arcpy.mapping.ListLayers(df, item):
reevesii
  • 1,519
  • 1
  • 12
  • 29