Select to view content in your preferred language

Use arcpy to check if .lyr file uses relative path names

3092
13
01-31-2017 05:24 PM
AnthonyCheesman1
Frequent Contributor

Hi

I have a library of many hundred .lyr files that are distributed to my user base along with a data package.

Users will save the data and layer files on various drive letters and directory locations. This works fine as the layer files are generally saved with relative file paths (creating using tool "Save To Layer File" and selecting the 'Store Relative Path' option.

I would now like to develop an audit process for the layer file library, and to do so I will walk through the directory structure and iterate through all of the .lyr files. For each file I will check if the data source is current (which I've worked out how to do) and then check that the .lyr file path is relative (which I haven't worked out how to do).

Is there an arcpy method that I can check this component of the .lyr file properties? I would imagine it sits somewhere with the layer methods, but I can't see any reference to this property in the documentation.

Thanks

0 Kudos
13 Replies
XanderBakker
Esri Esteemed Contributor

I don't...

0 Kudos
curtvprice
MVP Esteemed Contributor

I don't either, Xander's method is probably best then.

0 Kudos
XanderBakker
Esri Esteemed Contributor

The only thing I can come up with is to copy the layerfile to another location and see if the datasource is still pointing to the same location (absolute) or not (relative):

def main():
    import arcpy
    import os
    from shutil import copyfile
    tmp_folder = r'C:\GeoNet\RelativePath\tmp'

    lyrs = [r'C:\GeoNet\RelativePath\Layerfile_relative_path.lyr',
            r'C:\GeoNet\RelativePath\Layerfile_absolute_path.lyr']

    for lyr_file in lyrs:
        print "\n", lyr_file
        lyr = arcpy.mapping.Layer(lyr_file)
        datasource_before = lyr.dataSource
        print "before:", datasource_before
        lyr_file_dest = os.path.join(tmp_folder, os.path.split(lyr_file)[1])
        print lyr_file_dest
        copyfile(lyr_file, lyr_file_dest)
        lyr_tmp = arcpy.mapping.Layer(lyr_file_dest)
        datasource_after = lyr_tmp.dataSource
        print "after :", datasource_after
        if datasource_before == datasource_after:
            print " - Datasource is Absolute path"
        else:
            print " - Datasource is Relative path"


if __name__ == '__main__':
    main()‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

This yields:

C:\GeoNet\RelativePath\Layerfile_relative_path.lyr
before: C:\Fabiola\ManglaresInvemar\gdb\ManglarCentroPob.gdb\Manglares
C:\GeoNet\RelativePath\tmp\Layerfile_relative_path.lyr
after : C:\GeoNet\Fabiola\ManglaresInvemar\gdb\ManglarCentroPob.gdb\Manglares
 - Datasource is Relative path

C:\GeoNet\RelativePath\Layerfile_absolute_path.lyr
before: C:\Fabiola\ManglaresInvemar\gdb\ManglarCentroPob.gdb\Manglares
C:\GeoNet\RelativePath\tmp\Layerfile_absolute_path.lyr
after : C:\Fabiola\ManglaresInvemar\gdb\ManglarCentroPob.gdb\Manglares
 - Datasource is Absolute path‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
GrantHerbert
Frequent Contributor

This is what I see when I open the layer file in Notepad, for a layer file created with arcpy.SaveToLayerFile_management with is_relative_path set to "RELATIVE". Layer File Relative Path in Notepad

However I have just realized that the ". . \" does not always exist - it depends on where your data resides. However, a check for ": \" may identify an absolute path. This will probably require searching for the encoded values, which will look like b'\x00F' for example. I have no idea what the correct code for ':' would be though.

0 Kudos