Python UpdateLayer works in V10 but not in 10.1

996
12
Jump to solution
10-17-2012 10:48 AM
DaveJordan1
New Contributor III
I have a script written in v10 that compiles a series of maps and mailing labels based on a buffered distance around a parcel.  The script runs fine in V10.  In V10.1 it runs without error but does not symbolize correctly based on a layer files, specifically using UpdateLayer.  After UpdateLayer is processed, the screen refreshes but the symbols set in the layer file do not get processed. 

What has changed in 10.1 that would cause this?
Has anyone else come across this issue?

Here is an example that I copied from the python window in trying to emulate the script.  It does not apply the symbology either:

>>> SubjectLyr = arcpy.mapping.Layer("Y:\Notification Radius Pkgs\Dave3\Shapefiles\Dave3Subject.shp")
>>> mxd = arcpy.mapping.MapDocument("Current")
>>> df = arcpy.mapping.ListDataFrames(mxd, "Radius Map")[0]
>>> wPath = "Y:\Notification Radius Pkgs\\"
>>> arcpy.mapping.AddLayer(df, SubjectLyr,"AUTO_ARRANGE")
>>> sourceLayer = arcpy.mapping.Layer(wPath+"Setup10\LayerFiles\Subject.lyr")
>>> arcpy.mapping.UpdateLayer(df, SubjectLyr, sourceLayer, True)
>>>
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
ArkadiuszMatoszka
Occasional Contributor II
Sorry I missed one thing in my code.
Error is caused by list as argument, simple correction should help. Script will work, as long as layer names in data frame will be unique.
Try this one:
1>>> SubjectLyr = arcpy.mapping.Layer("Y:\\Notification Radius Pkgs\\Dave3\\Shapefiles\\Dave3Subject.shp") # use either \\ or / in paths 2>>> mxd = arcpy.mapping.MapDocument("CURRENT") 3>>> df = arcpy.mapping.ListDataFrames(mxd, "Radius Map")[0]  4>>> wPath = "Y:\\Notification Radius Pkgs\\" # same as in line 1 5>>> arcpy.mapping.AddLayer(df, SubjectLyr,"AUTO_ARRANGE")  6>>> SubjectLyr = arcpy.mapping.ListLayers(mxd, SubjectLyr.name, df)[0] # change reference to layer in mxd 7>>> sourceLayer = arcpy.mapping.Layer(wPath+"Setup10\\LayerFiles\\Subject.lyr") # same as in line 1 8>>> arcpy.mapping.UpdateLayer(df, SubjectLyr, sourceLayer, True)

View solution in original post

0 Kudos
12 Replies
ArkadiuszMatoszka
Occasional Contributor II
Hi,
Firstly use \\ or / to separate path. Also after adding layer to map document you have to change reference to this layer (layer on disk and in map document is not the same layer!)
Below your code with some changes that make it work:
1>>> SubjectLyr = arcpy.mapping.Layer("Y:\\Notification Radius Pkgs\\Dave3\\Shapefiles\\Dave3Subject.shp") # use either \\ or / in paths
2>>> mxd = arcpy.mapping.MapDocument("CURRENT")
3>>> df = arcpy.mapping.ListDataFrames(mxd, "Radius Map")[0] 
4>>> wPath = "Y:\\Notification Radius Pkgs\\" # same as in line 1
5>>> arcpy.mapping.AddLayer(df, SubjectLyr,"AUTO_ARRANGE") 
6>>> SubjectLyr = arcpy.mapping.ListLayers(mxd, SubjectLyr.name, df) # change reference to layer in mxd
7>>> sourceLayer = arcpy.mapping.Layer(wPath+"Setup10\\LayerFiles\\Subject.lyr")[0] # same as in line 1
8>>> arcpy.mapping.UpdateLayer(df, SubjectLyr, sourceLayer, True)


Cheers
Arek
0 Kudos
DaveJordan1
New Contributor III
Arek, Thank you for taking the time to reply.  nfortuneatley, I was not successfull in getting yuor sample to work.  I believe it is because ListLayer returns a list of layers rather than a layer. here is what I am getting:

>>> SubjectLyr = arcpy.mapping.Layer("Y:\\Notification Radius Pkgs\\Dave3\\Shapefiles\\Dave3Subject.shp")
>>> mxd = arcpy.mapping.MapDocument("CURRENT")
>>> df = arcpy.mapping.ListDataFrames(mxd, "Radius Map")[0]
>>> wPath = "Y:\\Notification Radius Pkgs\\"
>>> arcpy.mapping.AddLayer(df, SubjectLyr,"AUTO_ARRANGE") 
>>> SubjectLyr = arcpy.mapping.ListLayers(mxd, SubjectLyr.name, df)
>>> sourceLayer = arcpy.mapping.Layer(wPath+"Setup10\\LayerFiles\\Subject.lyr")[0]
Runtime error 
Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: 'Layer' object does not support indexing
#####Okay - get rid of the index
>>> sourceLayer = arcpy.mapping.Layer(wPath+"Setup10\\LayerFiles\\Subject.lyr")
>>> arcpy.mapping.UpdateLayer(df, SubjectLyr, sourceLayer, True)
Runtime error 
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "c:\program files (x86)\arcgis\desktop10.1\arcpy\arcpy\utils.py", line 181, in fn_
    return fn(*args, **kw)
  File "c:\program files (x86)\arcgis\desktop10.1\arcpy\arcpy\mapping.py", line 1868, in UpdateLayer
    assert isinstance(update_layer, Layer)
