I am struggling to move web services (tiled basemaps) out of group layers into the data frame. I've used arcpy.mapping.ListLayers to compose a list of layers, then I've ascertained what is a group layer with .isGroupLayer and I've tested the group layers name and then what it "supports". However I failed miserably to pick up weird web service group layer and move them. I've tested arcpy.mapping.AddLayer among a handful of things.

Any ideas are welcome. My desired outcome is to have no web services in group layers.

enter image description here

import arcpy
mxd ="C:\\Data\\native.mxd"
OriginMxd = arcpy.mapping.MapDocument (mxd)
df = arcpy.mapping.ListDataFrames(OriginMxd)[0]

for OPFSLyr in arcpy.mapping.ListLayers(OriginMxd, "", df):
    if str(OPFSLyr) == "Basemap": # if  it's named basemap
        if OPFSLyr.isGroupLayer:
            for subLayer in OPFSLyr:
                print subLayer
                arcpy.mapping.AddLayer(df, subLayer, "BOTTOM")
  • Are you able to do that manually in ArcMap? Commented Jul 2, 2015 at 8:03
  • Oh yes. In ArcMap it's a simple right-click>copy on the web service group layer and right-click>paste into the data frame.
    – GISI
    Commented Jul 2, 2015 at 8:15

1 Answer 1


You're close. Instead of AddLayer, you can use MoveLayer. The ESRI example code, along with some tweaks to your own data structures can be tweaked to move layers you want up to the root of the data frame. See code:

mxd = arcpy.mapping.MapDocument(r"C:\peendata\MoveLayers.mxd")
df = arcpy.mapping.ListDataFrames(mxd)[0]
moveThese = []

for layer in arcpy.mapping.ListLayers(mxd, "", df):
    print str(layer.name) + ">>>"
    if layer.isServiceLayer:
        print str(layer) + " is a service layer"
    if layer.isFeatureLayer:
        print str(layer) + " is a feature layer"
    if layer.isRasterLayer:
        print str(layer) + " is a raster layer"
    if layer.isGroupLayer:
        print str(layer) + " is a group layer"
    if str(layer) == "Group Layer 1":
        refLayer = layer

    if(layer.isServiceLayer and not layer.isGroupLayer):
        print "qualifies for movement"

for layer in moveThese:
    print "moving " + str(layer) 
    arcpy.mapping.MoveLayer(df, refLayer, layer, "BEFORE")

del mxd

Some caveats: not all web services are defined as web services. For example, OpenStreetMap, which you also add as an external link, is a layer package, so the code above will not move it. I did not find a way to detect whether it is a layer package from the web, so make sure the layers you want to move are what you expect code-wise.

In regards to your particular layer structure, be advised that Global_Imagery is a locked layer set, so you cannot its separate sublayers even in ArcMap by hand. In fact, the code still does it (kind of), but the moved layers are broken, and the original ones are still in place. Make sure the layers you are trying to move are actually moveable by hand.

Finally, the code should obviously be tweaked to what exactly you're looking for: you might not want them at the very root level, your topmost group layer might be called otherwise, etc. Included are some functions that you can use to test the layer's properties.

Oh and yes. Sometimes service layers are also group layers - so test carefully.

For reference, my layer structure pre and post: TOC pre and post-move

  • Alas, only: if layer.isGroupLayer: works. The layer.isService is not picking up the service layers in the group layers. What version of ArcGIS are you running?
    – GISI
    Commented Jul 8, 2015 at 3:46
  • I've tested this at 10.3.1 and it failed. I then tested it at 10.1 and it worked. I think there's a bug at 10.3.1. I will bring it to Esri Inc's attention.
    – GISI
    Commented Jul 8, 2015 at 4:07
  • Ah interesting. This was run on ArcGIS 10.2.
    – Max K
    Commented Jul 9, 2015 at 8:31
  • Esri Technical Support: "This is Tom with Esri tech support, I've taken over on this case from Amit. I've tested this issue in ArcGIS for Desktop version 10.3.1 and am unable to reproduce the issue. A layer within a group layer will return the correct results when checked against any of the is*Layer functions."
    – GISI
    Commented Jul 14, 2015 at 2:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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