¿Usa ArcPy para obtener simbología de capa?

16

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.

VietThanh Le
fuente

Respuestas:

15

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
MJ
fuente
Utilizar un gestor de contexto para ese archivo zip: with zipfile.ZipFile(msdPath) as zz:.
jpmc26
@MichaelJackson En su código, solo he reemplazado la ruta mxd. Pero recibí un error en la línea `lyr.symbologyFieldName = symbologyElement.getElementsByTagName (self.LYR_FIELD_NODE) ​​[0] .childNodes [0] .nodeValue`, diciendo 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.
panda
@panda Esta es una vieja respuesta. ¿Está utilizando una versión superior a la 10.0? En caso afirmativo, vea la respuesta a continuación sobre la propiedad de simbología del objeto de capa.
MJ
@MichaelJackson Uso la propiedad de simbología, pero parece que no es compatible en todos los casos, como cuando la capa usa más de un campo para la simbología. Necesito obtener los nombres de los campos utilizados, pero no puedo encontrar un método.
panda
10

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.

scw
fuente
6

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.

Bernd
fuente
desafortunadamente, la simbología de una capa es de solo lectura (según la quinta instancia de "simbología" en esta página , así como la que usted citó).
Roland
1
Sin embargo, "No todos los tipos de clase de simbología de capa son compatibles; para aquellos que no lo son, se devuelve la palabra clave OTHER". . Los tipos no admitidos incluyen valores únicos ráster, valores únicos en muchos campos y densidad de puntos. Esto sigue siendo cierto en ArcGIS 10.5. Si tiene la suerte de tener un SymbologyType compatible, consulte el script en gis.stackexchange.com/questions/184133/…
matt wilkie el