Étant donné qu'ArcGIS 10 est fourni avec le package ArcPy, je me demande s'il est possible d'utiliser les fonctions ArcPy pour obtenir la symbologie (c'est-à-dire la couleur, la largeur ...) d'une couche?
Étant donné qu'ArcGIS 10 est fourni avec le package ArcPy, je me demande s'il est possible d'utiliser les fonctions ArcPy pour obtenir la symbologie (c'est-à-dire la couleur, la largeur ...) d'une couche?
Réponses:
Pour ArcGIS 10.0, si vous pouvez utiliser une approche en lecture seule, l'exemple de code suivant révèle le champ (et la table jointe) qui constitue la base de la symbologie d'une couche. Il exporte un msd temporaire (un zip contenant des fichiers xml) et charge les attributs spécifiques dans un objet. Ces classes peuvent être étendues pour accéder à des attributs de couche supplémentaires.
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
Exemple de sortie de test:
Layer Name: Amphibian Species Richness Average of 30m Cells
Layer Symbology Field Name: biodiversity.AmphAve
list index out of range
. c'est parce que le symbologyElement.getElementsByTagName(self.LYR_FIELD_NODE)
est vide. Mais pourquoi est-il vide? J'ai supposé qu'il s'agit d'une alternative à la méthode lyr.symbology, mais cela ne fonctionne toujours pas.
ArcPy cherche à vous permettre de modifier la symbologie, mais uniquement avec les fichiers .lyr existants , et non à spécifier les symboles directement dans votre code en fonction de ma lecture du module.
Dans ArcGIS 10.1 et versions ultérieures, il existe un accès direct à la symbologie via la propriété de symbologie de l'objet de couche .
Pour ArcGIS 10.0, les solutions de contournement mentionnées ont fonctionné pour moi.
with zipfile.ZipFile(msdPath) as zz:
.