Since ArcGIS 10 comes with the ArcPy package, I'm wondering it is possible to use ArcPy functions to get Symbology (i.e color, width...) of a layer?
3 Answers
For ArcGIS 10.0, if you can make use of a read-only approach, the following code sample reveals the field (and joined table) that forms the basis for the symbology of a layer. It exports a temporary msd(a zip containing xml files) and loads the specific attributes into an object. These classes might be extended to gain access to additional layer attributes.
import zipfile
from arcpy import mapping
import os
from xml.dom.minidom import parse
class LayerExtras(object):
""" An object to hold attributes loaded from xml inside the msd."""
name = ""
symbologyFieldName = ""
class MxdExtras(dict):
""" Exposes extra MXD details by raiding an exported msd
Treat this object as a dictionary with layer name as the key and a custom object
with desired attributes as the value.
You must have write access to MXD directory (creates temporary msd file).
Only layers in the first dataframe are accessed.
"""
LYR_NAME_NODE = "Name"
LYR_SYMBOL_NODE = "Symbolizer"
LYR_FIELD_NODE = "Field"
MSD_SUFFIX = "_MxdExtrasTemp.msd"
MXD_SUFFIX = ".mxd"
EXCLUDED_FILE_NAMES = ["DocumentInfo.xml", "layers/layers.xml"]
mxdPath = ""
def __init__(self, mxdPath):
self.loadMxdPath(mxdPath)
def loadMxdPath(self, mxdPath):
""" Load mxd from file path """
self.mxdPath = mxdPath.lower()
mxd = mapping.MapDocument(self.mxdPath)
msdPath = self.mxdPath.replace(self.MXD_SUFFIX, self.MSD_SUFFIX)
# Delete temporary msd if it exists
if os.path.exists(msdPath):
os.remove(msdPath)
mapping.ConvertToMSD(mxd,msdPath)
zz = zipfile.ZipFile(msdPath)
for fileName in (fileName for fileName in zz.namelist() if not fileName in self.EXCLUDED_FILE_NAMES):
dom = parse(zz.open(fileName))
name, lyr = self.loadMsdLayerDom(dom)
self[name] = lyr
del zz
os.remove(msdPath)
def loadMsdLayerDom(self, dom):
""" Load dom created from xml file inside the msd. """
lyr = LayerExtras()
# Layer name
lyr.name = dom.getElementsByTagName(self.LYR_NAME_NODE)[0].childNodes[0].nodeValue
# Symbology field name
symbologyElement = dom.getElementsByTagName(self.LYR_SYMBOL_NODE)[0]
lyr.symbologyFieldName = symbologyElement.getElementsByTagName(self.LYR_FIELD_NODE)[0].childNodes[0].nodeValue
return lyr.name, lyr
############
# Test
if __name__ == "__main__":
mxdPath = r"c:\temp\AmphibianSpeciesRichnessAverageOf30mCells.mxd"
mxde = MxdExtras(mxdPath)
for lyr in mxde.itervalues():
print "Layer Name: ", lyr.name
print "Layer Symbology Field Name: ", lyr.symbologyFieldName
print
Example output of test:
Layer Name: Amphibian Species Richness Average of 30m Cells
Layer Symbology Field Name: biodiversity.AmphAve
-
1Use a context manager for that zip file:
with zipfile.ZipFile(msdPath) as zz:
.– jpmc26Commented Apr 24, 2018 at 1:58 -
@MichaelJackson In your code, I have only replaced the mxd path. But I got an error at the ` lyr.symbologyFieldName = symbologyElement.getElementsByTagName(self.LYR_FIELD_NODE)[0].childNodes[0].nodeValue` line, sayying
list index out of range
. this is because thesymbologyElement.getElementsByTagName(self.LYR_FIELD_NODE)
is empty. But why is it empty? I assumed that this is an alternative to the lyr.symbology method, but it still doesn't work.– pandaCommented Aug 30, 2018 at 7:26 -
@panda This is an old answer. Are you using version higher than 10.0? If yes, see answer below about the symbology property of the layer object.– M JCommented Sep 4, 2018 at 16:51
-
@MichaelJackson I use the symbology property but it seems it's not supported in all the cases, like when the layer uses more than one field for symbology. I need to get the names of the fields used, but I can't find a method.– pandaCommented Sep 5, 2018 at 13:53
ArcPy looks to let you change the symbology, but only with existing .lyr files, and not specify the symbols directly in your code based on my reading of the module.
In ArcGIS 10.1 and newer there is direct access to the symbology via the symbology property of the layer object.
For ArcGIS 10.0 the mentioned workarounds did work for me.
-
-
1However "Not all layer symbology class types are supported; for those that are not, the keyword OTHER is returned.". Unsupported types include Raster Unique Values, Unique Values Many Fields, and Dot Density. This is still true in ArcGIS 10.5. If you're lucky enough to have a supported SymbologyType see script in gis.stackexchange.com/questions/184133/… Commented Aug 23, 2017 at 22:52