1

I'm working on 24 MXD files. Several maps include "roads" layer in them, the other maps don't have this layer. I'm trying to add "roads" layer to all the maps that do not have this layer by using this code:

import arcpy,os,sys,fnmatch
from arcpy import env

env.workspace = r"G:\desktop\Project"
insertLayer = arcpy.mapping.Layer(r"G:\desktop\Project\layers\roads.lyr")
counter = 0 

for mxdname in arcpy.ListFiles("*.mxd"):
    print mxdname 
    mxd = arcpy.mapping.MapDocument(r"G:\desktop\Project\\" + mxdname)
    df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
    refLayer = arcpy.mapping.ListLayers(mxd, "residence", df)[0]
for lyr in arcpy.mapping.ListLayers(mxd, "" ,df):
    if 'roads' not in lyr:  
        arcpy.mapping.InsertLayer(df, refLayer, insertLayer, "BEFORE") # BEFORE\ AFTER
mxd.save()
counter = counter + 1

del mxd 
print counter

and this is the error i get:

 >>> 
landUse.mxd
Traceback (most recent call last):
  File "G:/desktop/y/yaron/shonot/software/---gis---/tools/YARON_SCRIPTS/aaaaaaaaaaaaaaaaa.py", line 18, in <module>
if 'roads' not in lyr:
  File "C:\Program Files (x86)\ArcGIS\Desktop10.3\ArcPy\arcpy\arcobjects\mixins.py", line 361, in __iter__
self.layers
AttributeError: LayerObject: Get attribute layers does not exist
>>> 

UPDATE:

I added this code line:

  if 'roads' not in lyr.name:

and now 'roads' layer has been added several times (each map) to all maps no matter if they contain 'roads' layer or not.

  • 3
    Maybe its just to text formatting in your question but shouldn't the second 'for' loop be inside the first? – Dowlers May 10 '16 at 14:15
  • how do i do it? – newGIS May 11 '16 at 6:22
3

Rather than looping through the layers, you can use python's filter function to determine if the roads layer is present.

So, replace

for lyr in arcpy.mapping.ListLayers(mxd, "" ,df):
if 'roads' not in lyr:  
    arcpy.mapping.InsertLayer(df, refLayer, insertLayer, "BEFORE") # BEFORE\ AFTER

with

if not filter(lambda x: 'roads' in x.name, arcpy.mapping.ListLayers(mxd, "" ,df)):  
    arcpy.mapping.InsertLayer(df, refLayer, insertLayer, "BEFORE") # BEFORE\ AFTER

Update: If you don't want to use lambdas, you can set a flag in the loop then insert the layer afterwards

has_roads = False
for lyr in arcpy.mapping.ListLayers(mxd, "" ,df):
    if 'roads' in lyr.name:
        has_roads = True
if not has_roads:
    arcpy.mapping.InsertLayer(df, refLayer, insertLayer, "BEFORE") # BEFORE\ AFTER
  • jon_two i didn't understand your code but it works, thanks. I would like to know if i can do it with my code , without lambda, is there another way?, is it possible? – newGIS May 11 '16 at 6:02
  • Filter [docs.python.org/2/library/functions.html#filter] returns an array of everything that matches the function in the first argument. The lambda here goes through everything in the second argument, checking the name property. – jon_two May 11 '16 at 8:26
  • Yes, I was just thinking this morning that you can use a boolean flag to show the road layer is present. See edit above. – jon_two May 11 '16 at 8:30
  • thanks jon_two-the code works exect i added change: "if 'roads' in lyr.name:" as PolyGeo said – newGIS May 15 '16 at 6:52
  • 1
    @newGIS oops, you're right. Corrected it now. – jon_two May 16 '16 at 10:02
4

Your variable lyr is a layer object and not a string or list of strings.

Consequently, to avoid that error you need to replace:

if 'roads' not in lyr:

with

if 'roads' not in lyr.name:
  • now, 'roads' layer add 4 times to all the maps – newGIS May 10 '16 at 12:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.