AssertionError
>>> arcpy.mapping.Layer(wPath+"Setup10\LayerFiles\Subject.lyr")
<map layer u'Dave502Subject'>
>>> arcpy.mapping.UpdateLayer(df, SubjectLyr, sourceLayer, True)
Runtime error 
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "c:\program files (x86)\arcgis\desktop10.1\arcpy\arcpy\utils.py", line 181, in fn_
    return fn(*args, **kw)
  File "c:\program files (x86)\arcgis\desktop10.1\arcpy\arcpy\mapping.py", line 1868, in UpdateLayer
    assert isinstance(update_layer, Layer)
AssertionError
####What are the values of the variables?
>>> print SubjectLyr
[<map layer u'Dave3Subject'>]
>>> print sourceLayer
Dave502Subject


ESRI support is telling me that this issue may be a bug in v10.1  They gave me a work-around, but I haven't tested it yet.  I will test it and report the results here.
0 Kudos
ArkadiuszMatoszka
Occasional Contributor II
Sorry I missed one thing in my code.
Error is caused by list as argument, simple correction should help. Script will work, as long as layer names in data frame will be unique.
Try this one:
1>>> SubjectLyr = arcpy.mapping.Layer("Y:\\Notification Radius Pkgs\\Dave3\\Shapefiles\\Dave3Subject.shp") # use either \\ or / in paths 2>>> mxd = arcpy.mapping.MapDocument("CURRENT") 3>>> df = arcpy.mapping.ListDataFrames(mxd, "Radius Map")[0]  4>>> wPath = "Y:\\Notification Radius Pkgs\\" # same as in line 1 5>>> arcpy.mapping.AddLayer(df, SubjectLyr,"AUTO_ARRANGE")  6>>> SubjectLyr = arcpy.mapping.ListLayers(mxd, SubjectLyr.name, df)[0] # change reference to layer in mxd 7>>> sourceLayer = arcpy.mapping.Layer(wPath+"Setup10\\LayerFiles\\Subject.lyr") # same as in line 1 8>>> arcpy.mapping.UpdateLayer(df, SubjectLyr, sourceLayer, True)
0 Kudos
JeffBarrette
Esri Regular Contributor
This is a known issue:
NIM085743 - UpdateLayer will not update symbology if the source layer object is not in the map.

We will address it in a future service pack.

Thanks,
Jeff
0 Kudos
DaveJordan1
New Contributor III
Yes it is known issue, However, Arek's reply above works for those that can not wait for the the next service pack or are looking for an alternative.

Thanks Arek - you just made my day!

Here is the response that I received from ESRI support which conincides with Areks solution exactly:

Hi Dave,

I have verified this and logged it as an equivalency bug: [#NIM085743  UpdateLayer will not update symbology if the source layer object is not in the map]. What I found is that if you add the layers to the map, then grab the layer object and set that equal to your subject and source variables, then this seems to work. The issue appears to be with pointing to an external layer/shp file. I will test this a bit, but you may need to set your variable equal to arcpy.mapping.ListLayers and use a wildcard to get the layer you add to the map. You can then use that variable in the UpdateLayer tool. I'll test this some more and let you know exactly what I can find. Thanks for your patience with this Dave.
0 Kudos
DaveJordan1
New Contributor III
Another solution reccomended by support is to use arcpy.ApplySymbologyFromLayer_management("Subject", "Source")  I haven't tried it myself as Arek's solution is working...
0 Kudos
JeffBarrette
Esri Regular Contributor
After further evaluation, there is an error in the original code - it is easy to miss. The Layer function is being used to reference a feature class on disk, not a layer file. It is documented that the Layer function is for referencing layer files. The bug is that an error should have been thrown. It should not have worked in 10.0.

Original code:
SubjectLyr = arcpy.mapping.Layer("Y:\Notification Radius Pkgs\Dave3\Shapefiles\Dave3Subject.shp")
mxd = arcpy.mapping.MapDocument("Current")
df = arcpy.mapping.ListDataFrames(mxd, "Radius Map")[0] 
wPath = "Y:\Notification Radius Pkgs\\"
arcpy.mapping.AddLayer(df, SubjectLyr,"AUTO_ARRANGE") 
sourceLayer = arcpy.mapping.Layer(wPath+"Setup10\LayerFiles\Subject.lyr")
arcpy.mapping.UpdateLayer(df, SubjectLyr, sourceLayer, True)


Thanks,
Jeff
0 Kudos
DaveJordan1
New Contributor III
Thanks Jeff,

Can you provide me a sample of how I should have approached this? This was one of the first things i tried sorting out when I first started in Python. Somewhere after this interesting post Managing-Symbology-using-Python I guess I bastardized it and made it work... I guess I assumed that the AddLayer call changed the reference to a layer.

SubjectLyr = arcpy.mapping.Layer("Y:\Notification Radius Pkgs\Dave3\Shapefiles\Dave3Subject.shp")
mxd = arcpy.mapping.MapDocument("Current")
df = arcpy.mapping.ListDataFrames(mxd, "Radius Map")[0] 
wPath = "Y:\Notification Radius Pkgs\\"
arcpy.mapping.AddLayer(df, SubjectLyr,"AUTO_ARRANGE") 
sourceLayer = arcpy.mapping.Layer(wPath+"Setup10\LayerFiles\Subject.lyr")
arcpy.mapping.UpdateLayer(df, SubjectLyr, sourceLayer, True)
0 Kudos
JeffBarrette
Esri Regular Contributor
Dave,

Again in your most recent post, you are referencing a shapefile via the Layer function.  You must reference a layer file. 

To fix this, add your shapefile into ArcMap, symboloize it however and then save out to a layer file (*.lyr).  Then replace the path to the shapefile with the path to the lyr file.

UpdateLayer will update all layer properties, including dataSource, if your set symbology_only=False.

Jeff
0 Kudos