Friday, 22 May 2015

arcgis 10.0 - Changing data source path involving feature dataset in *.lyr files using ArcPy?


How can one change the source data paths for every layer file in folder X using arcpy?


I've followed Updating and fixing data sources with arcpy.mapping as best I can, yet all I get is an unhelpful Runtime error : Layer: Unexpected error which doesn't tell me enough to troubleshoot what's wrong or missing.


Heres the code (simplified to test a single layer file):



import arcpy, os

fname = r'K:\Layers\xxx.lyr'
lyr = arcpy.mapping.Layer(fname)
oldpath = lyr.workspacePath
print 'oldpath: ', oldpath
lyr.findAndReplaceWorkspacePath(oldpath, r'C:\some\other.gdb')
print 'newpath: ', lyr.workspacePath

and the results:



oldpath:  K:\Canvec_Utility\Temp.gdb
Traceback (most recent call last):
File "x10x.py", line 12, in
lyr.findAndReplaceWorkspacePath(oldpath, r'C:\some\other.gdb')
File "C:\ESRI\ArcGIS\Desktop10.0\arcpy\arcpy\utils.py", line 181, in fn_
return fn(*args, **kw)
File "C:\ESRI\ArcGIS\Desktop10.0\arcpy\arcpy\_mapping.py", line 601, in findAndReplaceWorkspacePath
return convertArcObjectToPythonObject(self._arc_object.findAndReplaceWorkspacePath(*gp_fixargs((find_workspace_path, replace_workspace_path, validate), True
)))
ValueError: Layer: Unexpected error


((moved 'update' section into an answer))



Answer



It looks like the correct method to use when switching workspaces AND feature datasets is lyr.replaceDataSource(). Here's my working script:


''' Change the datasource path for the given layer file '''

import arcpy, os

# layer file to re-path
fname = arcpy.GetParameterAsText(0)

# new path to workspace containing the feature class
target_wspace = arcpy.GetParameterAsText(1)
# where to save the layer files
savedir = arcpy.GetParameterAsText(2)

lyr = arcpy.mapping.Layer(fname)

fixed_fname = os.path.join(savedir, lyr.longName)

print '\nOld layer properties (%s)' % (fname)

print 'workspace:\t', lyr.workspacePath
print 'full path:\t', lyr.dataSource

try:
lyr.replaceDataSource(target_wspace, 'FILEGDB_WORKSPACE', lyr.datasetName, True)
lyr.saveACopy(fixed_fname)
except:
print arcpy.GetMessages()

print '\nNew layer properties (%s)' % (fixed_fname)

print 'workspace:\t', lyr.workspacePath
print 'full path:\t', lyr.dataSource

del lyr

In testing it seems validate in this method is different again: it verifies the new workspace is valid, but ignores the feature class and feature datasets -- meaning it won't return an error if the target FC is not there.


On the other hand if the target FC is present, even inside a different feature dataset, the new data source path is adapted accordingly regardless of whether validate is true or false.


Update: now on Github to allow for easier sharing and revision.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...