# Ensure relative path in Arcgis layer files

I'm looking for the arcgis python equivalent of the VBA How to save a layer file with a relative path.

I'm using a script to change the paths in a collection of about 75 layer files before distributing to outside offices. The script works well, except that the new layer file paths are not relative, which means they usually are broken for the recipients as they rarely use the same drive letters etc. as we do, which pretty much defeats the purpose.

Paths follow the pattern X:\Layers\Category1\Group3, and X:\data\One.gdb, i.e. the layers and data are one the same drive but not in the same tree.

-
Pretty sure it's not possible in 10.0 without using ArcObjects in Python or reverse-engineering the layer file structure. Likely something they'll implement in 10.1 though. –  blah238 Oct 19 '11 at 5:10
Is the data path in the same folder as the script you are running or within a subfolder within its path? –  Dan Patterson Oct 19 '11 at 17:11
@dan, paths follow the pattern X:\Layers\Category1\Group3, X:\data\One.gdb –  matt wilkie Oct 19 '11 at 21:36

I found a solution: a) don't validate replaceDataSource (last parameter is False instead of True), and b) use SaveToLayerFile which has a "relative" parameter instead of saveACopy:

try:
lyr.replaceDataSource(target_wspace, 'FILEGDB_WORKSPACE', lyr.datasetName, False)
# lyr.saveACopy(fixed_fname)
arcpy.SaveToLayerFile_management(lyr, fixed_fname, "RELATIVE")
except:
print arcpy.GetMessages()


Unfortunately it doesn't work with group layer files, but at least it's progress!

For your info and to avoid confusion, as the apparent contradiction certainly confused me at first, in the Esri doc Paths explained it states unequivocally that relative paths are not supported in scripts while the reference page for Save to Layer file says just as clearly there is a RELATIVE keyword.

What this means in practice is that yes you must use full path notation in scripts, x:\data\foo.gdb and not ..\..\data\foo.gdb, and then saveToLayer strips the drive letter and leading directories on save. So the inputs must always be full paths, while the output may or may not be.

As far as I can tell SaveToLayerFile is the only arcpy command with a relative parameter. I presume there is an equivalent for saving mxd's but I haven't found it yet.

-

You can us arcpy like you're doing now, but save the layer files to the OS temp folder, and then use straight up Python to copy the saved file from temp location to wherever relative path it needs to go to.

-
Not sure how this solves the problem of making the path stored in the layer file itself relative. The point is to make it so there are no broken links on the client's file system. –  blah238 Oct 19 '11 at 19:34
The limitation in question is that the script being used to save the layer file requires an absolute path, so that path can be programatically set to go somewhere known, and then the user can be prompted or the file could be copied to a relative location using Python. So it's not the optimal solution, which would be for Esri to change the saveACopy method to allow relative paths. It is instead a workaround, but a solution nonetheless. –  Gady Oct 19 '11 at 22:10
my script uses whatever path is given to it, e.g. repath-layers mylayer.lyr ..\..\distribution-dir\fixed-layers ..\..\new\path\to\data.gdb is legal. The problem is that something in arcpy changes ..\..\new\path\to\data.gdb to x:\new\path\to\data.gdb when it saves the new layer file. I don't understand how using the temp folder is a solution, that is still an absolute path, and to my profile no less. This virtually guarantees the layer file will break when moved from my computer to someone elses. –  matt wilkie Oct 20 '11 at 20:42
Actually the temp folder solution tempfile.gettempdir() returns C:\temp or C:\tmp on Windows machines, so it should work to write the layer file there and then use shutil.move or shutil.copyfile to move it to some other known location. Just trying to provide you something better than "Nope, impossible." –  Gady Oct 21 '11 at 3:31
I appreciate the trying to provide at least something that could work, but putting the data under c:\temp as well is just not workable. –  matt wilkie Oct 31 '11 at 18:58