-1

I have a folder that contain mxd's projects. Each mxd has 3 and more data frame. I want to insert layer file to a specific data frame with position in the TOC. I don't know how to do it. I'm trying this code:

import arcpy,os,sys
import arcpy.mapping
from arcpy import env



env.workspace = r"C:\Projects"   
for mxdname in arcpy.ListFiles("*.mxd"):
    print mxdname
    mxd = arcpy.mapping.MapDocument(r"C:\Projects\\" + mxdname)
    insertLayer = arcpy.mapping.Layer(r"C:\Projects\layers\ways.lyr")
    dfList = arcpy.mapping.ListDataFrames(mxd, "*")
    for df in dfList:
        for lyr in arcpy.mapping.ListLayers(mxd, "", df):
            if lyr.name =="residence":
                arcpy.mapping.InsertLayer(df, lyr, insertLayer, "AFTER") 
                print 'InsertLayer'          
    mxd.save()
del mxd
2
  • how do you wwant to select your specific dataframe ?
    – radouxju
    Nov 10 '14 at 13:05
  • by index -because all my data frame as the same name "Layers"
    – newGIS
    Nov 10 '14 at 13:31
2

dflist will contain a list of the data frames in the mxd. Use index notation to access a specific data frame. The first data frame will be dflist[0], the second will be dflist[1], and so on.

Edit: although, since you're looping through dflist, what you probably want to do is check the name of the data frame:

if df.name == 'correctdataframe':
    arcpy.mapping.InsertLayer(df, lyr, insertLayer, "AFTER")

What you're currently doing is inserting the layer in every data frame that has a layer named 'residence'. Maybe this is what you want, but it's not exactly what your question states.

9
  • Where do I write those lines?
    – newGIS
    Nov 10 '14 at 13:04
  • You can put it right in the InsertLayer call: arcpy.mapping.InsertLayer(df[1], lyr, insertLayer, "AFTER") to put it in the second layer.
    – recurvata
    Nov 10 '14 at 13:10
  • but all my data frame as the same name "Layers"
    – newGIS
    Nov 10 '14 at 13:25
  • Then you need to change them to different names or skip looping through them and just use the index notation.
    – recurvata
    Nov 10 '14 at 13:28
  • 1
    df = arcpy.mapping.ListDataFrames(mxd)[index] replace "index" with the index of the dataframe
    – JasonT
    Nov 11 '14 at 0:13
1

That code are worked:

import arcpy,os,sys
from arcpy import env

env.workspace = r"C:\Project"   
for mxdname in arcpy.ListFiles("*.mxd"):
    print mxdname 
    mxd = arcpy.mapping.MapDocument(r"C:\Project\\" + mxdname)
    df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]                                       
    LayerList = arcpy.mapping.ListLayers(mxd, "abc", df)
    if len( LayerList) == 0:
        continue
    insertLayer = arcpy.mapping.Layer(r"C:\Project\layers\ways.lyr")
    arcpy.mapping.InsertLayer(df,  LayerList [0], insertLayer, "AFTER")
    print 'InsertLayer'
    mxd.save()
del mxd 
3
  • Glad it works for you, but not the most efficient code. For example, you're declaring InsertLayer every time through the loop. There is no need to do this, since it never changes. You could drop the continue statement by changing the if statement to: if LayerList:, then putting the next three lines in the if block. Using the if statement this way, any empty list will evaluate to False, non-empty to True. It also seems odd that LayerList would ever return False. That would mean you have a data frame with no layers. Certainly possible, but then why is it there?
    – recurvata
    Nov 11 '14 at 12:43
  • yes you right,so how to wrote it ?
    – newGIS
    Nov 12 '14 at 5:58
  • Move the 'insertLayer =...' line to below'env.workspace...' and above 'for mxdname...'. Change 'if len(LayerList) == 0:' to 'if LayerList:', delete 'continue', and indent the next 5 lines so they're in the if block. Look at my response below for guidance. Also, as stated, based on the error you received, you must have at least one mxd that has a data frame with no layers. I don't know why that is, that would be, that's up to you.
    – recurvata
    Nov 12 '14 at 12:34
0

Ok, based on your comments in chat, (that you know which data frame to insert into) and the fact that code won't format in chat (at least, I don't know how), try this:

# no need to keep declaring the inserted layer in the loop. This could be shortened,
# but I like this way because it makes it easier to swap in new values
basedir = r"C:\Projects"
newlyr = r"layers\ways.lyr"
insertLayer = arcpy.mapping.Layer(os.path.join(basedir, newlyr))

# get list of mxds and loop through them
for mxdname in arcpy.ListFiles("*.mxd"):
    print mxdname
    # set current mxd to be the MapDocument
    mxd = arcpy.mapping.MapDocument(os.path.join(basedir, mxdname))
    # since all data frames have the same name, have to get a list of them 
    # to enable indexing
    dfList = arcpy.mapping.ListDataFrames(mxd, "*")

    # get a list of the layers in the first data frame and check if there's a layer
    # named 'residence' in it. If so, insert the new layer. This assumes you know
    # that the first layer is the one you want, per example in chat.
    for lyr in arcpy.mapping.ListLayers(mxd, "", df[0]):
        if lyr.name =="residence":
            arcpy.mapping.InsertLayer(df[0], lyr, insertLayer, "AFTER")
    print 'InsertLayer'

If you know that the mxd has a layer named 'residence', you could skip the for loop with ListLayers and just use the InsertLayer line (changing indentation, of course). If your data frames had different names, you could skip the ListDataFrames code and refer to them by name.

2
  • i get an error: Traceback (most recent call last): File "C:/Users/yaron.KAYAMOT/Desktop/chat.py", line 13, in <module> for mxdname in arcpy.ListFiles("*.mxd"): TypeError: 'NoneType' object is not iterable
    – newGIS
    Nov 11 '14 at 5:49
  • This would be due to a data frame with no layers. While this is possible, why would there be an empty data frame in an existing mxd?
    – recurvata
    Nov 11 '14 at 12:46

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.