Updating a layer to multiple MXDs

1037
5
Jump to solution
03-15-2013 06:13 PM
KenLucas
Occasional Contributor
I'm frustrated that the ESRI sample scripts do not allow updating multiple mxds. In the real world why would someone go to the trouble to modify a sample script that just updates one mxd?  Would it not just be faster to make the change to the single mxd?  Every scenrio I encounter requires updating a huge no of mxds.
Here's a script  that works, on our server, to remove multiple layers from multiple mxds. Could someone, please, tell me how to mod it to update layer. I tried modifying the sample layer available from esri and couldn't even get close. I just want to change the color symbology of the dams layer, for all of the mxds stored in the target layers folder, with the source layer, Dams, archived in an "update layers" folder on my server
Ken




import arcpy
import os
import glob
mxds_path = r'S:\\Users Shared\\LOpperman\\Town Scale MXDs\\MXDs\\targetlayers\\'
layer_name = r'dams'
data_frame = r'Primary'
layers = []
mxds = []

for infile in glob.glob(os.path.join( mxds_path, "*.mxd" )):
  mxd = arcpy.mapping.MapDocument(infile)
  print "removing Dams layer from "  + infile
  for df in arcpy.mapping.ListDataFrames(mxd, data_frame):
    for lyr in arcpy.mapping.ListLayers(mxd, "", df):
      #print lyr
      if lyr.name.lower() == layer_name:
        print 'Remove layer ' + layer_name
        arcpy.mapping.RemoveLayer(df, lyr)
  #copyFile = mxds_path + r"NEW_" +
  #print copyFile
  mxd.save()
 

#for mxd_name in mxds:
  #mxd = arcpy.mapping.MapDocument(mxds_path + mxd_name)
  #print 'removing layer for ' + mxd_name
 
#  mxd.save() 
[/COD]
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
T__WayneWhitley
Frequent Contributor
Do something like this (untested):
import arcpy, os, glob mxds_path = r'S:\\Users Shared\\LOpperman\\Town Scale MXDs\\MXDs\\targetlayers\\' layer_name = r'dams' data_frame = r'Primary'  # Say you want to replace the 'Dams' layer with an updated dams layer saved to a layer file. # ...in this case a 'source' layer object was created using lyr file stored outside the map document: # (The network folder 'LYRs' is fictitious...replace this pathname accordingly.) sourceLayer = arcpy.mapping.Layer(r'S:\\Users Shared\\LOpperman\\Town Scale MXDs\\LYRs\\Dams.lyr")  for infile in glob.glob(os.path.join( mxds_path, "*.mxd" )):      mxd = arcpy.mapping.MapDocument(infile)      print "replacing Dams layer from " + infile      for df in arcpy.mapping.ListDataFrames(mxd, data_frame):           for lyr in arcpy.mapping.ListLayers(mxd, "", df):                if lyr.name.lower() == layer_name:                     print 'Replace layer ' + layer_name                     # 'wholesale' replace (not just the symbology)                     arcpy.mapping.UpdateLayer(df, lyr, sourceLayer, False)  mxd.save() del mxd print 'finished!' 


That should do it!  I set this up for 'wholesale' replacement of the layer -- replacing only the symbology (with the 4th param of UpdateLayer set to True) is trickier I think.  It's easier to simply replace the layer and be done with it -- and I think the processing time is equivalent.

The question came just in time - I was doing something very similar for my workplace....just finished testing a few command lines to make sure it works replacing a single layer in a single mxd and it works great.  So I just inserted the similar coding in your already existing looping code and cleaned it up a bit.  I didn't test this looping version so if it chokes up a bit, just let me know, and we'll fix it.

Enjoy,
Wayne

...one thing further:
I didn't mention this, but you could just as well update a layer with a layer from another map....just like in the samples from the webhelp.  The reason I used a layer file in the demo script above is because I need something similar - I distributed to the users in my organization a data reference by layer file - they each individually proceeded to add it as they saw fit to any of their maps.
Now, since moving to a new server, one of the things I did was provide a replacement layer to an image catalog for temporary access to 2012 orthophotos (that's another story) - my users are not yet keen on using what I call a 'layer library' to 'exchange' layers themselves (and some have very large mxds so wouldn't work so well anyway).  A script tool using the UpdateLayer function I am sending them along with a script tool to update their database connections fills the bill well.

