Dado que ArcGIS 10 viene con el paquete ArcPy, me pregunto si es posible usar las funciones de ArcPy para obtener la simbología (es decir, color, ancho ...) de una capa.
Dado que ArcGIS 10 viene con el paquete ArcPy, me pregunto si es posible usar las funciones de ArcPy para obtener la simbología (es decir, color, ancho ...) de una capa.
Respuestas:
Para ArcGIS 10.0, si puede utilizar un enfoque de solo lectura, el siguiente ejemplo de código revela el campo (y la tabla unida) que forma la base para la simbología de una capa. Exporta un msd temporal (un archivo zip que contiene archivos xml) y carga los atributos específicos en un objeto. Estas clases pueden ampliarse para obtener acceso a atributos de capa adicionales.
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
Ejemplo de salida de prueba:
Layer Name: Amphibian Species Richness Average of 30m Cells
Layer Symbology Field Name: biodiversity.AmphAve
list index out of range
. Esto es porque el symbologyElement.getElementsByTagName(self.LYR_FIELD_NODE)
está vacío. ¿Pero por qué está vacío? Supuse que esta es una alternativa al método lyr.symbology, pero aún no funciona.
ArcPy busca permitirle cambiar la simbología, pero solo con los archivos .lyr existentes , y no especificar los símbolos directamente en su código en función de mi lectura del módulo.
En ArcGIS 10.1 y posteriores hay acceso directo a la simbología a través de la propiedad de simbología del objeto de capa .
Para ArcGIS 10.0, las soluciones mencionadas me funcionaron.
with zipfile.ZipFile(msdPath) as zz:
.