Hi All,
I've been trying to ungroup a group layer in TOC using Arcpy with no luck. There is no such function in arcpy so the approach I am trying to do is moving layer by layer out of the group and place them all on top of TOC.
However I can't get the loop through layers working.
The mxd structure is:
And I want to have:
The code below only moves the last layer from the TopGroup:
import arcpy, os
MapMainFolder = r"Z:\Workspace" # topmost folder
for (root, dirs, files) in os.walk (MapMainFolder):
for fileName in files:
if os.path.splitext (fileName)[1] == ".mxd":
arcpy.AddMessage (fileName)
fullPath = os.path.join (root, fileName)
mxd = arcpy.mapping.MapDocument (fullPath)
print fileName
df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
#Layers to be moved !!! NEEDS TO LOOP through all layers !!!
for lyr in arcpy.mapping.ListLayers(mxd):
if lyr.name != lyr.longName:
moveLayer = lyr
print moveLayer
#Topmost group layer, the content of this group layer should be moved above this layer and the group can remain empty
for lyr in arcpy.mapping.ListLayers(mxd):
if lyr.name == lyr.longName:
refLayer = lyr
print refLayer
arcpy.mapping.MoveLayer(df, refLayer, moveLayer, "BEFORE")
arcpy.RefreshTOC()
arcpy.RefreshActiveView()
mxd.save()
Anyone has any idea on:
The reason I need to ungroup the layers is to avoid having all layers rasterized when exporting to an Illustrator file.
Thanks for help!
Solved! Go to Solution.
If you want to flatten all group layers, which it seems like you do, then Terry Giles's code will do the trick. If you want to flatten all group layers by just one level, the following code will work (it leaves the high level empty group layers in place):
import arcpy
for df in arcpy.mapping.ListDataFrames(mxd):
for lyr in arcpy.mapping.ListLayers(mxd, "*", df):
depth = len(lyr.longName.split("\\"))
if depth == 1:
refLayer = lyr
elif depth == 2:
moveLayer = lyr
arcpy.mapping.MoveLayer(df, refLayer, moveLayer, "BEFORE")
arcpy.RefreshTOC()
How do you want to handle nested group layers, or don't you have any?
wouldn't it just be easier to get the list of layers, remove them from the project, then add them back in the order that you want?
basic implementation of Dan Patterson's answer - takes them all out and puts the non group layers back in, in the order they were. Assumes there are no properties set on the group layers (e.g. scale dependency) that you would also want apply to the sublayers once ungrouped.
import arcpy
def is_group_layer(layer):
return not layer.isGroupLayer
mxd = arcpy.mapping.MapDocument("current")
for df in arcpy.mapping.ListDataFrames(mxd):
layers = arcpy.mapping.ListLayers(mxd,"",df)
keep_layers = filter(is_group_layer,layers)
for layer in layers:
arcpy.mapping.RemoveLayer(df,layer)
for layer in keep_layers:
arcpy.mapping.AddLayer(df,layer,"BOTTOM")
mxd.save()
Thanks Terry Giles. It works but it ungroups everything. I forgot to mention there were some subgroups in the topmost group layer and they needed to remain grouped. Anyway the other solution below works.
Perhaps something like:
mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd)[0]
for layer in arcpy.mapping.ListLayers(mxd):
if layer.isGroupLayer:
if layer.name == layer.longName:
refLayer = layer
# print "Reference layer: {}".format(refLayer.name)
else:
if layer.name != layer.longName:
moveLayer = layer
# print "Move layer: {}".format(moveLayer.name)
arcpy.mapping.MoveLayer(df,refLayer,moveLayer,"BEFORE")
# group layers should be empty, remove them
for layer in arcpy.mapping.ListLayers(mxd):
if layer.isGroupLayer:
arcpy.mapping.RemoveLayer(df, layer)
Thanks Randy,
This seem to work. However I forgot to add there are indeed sub-grouplayers within the top group layer with group settings ( transparency etc.) and they need to remain in groups. Basically I just need to ungroup only the topmost group.
The TOC looks like this:
And I need to have:
Your script works perfect but I need to keep the subgroup settings intact. I realise that might be a limiting factor.
Cheers!!
If you want to flatten all group layers, which it seems like you do, then Terry Giles's code will do the trick. If you want to flatten all group layers by just one level, the following code will work (it leaves the high level empty group layers in place):
import arcpy
for df in arcpy.mapping.ListDataFrames(mxd):
for lyr in arcpy.mapping.ListLayers(mxd, "*", df):
depth = len(lyr.longName.split("\\"))
if depth == 1:
refLayer = lyr
elif depth == 2:
moveLayer = lyr
arcpy.mapping.MoveLayer(df, refLayer, moveLayer, "BEFORE")
arcpy.RefreshTOC()
This is it bixb0012!!
Works flawlessly. Thanks a lot!
Indeed I forgot to add there are sub-grouplayers within the top group layer with layer properties( transparency etc.) and they need to remain in groups. Basically I just needed to ungroup only the topmost group.
The TOC looks like this:
And I need to have:
Anyway your solution works and it remains the layer properties as they were in the subgroups. Elegant and simple.
Cheers!
Jan