View solution in original post

0 Kudos
5 Replies
T__WayneWhitley
Frequent Contributor
Do something like this (untested):
import arcpy, os, glob mxds_path = r'S:\\Users Shared\\LOpperman\\Town Scale MXDs\\MXDs\\targetlayers\\' layer_name = r'dams' data_frame = r'Primary'  # Say you want to replace the 'Dams' layer with an updated dams layer saved to a layer file. # ...in this case a 'source' layer object was created using lyr file stored outside the map document: # (The network folder 'LYRs' is fictitious...replace this pathname accordingly.) sourceLayer = arcpy.mapping.Layer(r'S:\\Users Shared\\LOpperman\\Town Scale MXDs\\LYRs\\Dams.lyr")  for infile in glob.glob(os.path.join( mxds_path, "*.mxd" )):      mxd = arcpy.mapping.MapDocument(infile)      print "replacing Dams layer from " + infile      for df in arcpy.mapping.ListDataFrames(mxd, data_frame):           for lyr in arcpy.mapping.ListLayers(mxd, "", df):                if lyr.name.lower() == layer_name:                     print 'Replace layer ' + layer_name                     # 'wholesale' replace (not just the symbology)                     arcpy.mapping.UpdateLayer(df, lyr, sourceLayer, False)  mxd.save() del mxd print 'finished!' 


That should do it!  I set this up for 'wholesale' replacement of the layer -- replacing only the symbology (with the 4th param of UpdateLayer set to True) is trickier I think.  It's easier to simply replace the layer and be done with it -- and I think the processing time is equivalent.

The question came just in time - I was doing something very similar for my workplace....just finished testing a few command lines to make sure it works replacing a single layer in a single mxd and it works great.  So I just inserted the similar coding in your already existing looping code and cleaned it up a bit.  I didn't test this looping version so if it chokes up a bit, just let me know, and we'll fix it.

Enjoy,
Wayne

...one thing further:
I didn't mention this, but you could just as well update a layer with a layer from another map....just like in the samples from the webhelp.  The reason I used a layer file in the demo script above is because I need something similar - I distributed to the users in my organization a data reference by layer file - they each individually proceeded to add it as they saw fit to any of their maps.
Now, since moving to a new server, one of the things I did was provide a replacement layer to an image catalog for temporary access to 2012 orthophotos (that's another story) - my users are not yet keen on using what I call a 'layer library' to 'exchange' layers themselves (and some have very large mxds so wouldn't work so well anyway).  A script tool using the UpdateLayer function I am sending them along with a script tool to update their database connections fills the bill well.
0 Kudos
T__WayneWhitley
Frequent Contributor
Thanks Ken for pointing that out - there is a double-quote error on the line to set the sourceLayer var, so substitute this line (or find/replace with a single-quote):
sourceLayer = arcpy.mapping.Layer(r'S:\\Users Shared\\LOpperman\\Town Scale MXDs\\LYRs\\Dams.lyr')


...why you should test the code you post, lol!


Enjoy,
Wayne
0 Kudos
KenLucas
Occasional Contributor
Wayne,
  I must have tried every punctuation change I could think of, before giving up. That small change made the script work. This teaches me that error could be in the sentence above the sentence that gets highlited in IDLE, when the script fails. Thank you so much the major re write of the sample code. I can now modify almost a hundred mxds. You're a handy pal to have!
Ken
0 Kudos
KenLucas
Occasional Contributor
Wayne,
  I must have tried every punctuation change I could think of, before giving up. That small change made the script work. This teaches me that error could be in the sentence above the sentence that gets highlited in IDLE, when the script fails. Thank you so much the major re write of the sample code. I can now modify almost a hundred mxds. You're a handy pal to have!
Ken
0 Kudos
T__WayneWhitley
Frequent Contributor
Seriously?...you must have meant minor change with major impact.  See, that's why I like so much to write code - it is just a little work where a minor tweak here or there can make all the difference between running or not running.

Glad it works!....now if only everything would work half as well as that!!...I just don't always see it as soon as I'd like, but hey, it's satisfying when it works out.

Just keep slogging forward, leaping forward, or whatever you have to do, just shift into forward gear, lol!
Hey, have a great weekend.

Enjoy,
Wayne
0 Kudos