Ungroup a Group Layer

3894
8
Jump to solution
10-22-2017 08:17 PM
janrykr1
Emerging Contributor

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:

  • Topmost Group
    • Layer1
    • Layer2
    • Layer3
    • ...

And I want to have: 

  • Layer1
  • Layer2
  • Layer3
  • ...

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:

  1. how to loop through the layer list?
  2. how use a different approach? 

The reason I need to ungroup the layers is to avoid having all layers rasterized when exporting to an Illustrator file.

Thanks for help!

1 Solution

Accepted Solutions
JoshuaBixby
MVP Esteemed Contributor

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()

View solution in original post

8 Replies
JoshuaBixby
MVP Esteemed Contributor

How do you want to handle nested group layers, or don't you have any?

0 Kudos
DanPatterson_Retired
MVP Emeritus

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?

TerryGiles
Frequent Contributor

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()
janrykr1
Emerging Contributor

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.

0 Kudos
RandyBurton
MVP Alum

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)
janrykr1
Emerging Contributor

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:

  • Topmost Group
    • Layer1
    • Group (has group layer properties)
      • Layer2
      • Layer3
      • ...
    • Layer4
    • ...

And I need to have: 

  • Layer1
  • Group  (has group layer properties)
    • Layer2
    • Layer3
    • ...
  • Layer4
  • ...

Your script works perfect but I need to keep the subgroup settings intact. I realise that might be a limiting factor.

Cheers!!

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

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()
janrykr1
Emerging Contributor

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:

  • Topmost Group
    • Layer1
    • Group (has group layer properties)
      • Layer2
      • Layer3
      • ...
    • Layer4
    • ...

And I need to have: 

  • Layer1
  • Group  (has group layer properties)
    • Layer2
    • Layer3
    • ...
  • Layer4
  • ...

Anyway your solution works and it remains the layer properties as they were in the subgroups. Elegant and simple.

Cheers!

Jan

0 Kudos