UpdateLayer Not Showing Changes in TOC or ActiveView

640
5
Jump to solution
06-05-2014 10:02 AM
JonathanMulder
New Contributor III
Greetings,

I've been wrestling with this for most of the day and am flummoxed!

I am going through a "For Loop" adding 5 (ultimately will be ~150 after testing) feature classes in a Feature Dataset (named "GroundwaterBasins") in a geodatabase, and trying to change the symbology for each dataset based upon a layer file that I have already saved ("PORSymbologyLayer").  I have inserted "arcpy.RefreshTOC" and "arcpy.RefreshActiveView".  I've even broken it down into two "For Loops (one for adding the
feature class, and one for changing the symbology).  I've even tried "ApplySymbologyFromLayer_mangement" which also doesn't change the symbology.

Can anyone see what I'm doing wrong?

Thanks,
Jonathan Mulder
Engineering Geologist
California Department of Water Resources

##Reference the Current map document. mxd = arcpy.mapping.MapDocument("CURRENT") df = arcpy.mapping.ListDataFrames(mxd)[0]  arcpy.env.workspace = os.path.join(GeoDatabaseNameAndLocation,"GroundwaterBasins") CurrentWorkspacePath = os.path.join(GeoDatabaseNameAndLocation,"GroundwaterBasins") PORSymbologyLayer = arcpy.mapping.Layer(os.path.join(GeoDatabaseLocation,"GIS","PeriodOfRecord.lyr")) arcpy.AddMessage(PORSymbologyLayer) BasinList = arcpy.ListFeatureClasses("*") arcpy.AddMessage(BasinList) for Basin in BasinList:     BasinFeatureClass = arcpy.mapping.Layer(Basin)     arcpy.AddMessage(BasinFeatureClass)     arcpy.mapping.AddLayer(df, BasinFeatureClass, "TOP")     arcpy.RefreshTOC()     arcpy.RefreshActiveView()  for Basin in BasinList:     BasinFeatureClass = arcpy.mapping.Layer(Basin) ##    arcpy.ApplySymbologyFromLayer_management (BasinFeatureClass, PORSymbologyLayer)     arcpy.mapping.UpdateLayer(df,BasinFeatureClass,PORSymbologyLayer)     arcpy.RefreshTOC()     arcpy.RefreshActiveView()
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
T__WayneWhitley
Frequent Contributor
Hello Jon-

That's because ListLayers returns a list of Layer objects, so you don't need to try to 'reinstantiate' it as that kind of object - you should be able to do this (provided there's actually a return from ListLayers):

BasinLayersInMap = arcpy.mapping.ListLayers(mxd,"*",df) arcpy.AddMessage(BasinLayersInMap) for Basin in BasinLayersInMap:     arcpy.mapping.UpdateLayer(df, Basin, PORSymbologyLayer,"TRUE")     arcpy.RefreshTOC()     arcpy.RefreshActiveView()


-Wayne

View solution in original post

0 Kudos
5 Replies
markdenil
Occasional Contributor III
It looks like when you go to update the symbolization
(I hate that awful word: "symbology". ugh. It is neither a science nor a religion... anyway...)
you are not operating on the ArcMap layers you just added.

Instead, you are again looping through BasinList
BasinList is a list of feature classes on disk
even though you again make layers from the FCs,
they are NOT the layers in your ArcMap data frame.

For your symbolization loop, start with a new list of layers in the data frame,
using: ListLayers (map_document_or_layer, {wildcard}, {data_frame})
This list will contain the objects you need to update.

Then, when you do the
arcpy.mapping.UpdateLayer(df,BasinFeatureClass,PORSymbologyLayer)
make it
arcpy.mapping.UpdateLayer(df,BasinFeatureClass,PORSymbologyLayer, True)

Yes, the default is True, but, as it says in the Zen of Python (>>> import this):
Explicit is better than implicit.
0 Kudos
JonathanMulder
New Contributor III
Thanks very much for your response.  I should have realize that I need to list the layers in the map, not the Feature Classes.

So, I've modified my code as follows, but it crashes on line 33 ("  BasinLayer = arcpy.mapping.Layer(Basin)
").

Any idea why?

Jon Mulder

import arcpy
import arcpy.mapping
import datetime
import os


arcpy.env.overwriteOutput = True
GeoDatabaseNameAndLocation = "G:\MaxtorDrive\GroundwaterDatabases\GWIDS\GroundwaterBasinOverdraftAnalysis.gdb"


GeoDatabaseName = os.path.basename(GeoDatabaseNameAndLocation)
GeoDatabaseLocation = os.path.dirname(GeoDatabaseNameAndLocation)

##Reference the Current map document.
mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd)[0]

