Unable to change data source path for group layer file

6213
13
Jump to solution
06-01-2012 07:02 AM
jayshukla
New Contributor III
Hi There,
I am having some difficulty changing the data source for a grooup layer. Below is the code that i am using. It processes LYR file successfully that has single data source but if LYR file has more than one data layers, it doesn't do it. Appreciate any feedback.

Thanks
Jay  



import arcpy, datetime, os, io, sys

try:

    #Read input parameters from GP dialog
   
 
    # Prod Setting...
    folderPath = arcpy.GetParameterAsText(0)
    output = arcpy.GetParameterAsText(1)
    sourceString = r"P:\Temp" #
    replacmentString = r"Z:\Temp" #
   
    #Create an output file
    outFile = open(output, "w")

    #Loop through each "LYR" file
    count = 0
    for path, dires, files in os.walk(folderPath):
        #for filename in os.listdir(folderPath):
        for filename in files:
            #fullpath = os.path.join(folderPath, filename)
            fullpath = os.path.join(path, filename)

            if os.path.isfile(fullpath):
                if filename.lower().endswith(".lyr"):
                    groupLayerName = ""
                    #Reference LYR
                    layerFile = arcpy.mapping.Layer(fullpath)

                    #Reference each layer in a layer file
                    count = 1
                    for lyr in arcpy.mapping.ListLayers(layerFile):
                        if lyr.isGroupLayer:
                            groupLayerName = lyr.name

                        if lyr.supports("DATASOURCE"):
                            dataSourceOrig = str(lyr.dataSource)
                            if dataSourceOrig.find(sourceString) >= 0:
                               
                                dataSourceNew = dataSourceOrig.replace(sourceString, replacmentString)

                                if groupLayerName:
                                    outFile.write(fullpath + "\t" + groupLayerName + "\t" +lyr.name + "\t"  + dataSourceOrig + "\t" + dataSourceNew + "\t" + "GROUP LAYER SOURCE" "\n")
                                    lyr.findAndReplaceWorkspacePath(sourceString, replacmentString, True)
                                    lyr.save()
                                else:
                                    outFile.write(fullpath + "\t" + "Non Group Layer" + "\t" + lyr.name + "\t" + dataSourceOrig + "\t" + dataSourceNew + "\t" + "SINGLE LAYER SOURCE" "\n")
                                    lyr.findAndReplaceWorkspacePath(sourceString, replacmentString, True)
                                    lyr.save()
                    del layerFile

    outFile.close()

    #Open the resulting text file
    os.startfile(output)

    #Delete variables that reference data on disk
    del outFile
   
except Exception, e:
  import traceback
  map(arcpy.AddError, traceback.format_exc().split("\n"))
  arcpy.AddError(str(e))
0 Kudos
1 Solution

Accepted Solutions
NobbirAhmed
Esri Regular Contributor
Group Layer does not have any path - so you cannot change its path. Whenever, you encounter a group layer, skip it as in this code snippet:

if layer.isGroupLayer:     pass    # skip else:     #replace data path


It will be easier to read your code if you copy-paste them within CODE tags (click on the hash symbol to get tags).

There is a simple sample here:

import arcpy mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd") for lyr in arcpy.mapping.ListLayers(mxd):     if lyr.supports("DATASOURCE"):         if lyr.dataSource == r"C:\Project\Data\Parcels.gdb\MapIndex":             lyr.findAndReplaceWorkspacePath(r"Data", r"Data2") mxd.saveACopy(r"C:\Project\Project2.mxd") del mxd


Here is the topic:
http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/Updating_and_fixing_data_sources_with_...

View solution in original post

0 Kudos
13 Replies
NobbirAhmed
Esri Regular Contributor
Group Layer does not have any path - so you cannot change its path. Whenever, you encounter a group layer, skip it as in this code snippet:

if layer.isGroupLayer:     pass    # skip else:     #replace data path


