Tuesday, 10 July 2018

arcgis 10.0 - Repairing data sources in multiple MXDs using ArcPy?


I have about 50 mxd's with all broken layers that I have been going through and manually resetting.


The data was moved from another computer and the folder structure was changed so it isn't just a simple process of changing (example):


"F:\Data\Rivers.shp" to "C:\Data\Rivers.shp"


it is more like :



"F:\Data\Rivers.shp" to C:\Data\Park\Water\Rivers.shp


and so on for all kinds of data (boundaries, veg cover, roads, etc.) each in their own sub-folder.


I want to make a script that I can run repeatedly whenever I open one of these mxd's that would at least repair some of the more common layers that are found in most of my mxd's, and then I can manually repair the rest. That way I can at least save myself some time.


I have been using something along the lines of :


import arcpy
mxd = arcpy.mapping.MapDocument("CURRENT")

for lyr in arcpy.mapping.ListLayers(mxd):
if lyr == "Rivers": #Should this be the layner name in TOC or FC name?
lyr.replaceDataSource(r"C:\Data\Park\Water", "SHAPEFILE_WORKSPACE", "Rivers")


The idea then would be to somehow add multiple "replace" scripts in the above for other common layers that are in my mxd's.


However the above script doesn't even fix the Rivers layer.


How can I get it to work, and also add in other layers to be repaired that have different file paths?



Answer



You are on the right track with your script. It looks like your problem lies in how you are comparing the Layer object, to the Name of the Layer in the Table of Contents.


When you use the ListLayers function, what is returned is a Layer object. You cannot then compare this to a text string to see if they are equal, you need to access the Name of the Layer instead.


import arcpy
mxd = arcpy.mapping.MapDocument("CURRENT")


for lyr in arcpy.mapping.ListLayers(mxd):
if lyr.name.lower() == "rivers": #This should be the Layer name in the TOC?
lyr.replaceDataSource(r"C:\Data\Park\Water", "SHAPEFILE_WORKSPACE", "Rivers")

To add more selectors, you simply expand the if/then portion of the code to look for different layer names.


for lyr in arcpy.mapping.ListLayers(mxd):
if lyr.name.lower() == "rivers": #This should be the Layer name in the TOC?
lyr.replaceDataSource(r"C:\Data\Park\Water", "SHAPEFILE_WORKSPACE", "Rivers")
elif lyr.name.lower() == "streets":
lyr.replaceDataSource(r"C:\Data\Facilities\Streets", "SHAPEFILE WORKSPACE", "Streets")


Simply continue to modify the name selector to find any particular unique layer in your .mxd, and add a replaceDataSource function to handle it. Please notice that I used the lower function when testing for the name. This is also used by ESRI in their help documents, with the reasoning likely being that it removes the chance of inconsistencies in capitalization, causing a mismatch in the layer name.


Here is the ESRI Help article on Updating and Fixing Data Sources with Arcpy Mapping


The Help files for ArcGIS in general are very useful as they contain clear explanations, and a lot of Python code samples that you can simply copy/paste and modify to suit your specific needs.


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...