arcpy.env.workspace = os.path.join(GeoDatabaseNameAndLocation,"GroundwaterBasins")
CurrentWorkspacePath = os.path.join(GeoDatabaseNameAndLocation,"GroundwaterBasins")
PORSymbologyLayer = arcpy.mapping.Layer(os.path.join(GeoDatabaseLocation,"GIS","PeriodOfRecord.lyr"))
arcpy.AddMessage(PORSymbologyLayer)
BasinList = arcpy.ListFeatureClasses("*")
arcpy.AddMessage(BasinList)
for Basin in BasinList:
    BasinFeatureClass = arcpy.mapping.Layer(Basin)
    arcpy.AddMessage(BasinFeatureClass)
    arcpy.mapping.AddLayer(df, BasinFeatureClass, "TOP")

#Create list of Basin Layer in map.
BasinLayersInMap = arcpy.mapping.ListLayers(mxd,"*",df)
arcpy.AddMessage(BasinLayersInMap)
for Basin in BasinLayersInMap:
    BasinLayer = arcpy.mapping.Layer(Basin)
    arcpy.mapping.UpdateLayer(df,BasinLayer,PORSymbologyLayer,"TRUE")
    arcpy.RefreshTOC()
    arcpy.RefreshActiveView()
0 Kudos
T__WayneWhitley
Frequent Contributor
Hello Jon-

That's because ListLayers returns a list of Layer objects, so you don't need to try to 'reinstantiate' it as that kind of object - you should be able to do this (provided there's actually a return from ListLayers):

BasinLayersInMap = arcpy.mapping.ListLayers(mxd,"*",df) arcpy.AddMessage(BasinLayersInMap) for Basin in BasinLayersInMap:     arcpy.mapping.UpdateLayer(df, Basin, PORSymbologyLayer,"TRUE")     arcpy.RefreshTOC()     arcpy.RefreshActiveView()


-Wayne
0 Kudos
JonathanMulder
New Contributor III
That did the trick, Wayne!  Thanks very much!

Jon Mulder
0 Kudos
T__WayneWhitley
Frequent Contributor
Jon, since you said you'll be executing this on quite a few more layers (150+ ?), I'd like to suggest 'combining' your for loops into this one (I didn't test this) in the interest of efficiency (if it works):
for Basin in BasinList:
    BasinFeatureClass = arcpy.mapping.Layer(Basin)
    arcpy.AddMessage(BasinFeatureClass)
    arcpy.mapping.UpdateLayer(df,BasinFeatureClass,PORSymbologyLayer,"TRUE")
    arcpy.mapping.AddLayer(df, BasinFeatureClass, "TOP")
    arcpy.RefreshTOC()
    arcpy.RefreshActiveView()


I'm not sure if UpdateLayer output is auto-added to the map; if so, you don't need AddLayer.
Also, if you'd like to award Mark something for his contribution, he probably deserves it -- I just came in on this at the tail end...

-Wayne


PS- Agreed, Mark, ha ha:
"Yes, the default is True, but, as it says in the Zen of Python (>>> import this):
Explicit is better than implicit."

For anyone who hasn't seen the printout of Zen of Python, enter import this at the python command prompt.
0 Kudos