Select to view content in your preferred language

how to insert a layer to multiple mxds

2584
9
01-10-2013 04:55 PM
KenLucas
Occasional Contributor
I'd like to insert or add a single .lyr feature into the first data frame of each of two mxds,  named "One" & "Two", both stored in the same folder. Each mxd has two data frames, "Layers1" & "Layers2". The layer feature I want to insert is called "new".lyr   I've checked the arcpy site package for sample code and read a lot of the old python threads and can't find the code to set a variable "mxd" = multiple mxds
I also don't know the code to save the two mxds after the new layer has been added.
Ken
Tags (2)
0 Kudos
9 Replies
ArkadiuszMatoszka
Occasional Contributor II
Hi,
Do you have to add to both mxds at the same time. Easiest way would be iteration over mxd files and addin lyr to one document at time (as below)
Cheers
Arek
import arcpy
add_layer = arcpy.mapping.Layer('C:\\Path\\to\\lyrfile.lyr')
mxds_path = 'c:\\path\\to\\mxds\\'
mxds = ['one.mxd', 'two.mxd']
for mxd_name in mxds:
  mxd = arcpy.mapping.MapDocument(mxds_path + mxd_name)
  df = arcpy.mapping.ListDataFrames(mxd, 'Layers1')[0]
  arcpy.mapping.AddLayer(df, addLayer, "TOP")
  mxd.save()
0 Kudos
KenLucas
Occasional Contributor
Arek, 
  Thanks so much for trying to help me.
   I modified your code to insert the paths and change the names.  How should I correct this code to get the script to work.  After a lot of trial and error I still get an "Invalid MXD filename" error
import arcpy
add_layer = arcpy.mapping.Layer('C:\Temp2\Dams.lyr')
mxds_path = ('c:\Temp2')
mxds = ('T1.mxd', 'T2.mxd')
for mxd_name in mxds:
  mxd = arcpy.mapping.MapDocument(mxds_path + mxd_name)
  df = arcpy.mapping.ListDataFrames(mxd, "Layers1")[0]
  arcpy.mapping.AddLayer(df, addLayer, "TOP")
  mxd.save()

Ken
0 Kudos
ArkadiuszMatoszka
Occasional Contributor II
Use double backslashes ("\\") in paths (ie. on add_layer)  instead of single ones, also mxds_path should be 'c:\\Temp2\\', not ('c:\Temp2') - no parenthesis, '\\' at end of string.
That should do.
Regards.
Arek
0 Kudos
KenLucas
Occasional Contributor
Arek,
  It took another full hour of trial and error, after recieving your last thread, but I fianally got your sample code to work. It turns out that the script has to be saved to, and run, from a diff folder; I've always ran script from the same folder. Even with researching the the arcgis help I would not have been able to Addlayer to multiple mxds without your kindness and patience helping me. Thanks so much.
Ken
0 Kudos
TomMagdaleno
Regular Contributor
Good thread.  Is their an easy way to do this where you want to do it to all MXDs in a folder?
0 Kudos
JohnDye
Regular Contributor
Good thread.  Is their an easy way to do this where you want to do it to all MXDs in a folder?


Sure, you could just modify the existing code with the listfiles() function and leverage the wildcard argument to identify MXDs in a given folder.

# Import the arcpy module
import arcpy
# Identify the path to the Layer File you want to insert on disk.
InsertLayer = arcpy.mapping.layer(r"C:\MyGIS\Layers\TheLayerFileToInsert.lyr")
# Identify the Folder containing the MXDs you want to insert the 'InsertLayer' into
MXDsFolder = r"C:\MyGIS\MXDsFolder"
# Set the Environment Workspace to the MXDs Folder so that the 'ListFiles()'
# function will search this folder for MXDs when called
arcpy.env.workspace = MXDsFolder
# Call the 'arcpy.ListFiles()' function and invoke the wildcard parameter to only 
# return MXDs from the folder. Populate the results in the variable 'MXDsList'
MXDsList = arcpy.ListFiles("*.mxd")
# Loop through each MXD in the 'MXDsList'
for MXD in MXDsList:
    # Establish the current MXD as the 'TargetMXD' to insert the Layer into
    TargetMXD = arcpy.mapping.MapDocument(MXDsFolder + "\\" + str(MXD))
    # Get a reference to the first dataframe in the Target MXD
    TargetDF = arcpy.mapping.ListDataFrames(TargetMXD)[0]
    # Add the Layer to the TargetMXD
    arcpy.mapping.AddLayer(TargetDF, InsertLayer, "TOP")
    # Save the MXD
    TargetMXD.save()
