Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I am trying to use os.walk to go through a directory tree, pull out all the .shp files in it, create a grouplayer in the mxd, rename the grouplayer the folder name, then add the layers from that folder to the group. This is because I have a lot of folders with files in them that represent geologic formation and they don't mean anything once seperated from the name of the formation. From what I read you can't just add a blank group layer in an mxd from python without first creating a blank one and adding that. The problem starts at the for group_name in rename_group_layer loop. It doesn't even make it through to the print group_name test. Basically it just falls out of the loop from what I can tell. Then I need to figure out how to add the layers from the folder into the renamed group layer. I have two lines commented out that I think are a start, but I haven't gotten it to go through the renaming loop yet. It will rename the first "New Group Layer" if I put that line above the loop to the correct folder name. I am pretty new to python so any help you can give would be greatly appreciated. Thanks in advance.

import os
import arcpy

# Set workspace environment to a folder
WS = r'c:\test_define\Appalachian Basin'
arcpy.env.workspace = WS

mxd = arcpy.mapping.MapDocument(r"c:\test_define\test_python_add3.mxd")
df = arcpy.mapping.ListDataFrames(mxd, "layers")[0]

print ("#") *80
for (path, dirs, files) in os.walk(WS):
    for name in files:
        if name.endswith(".shp"):
        print path
           print "^^^^^^^^^^^^^^^^^^ path variable"

            try:
                layers = arcpy.mapping.ListLayers(mxd)
                for layer in layers:
                    if layer.isGroupLayer and layer.name == os.path.basename(path):
                        newLayer = arcpy.mapping.Layer(os.path.join(path, name))
                        arcpy.mapping.AddLayerToGroup(df, layer, newLayer, "BOTTOM")
                    else:
                        groupLayer =                       arcpy.mapping.Layer(r"c:\test_define\empty_group_layer.lyr")  
                        arcpy.mapping.AddLayer(df, groupLayer, "BOTTOM")

                        layers = arcpy.mapping.ListLayers(mxd)
                        for layer in layers:
                            if layer.isGroupLayer and layer.name == "New Group Layer":
                                layer.name = os.path.basename(path)

                        newLayer = arcpy.mapping.Layer(os.path.join(path, name))
                        arcpy.mapping.AddLayerToGroup(df, layer, newLayer, "BOTTOM")

#mxd.save()


# print messages when the tool runs successfully
            print(arcpy.GetMessages(0))
            #print ("+") *50
        except arcpy.ExecuteError:
            print(arcpy.GetMessages(2))

        except Exception as ex:
            print(ex.args[0])

mxd.saveACopy(r"c:\test_define\test.mxd")

share|improve this question
    
Oh there is no error by the way. It runs to exit code 0 but just doesn't execute that loop. –  SStreisel May 1 '13 at 16:28
    
You have a python27 tag which suggests you are using ArcGIS 10.1 or 10.1 SP1. If it is the latter you may want to consider using arcpy.da.Walk. Also, is there any chance that you can break that long first paragraph up into a series of steps to make it easier to digest? If you can include a question mark somewhere it should make the main focus of your Question more obvious too. –  PolyGeo May 2 '13 at 10:38
add comment

2 Answers

This should work; it worked for me. This will give you a group layer named by the folder and a layer with the name of the shapefile. I built off what artwork21 posted.

import os
import arcpy

WS = r'c:\test_define'
arcpy.env.workspace = "in_memory"

mxd = arcpy.mapping.MapDocument(r"c:\test_define\test_python_add2.mxd")
df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]

for (path, dirs, files) in os.walk(WS):
    for name in files:
        if name.endswith(".shp"):

            groupLayer = arcpy.mapping.Layer(r"c:\test_define\empty_group_layer.lyr")  
            arcpy.mapping.AddLayer(df, groupLayer, "BOTTOM")

            layers = arcpy.mapping.ListLayers(mxd)
            for layer in layers:
                if layer.isGroupLayer and layer.name == "New Group Layer":
                    layer.name = os.path.basename(path)

            newLayer = arcpy.mapping.Layer(os.path.join(path, name))
            arcpy.mapping.AddLayerToGroup(df, layer, newLayer, "BOTTOM")

