Mass Symbology additions via Python

793
4
07-11-2011 11:47 AM
ToddGray
New Contributor
I generally get about a thousand new layers added to a map a few times a week...I was wondering if anyone is aware of a python script that would automate that process of adding the Symbology to all the layers, they are usually always the same cutpoints and colors ect.

Thanks for any insight.
Tags (2)
0 Kudos
4 Replies
BradPosthumus
Occasional Contributor II
What type of data (vector/raster) and classification (unique value, graduated colours, etc.) are you using? What version of ArcGIS is this for?
0 Kudos
ToddGray
New Contributor
BP, it is raster data, with graduated colors.  I'm using the latest version.  (10)
0 Kudos
BradPosthumus
Occasional Contributor II
Here's one way of doing it using the comtypes site-package with ArcObjects. The script below opens an MXD, grabs the symbology (renderer) of the first layer of the first data frame, and replaces every other raster layer's symbology (in the same data frame) with it. Essentially you end up with an MXD where all rasters in the first data frame use the exact same symbology.

I noticed a side effect though: the symbology between the rasters is linked, so changing the symbology (e.g. a colour or label value) in one of the rasters will change it in all of them. Changing the renderer type though (e.g. Classified to Stretched) breaks this link.

Comtypes is available here: http://sourceforge.net/projects/comtypes/. Hopefully symbology will be included in future releases of ArcPy so we can avoid these comtypes work-arounds.

Note that I only have access to 9.3 so this is untested in ArcMap 10.

import comtypes.client
esriCarto = comtypes.client.GetModule(r'C:\Program Files\ArcGIS\com\esriCarto.olb')

def openMxd(strMxd):
    """ Opens an MXD and returns an IMapDocument object. """
    try:
        objMapDocument = comtypes.client.CreateObject(esriCarto.MapDocument, interface=esriCarto.IMapDocument)
        if objMapDocument.IsMapDocument(strMxd):
            objMapDocument.Open(strMxd, "")
        else:
            return 0
        return objMapDocument
    except:
        return 0

strMxd = r"C:\workspace\test.mxd"
# Open the MXD
objMapDocument = openMxd(strMxd)
if objMapDocument:
    try:
        # Get the first map in the MXD
        objMap = objMapDocument.Map(0)
        # Get the first layer in the map (i.e. data frame) - MUST BE A RASTER
        objSourceLayer = objMap.Layer(0)
        # Get the layer's renderer
        objRasterLayer = objSourceLayer.QueryInterface(esriCarto.IRasterLayer)
        objSourceRasterRenderer = objRasterLayer.Renderer
        # Loop through the rest of the layer in the map
        for i in range(1, objMap.LayerCount):
            objDestinationLayer = objMap.Layer(i)
            print objDestinationLayer.Name
            # Replace the current layer's renderer with the first layer's renderer
            try:
                objRasterLayer = objDestinationLayer.QueryInterface(esriCarto.IRasterLayer)
                objRasterLayer.Renderer = objSourceRasterRenderer
            except:
                print "Not a raster"
                continue
        # Save the MXD and close it.
        objMapDocument.Save()
        objMapDocument.Close()
    except:
        print "Error"
        objMapDocument.Close()
0 Kudos
WadeGivens
New Contributor II
Will this work if you are using a stretched symbology on your rasters?  Will it apply the stretced symbology and color scheme, but change the min and max values based on each raster it loops through?

Thanks,
Wade
0 Kudos