print "Complete"
0 Kudos
TomMagdaleno
Regular Contributor
Awesome!  Thank you John Dye! 
Is their a way to batch "Repair data sources" and point everything to one geodatabase and let it find the right feature?  Somehow the path to my geodatabase got jumbled.  I tried to do it here
import arcpy, os
folderPath = r"C:\\01Working_Directory\\LandscapeMaps"
# Set the Environment Workspace to the MXDs Folder so that the 'ListFiles()'
# function will search this folder for MXDs when called
arcpy.env.workspace = folderPath
# Call the 'arcpy.ListFiles()' function and invoke the wildcard parameter to only 
# return MXDs from the folder. Populate the results in the variable 'MXDsList'
MXDsList = arcpy.ListFiles("*.mxd")
# Loop through each MXD in the 'MXDsList'
for MXD in MXDsList:
    # Establish the current MXD as the 'TargetMXD' to insert the Layer into
    TargetMXD = arcpy.mapping.MapDocument(folderPath + "\\" + str(MXD))
for filename in os.listdir(folderPath):
 fullpath = os.path.join(folderPath, filename)
 if os.path.isfile(fullpath):
  basename, extension = os.path.splitext(fullpath)
 if extension.lower() == ".mxd":
  mxd = arcpy.mapping.MapDocument(fullpath)
mxd.findAndReplaceWorkspacePaths(r"c:\01Working_Directory\LandscapeMaps\LandscapeDistrict.gdb", r"G:\CamarilloGIS\Projects\PublicWorks\STREETS\Landscape Districts\LandscapeDistricts.gdb")
TargetMXD.save()
print "All Repathed!"


I get this error
Traceback (most recent call last):
  File "C:/01Working_Directory/Python/RepathToolLoop.py", line 20, in <module>
    mxd = arcpy.mapping.MapDocument(fullpath)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.2\arcpy\arcpy\arcobjects\mixins.py", line 609, in __init__
    assert (os.path.isfile(mxd) or (mxd.lower() == "current")), gp.getIDMessage(89004, "Invalid MXD filename")
AssertionError: Invalid MXD filename.
Any ideas?
0 Kudos
JohnDye
Regular Contributor
The first problem I see here is that you are using double backslashes inside of a raw string literal. A raw string literal is the exact string written inside of quotes when prefaced with an 'r'.

When you specify a path with as a raw string literal, you don't need the double-backslashes because python is going to use the exact string specified within the quotes. Just use a single backslash, the same as you would in Windows to navigate to a specific path. For me, this is why I always specify a path as a raw string literal. I can use the same formatting to define a path as Windows.

If you don't use the raw string literal prefix (r), then you do need to use double-backslashes because a single backslash is an escape in python. If you use a single backslash without the raw string literal prefix,  you will likely end up escaping some of the characters in your path.

As a result of having those double-backslashes inside of a raw string literal, when you perform the 'os.path.join()' function, the return contains an excessive number of backslashes.

Take this example:
>>> folderPath = r"C:\\01Working_Directory\\LandscapeMaps"
>>> file = "MyGISFile"
>>> os.path.join(folderPath, file)
'C:\\\\01Working_Directory\\\\LandscapeMaps\\MyGISFile'
>>>

That's a lot of backslashes. The last part where the file was joined to the folderPath is ok because the 'os.path.join()' inserted the appropriate seperator when executing the join. Replacing the double-backslashes in your 'folderPath' variable with single backslashes should resolve the issue.

In regards to fixing your broken data sources, it is completely possible. You already know how to loop through a list of MXDs, so now it's just a matter of invoking the appropriate functions to list the broken data sources, loop through that list and replace their data sources. Take a look at this help article. It should point you in the right direction.
0 Kudos
CarolinaDByl
New Contributor II

Hi! Is there a way to insert the feature layers from a gdb with a specific formatting, using as a base the code that TomMagdaleno used? I'm in ArcMap 10.8. Maybe there is something I can fix in the feature layers in the gdb so they always are added with the same specific format. Thanks in advance!

0 Kudos