mxd.save()

You have to make the shapefiles into layers and use AddLayerToGroup. If you want a single group layer for each folder you can recycle this code and modify the os.walk to check for folders with .shp's and go from there. Although, I would recommend trying to contain all these shapefiles into a geodatabase with a proper naming structure and metadata to fit your needs.

To elaborate on the nonrepeating,

import arcpy
import os 

WS = r'c:\test_define'
arcpy.env.workspace = "WS"
mxd = arcpy.mapping.MapDocument(r"c:\test_define\test_python_add2.mxd")
df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
groupLayer = arcpy.mapping.Layer(r"c:\test_define\empty_group_layer.lyr")

for (path, dirs, files) in os.walk(WS):
    for name in files:
        if name.endswith(".shp"):

            layers = arcpy.mapping.ListLayers(mxd)
            name_list = []
            for layer in layers:
                if layer.isGroupLayer:
                    name_list.append(layer.name)

            if os.path.basename(path) not in name_list:
                arcpy.mapping.AddLayer(df, groupLayer, "BOTTOM")
                layers = arcpy.mapping.ListLayers(mxd)
                for layer in layers:
                    if layer.isGroupLayer and layer.name == "New Group Layer":
                        layer.name = os.path.basename(path)
                        newLayer = arcpy.mapping.Layer(os.path.join(path, name))
                        arcpy.mapping.AddLayerToGroup(df, layer, newLayer, "BOTTOM")

            if os.path.basename(path) in name_list:
                layers = arcpy.mapping.ListLayers(mxd)
                for layer in layers:
                    if layer.isGroupLayer and layer.name == os.path.basename(path):
                        newLayer = arcpy.mapping.Layer(os.path.join(path, name))
                        arcpy.mapping.AddLayerToGroup(df, layer, newLayer, "BOTTOM")


mxd.save()

This will check to see if a group layer already exists and will add to it, if so. Else, it will create a new group layer and add the layer.

share|improve this answer
    
To have nonreapting groupfiles: list the layers, and if the group layer is not present - make and add, else skip to AddLayerToGroup. –  gm70560 May 2 '13 at 20:45
    
I am sorry. I just got back to this and made the changes you suggested. Thank you so much for your help. Forgive my ignorance and newness to this, but I am stuck on this "to have nonreapeating groupfiles" though. I am getting a new group for every file in the folder which makes sense after going over the code. You would have to put the list and the skip above the add grouplayer line correct? I am just struggling to figure out where this would go in the code. Again I appreciate all of your help. –  SStreisel May 13 '13 at 17:31
    
I have updated my answer to incorporate the non-repeating issue. –  gm70560 May 13 '13 at 21:25
    
With the new code you suggested GM it doesn't do anything. It just creates a blank MXD doc. the map document (mxd = c:\test_define\test_python_add3.mxd) is blank that its using to add these groups to. The group layer doesn't get created unless the first layers loop is false. So it doesn't create the first group layer to run the test on until after the test fails. Is it kicking it out of the loop because there is no layer to list? –  SStreisel May 14 '13 at 18:25
    
How in the heck do you add a code snippet in here? –  SStreisel May 15 '13 at 16:45
show 4 more comments

You can get group names within map document by:

layers = arcpy.mapping.ListLayers(mxd)

for layer in layers:

    if layer.isGroupLayer and layer.name == "Group":
       newname = str(yourfoldername) 
       layer.name = newname

       mxd.save()
share|improve this answer
    
So I can replace the whole section from rename_group_layer = arcpy.mapping.ListLayers(mxd, "", )[0] to the end with your code and substitue "New Group Layer" for "Group"? –  SStreisel May 1 '13 at 17:23
    
Yes, not removing your defining of group layer and adding it in first. –  artwork21 May 1 '13 at 17:39
    
This is what I changed the code to. –  SStreisel May 1 '13 at 19:22
    
It still doesn't get down to where it will print newname in the loop. It creates 3 group layers with the name of the first folder. No clue why its doing this.. –  SStreisel May 1 '13 at 19:40
    
I put the changes you suggested in the main code box.. Any more suggestions? –  SStreisel May 1 '13 at 19:48
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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