arcpy get the style item details from a legend item

2923
9
Jump to solution
11-29-2016 11:27 AM
NatashaJurko
New Contributor III

Hi everybody,

Working with ArcGIS 10.4, ArcInfo Licence

I am writing an arcpy script to set up a process for map automation.   The user will design a map layout how they like and then use that layout to iterate through a list of rasters and export to pdf.   I have pre-programmed certain text elements and one legend element to be dynamic and change as the rasters are added/removed from the layout.

My issue is with the legend element and style item.  The user will add a legend and determine the item style of the raster layer using the legend wizard.  I'd like my arcpy script to read what that style item type is and apply it to the next raster that is added to the map.    I've been searching for ideas on how to 'describe' or 'get' the style item, but I can't find and arcpy method (and I'm way too novice to figure out the pure python way).   I think I have to read the style item path name. I assume the information I need is floating around there somewhere because the legend wizard needs to know what the file path is rights?!

Does anyone have an idea of where to find an answer of what type of command I'm looking for?  (even a search keyword would be useful!)

Below is a snippet of my script combined with how I want it to work (legend style item file variable).  Also included is a screenshot of the tool and the map layout with the dynamic elements.  These are works in progress!

Thanks,

Natasha

import arcpy
from arcpy import env
import arcpy.mapping as mp

# This is part of my script... I am envisioning something like.....

mxd = arcpy.mapping.MapDocument("CURRENT")

df = arcpy.mapping.ListDataFrames(mxd)[0]

legendItemStyleFile = #This is where I want to 'get' the style path 
                      # currently in use by the item already in my legend.

# Do some stuff here to add the rasters in my Raster List, 
# and to make a map based only on the rasters in the Raster List.

for raster in rasterFileName:
    rasterLayer = mp.Layer(raster)
    rasterLayer.visible = True
    rasterSplit = re.split("[.,_?:]+", str(raster))

    rasterFWI = rasterSplit[0]
    rasterDate = rasterSplit[1]
    rasterFileType = rasterSplit[2]
    
    #Changes the date label if the boolean is true
    if labelDate == 'true':

        arcpy.AddMessage("layer date: " + rasterDate)
        #Date Text Element Change
        textDate = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "textDate")[0]
        textDate.text = rasterDate
        #arcpy.AddMessage(compareRaster)
   
    #Changes the header label if the boolean is true
    if labelHeader == 'true':
        textHeader = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "textHeader")[0]
        textHeader.text = rasterFWI.upper()
    
    #Update the legend item with the style from my original raster (legendItemStyleFile variable).  
    legend = arcpy.mapping.ListLayoutElements(mxd, "LEGEND_ELEMENT")[0]
    styleItem = arcpy.mapping.ListStyleItems("USER_STYLE", "Legend Items", legendItemStyleFile)[0]
 
    legend.updateItem(lyr, styleItem)

    #*** still have to write the export, turn off raster and turn on the next part of this script...


    arcpy.RefreshTOC()
    arcpy.RefreshActiveView()
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

0 Kudos
1 Solution

Accepted Solutions
LukeWebb
Occasional Contributor III

I dont think we can use style manager within Arcpy.  

I have tested "Layer.replacedatasource" and it appears to retain the styles!

Take a copy of the layer the user set up in the mxd.   (ARRRG the copy doesnt retain styles! So skip this step)

update its data source

update any symbology as required

then remove the template.      (This step no longer exists due to the ARRG caveat above)

View solution in original post

9 Replies
LukeWebb
Occasional Contributor III

I think this should work for rasters, it works for FCs:

import arcpy

mxd = arcpy.mapping.MapDocument("CURRENT")
lyr_with_source_symbology = arcpy.mapping.ListLayers(mxd,'Name Of The Source Layer in the mxd')[0]
layer_to_symbolise = arcpy.mapping.ListLayers(mxd,'Name of the Target layer in the mxd again')[0]

arcpy.ApplySymbologyFromLayer_management(layer_to_symbolise,lyr_with_source_symbology)‍‍‍‍‍‍‍‍‍‍‍‍‍‍
















#Version 2, that hints at how to deal with your specific workflow:


import arcpy

mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd, "*")[0]
lyr_with_source_symbology = arcpy.mapping.ListLayers(mxd,'Name Of The Source Layer in the mxd')[0]

addLayer = arcpy.mapping.Layer(r"path_to_the_new_raster")
arcpy.ApplySymbologyFromLayer_management(addLayer, lyr_with_source_symbology)‍‍‍‍‍‍‍‍‍‍‍‍‍‍
arcpy.mapping.AddLayer(df, addLayer, "BOTTOM")
arcpy.mapping.RemoveLayer(df, lyr_with_source_symbology)


FC_Basson
MVP Regular Contributor

It works.

0 Kudos
NatashaJurko
New Contributor III

Thanks for replying. Applying symbology layers is working okay, that is not an issue... apologies for not being clear!

The roadblock I'm facing is with the Legend Element and adding raster layers to the legend with specific legend styles.  I think with the Style Manager and StyleItem part of the arcpy mapping module.  

I want my script to determine what style is in use by the current raster item in the legend.... save that style.... remove the item from the legend....add a different item to the legend.... implement the same style as the previous item.

Here is an example::

This is my legend formatted how I want (only label showing).  

After adding a different layer to the legend, the arcmap default style is used (with layer name, header and label).

                

0 Kudos
LukeWebb
Occasional Contributor III

Is the style in the legend not the same as a layer in the map?

The legend is just a representation of this layers properties, we work in layers within arcpy. 

EDIT - OK I understand! I was worried about the display symbologys and 'values' becoming incorrect, you are worried about only the visual display of the legend item! 

0 Kudos
LukeWebb
Occasional Contributor III

Possible alternative,  setup your map with the right "Style" using any raster....then make your code:

layer.replaceDataSource()   or whatever the function is?

NatashaJurko
New Contributor III

They have different arcpy mapping module classes, so I am hoping I can alter the legend class separately from the symbology class.  I just want to deal with the way the legend looks, not alter the symbology of the raster layer on the map or in the TOC.

0 Kudos
LukeWebb
Occasional Contributor III

I dont think we can use style manager within Arcpy.  

I have tested "Layer.replacedatasource" and it appears to retain the styles!

Take a copy of the layer the user set up in the mxd.   (ARRRG the copy doesnt retain styles! So skip this step)

update its data source

update any symbology as required

then remove the template.      (This step no longer exists due to the ARRG caveat above)

NatashaJurko
New Contributor III

Thanks Luke, I'll take a look at the 'replacedatasource' option and see if I can make it work!

0 Kudos
NatashaJurko
New Contributor III

Just wanted to follow up to my marking this as the correct answer.  

The Layer.replacedatasource worked!!

The only thing I changed in your step-by-step is that instead of making a copy of the template layer (like you said it doesn't work) I 'saved' the original datasource layer as a separate variable:

Saved the original data source from the template layer in a new variable within the script.  

Iterated through all the rasters in the template layer, reassigning the datasource each time.  

At then end used the variable holding the original datasource to assign the template layer back to the original.

Thanks for finding the Replace Data source... I would never have thought to use that!

N