It will be easier to read your code if you copy-paste them within CODE tags (click on the hash symbol to get tags).

There is a simple sample here:

import arcpy mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd") for lyr in arcpy.mapping.ListLayers(mxd):     if lyr.supports("DATASOURCE"):         if lyr.dataSource == r"C:\Project\Data\Parcels.gdb\MapIndex":             lyr.findAndReplaceWorkspacePath(r"Data", r"Data2") mxd.saveACopy(r"C:\Project\Project2.mxd") del mxd


Here is the topic:
http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/Updating_and_fixing_data_sources_with_...
0 Kudos
WaiChan1
New Contributor II
I am running into the same problem - not in ArcMap, but in ArcCatalog. I am trying to change the data sources of layer files systematically in a folder in ArcCatalog. The python script runs fine except when it hits a group layer file.

The script can read the group layer, recognizes it is a group layer, loop through the group layer to access each individual layer. However, the individual layers within the group layer do not support "dataSource" or "datasetName" properties. And therefore, I cannot change the data sources of these group layers.

I couldn't seem to find much documentation on this issue. Does anyone else encounter the same problem and can offer some suggestions? Thank you!
0 Kudos
NobbirAhmed
Esri Regular Contributor
I've just tested on 10.0 SP5 and cannot reproduce the issue. Which version of ArcGIS you are using? Can you post your code? Don't forget to use code block (click on # sign above).

Have you tested this line?

if lyr.supports("DATASOURCE"):
0 Kudos
WaiChan1
New Contributor II
Thank you for the response. I am also using ArcGIS 10.0 SP 5.

For a one-level group layer, I can cycle through each individual layer and repoint the data source. My problem comes when it gets to a nested group layer. For any sub-group layers within a group layer, the script does not support any datasource.

Here is my short script:

import arcpy
lyr = arcpy.mapping.Layer(r"C:\Temp\Group1.lyr") #Nested group layer file
for layer in lyr:
    print layer.dataSource


And here is the error that follows the execution. The error appears when it hits the sub-group layer within the group layer.

Traceback (most recent call last):
  File "<interactive input>", line 2, in <module>
  File "C:\Program Files (x86)\ArcGIS\Desktop10.0\arcpy\arcpy\arcobjects\_base.py", line 70, in _get
    return convertArcObjectToPythonObject(getattr(self._arc_object, attr_name))
AttributeError: LayerObject: Get attribute dataSource does not exist
0 Kudos
NobbirAhmed
Esri Regular Contributor
Have you checked both layer.isGroupLayer and layer.supports("DATASOURCE")? See my code below:

import arcpy

try:
    mxd = arcpy.mapping.MapDocument(r"C:\test\mymap.mxd")
    layers = arcpy.mapping.ListLayers(mxd)

    for layer in layers:
        if not layer.isGroupLayer:
            if layer.supports("DATASOURCE"):
                print layer.dataSource

except:
    print "Exception ...."
WaiChan1
New Contributor II
That was it!! I was scratching my head for a couple of weeks figuring out how to do nested group layers in Python. I can't believe it was this simple. Thank you again!
0 Kudos
JeffThomas
New Contributor II

I am also attempting to re-source a bunch of layer files, some of which are group layers, in a folder. I started with the same script found above, which the OP also posted to GIS Stack Exchange and someone there added a recursive function to parse through nested group layers. Seemed like the perfect solution. Except the script errors out as soon as it hits a group layer. More specifically: as soon as it tries to save the first layer within a group layer, it returns an error: "No filename set". I believe this is because the .name and .longName attributes of the layer variable are the same even though they shouldn't be if the layer is inside a group layer. Thus, the conditional statement on line 27 (if singlelayer.name != singlelayer.longName:) is never met and all layers move on to "else". Something in this script is causing .name and .longName to become identical because they are just fine if I check for them in a separate, simpler script. I am using ArcGIS 10.2, but I believe the original script was written for 10.0. Any ideas what could be causing this?

import arcpy, datetime, os, io, sys  def walknestedgroups(layerlist,srcString,repString,pathfull,outputFile):   if layerlist.isGroupLayer:     #Cycle through grouplayer     print "%s is a group layer" % layerlist          for layer in layerlist:       print "%s is a layer inside %s" % (layer,layerlist)       print "name: " + layer.name       print "long name: " + layer.longName       #This will continue to cycle through and test for group layers       walknestedgroups(layer,srcString,repString,pathfull,outputFile)    else:      print "%s is a single layer" % layerlist           #Once a non-group layer is returned, head through the rest of original script     singlelayer = layerlist     if singlelayer.supports("DATASOURCE"):       dataSourceOrig = str(singlelayer.dataSource)       if dataSourceOrig.find(srcString) >= 0:         dataSourceNew = dataSourceOrig.replace(srcString, repString)          #This comparison test for layers in a group layer vs those not in.  The .longName property includes all group layers as part of path         if singlelayer.name != singlelayer.longName:           outputFile.write(pathfull + "\t" + singlelayer.longName + "\t" + singlelayer.name + "\t" + dataSourceOrig + "\t" + dataSourceNew + "\t" + "GROUP LAYER SOURCE" "\n")           singlelayer.findAndReplaceWorkspacePath(sourceString, replacementString, True)           print "%s group source changed" % singlelayer           singlelayer.save()           print "%s saved" % singlelayer          else:           outputFile.write(pathfull + "\t" + "Non Group Layer" + "\t" + singlelayer.longName + "\t" + dataSourceOrig + "\t" + dataSourceNew + "\t" + "SINGLE LAYER SOURCE" "\n")           singlelayer.findAndReplaceWorkspacePath(srcString, repString, True)           print "%s source changed" % singlelayer            singlelayer.save()           print "%s saved" % singlelayer      return layerlist     print "loop exited for " + layerlist + " group layer"   try:      #Read input parameters from GP dialog    # Prod Setting...   folderPath = r"G:\JThomas\LayerFiles\Vector\REAL_PROPERTY"   output = r"G:\JThomas\LayerFiles\logfile.log"   sourceString = ""    replacementString = r"P:\LE\Connections\LE_CAC @ CLJN.sde"    #Create an output file   outFile = open(output, "w")    #Loop through each "LYR" file   count = 0   for path, dires, files in os.walk(folderPath):     # for filename in os.listdir(folderPath):     for filename in files:       # fullpath = os.path.join(folderPath, filename)       fullpath = os.path.join(path, filename)        if os.path.isfile(fullpath):                if filename.lower().endswith(".lyr"):           groupLayerName = ""           #Reference LYR           layerFile = arcpy.mapping.Layer(fullpath)            #Iterate through layer list and all group layers.  Return single layer            for totallayer in arcpy.mapping.ListLayers(layerFile):             #This function will take each layer in the .lyr file, cycle through any group layers then apply path changes to individual layers             singlelayer = walknestedgroups(totallayer,sourceString,replacementString,fullpath,outFile)           del layerFile    outFile.close()    #Open the resulting text file   os.startfile(output)    #Delete variables that reference data on disk   del outFile  except Exception, e:   import traceback   map(arcpy.AddError, traceback.format_exc().split("\n"))   arcpy.AddError(str(e))   print "Error: %s" % e

Edit: not sure what the deal is with the code block. It looked fine in the preview and now it's all one line. I've attached it as a separate file. Sorry for any inconvenience viewing it!

ericmeyers1
New Contributor III

I'm having the exact same issues and cannot figure out why I keep getting the error 'no filename set'. It is discouraging that ESRI would allow you to create group .lyr files but not allow you to modify them the same way.

0 Kudos
AnnStark2
New Contributor II

I am having the same issue.  Is this a new bug that a previously working script now fails?

0 Kudos