Vous utilisez ArcPy pour obtenir la symbologie des couches?
16
É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?
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
classLayerExtras(object):""" An object to hold attributes loaded from xml inside the msd."""
name =""
symbologyFieldName =""classMxdExtras(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 existsif os.path.exists(msdPath):
os.remove(msdPath)
mapping.ConvertToMSD(mxd,msdPath)
zz = zipfile.ZipFile(msdPath)for fileName in(fileName for fileName in zz.namelist()ifnot 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
############# Testif __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:
LayerName:AmphibianSpeciesRichnessAverage of 30mCellsLayerSymbologyFieldName: biodiversity.AmphAve
Utilisez un gestionnaire de contexte pour ce fichier zip: with zipfile.ZipFile(msdPath) as zz:.
jpmc26
@MichaelJackson Dans votre code, je n'ai remplacé que le chemin mxd. Mais j'ai eu une erreur sur la ligne `lyr.symbologyFieldName = symbologyElement.getElementsByTagName (self.LYR_FIELD_NODE) [0] .childNodes [0] .nodeValue`, disant 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.
panda
@panda C'est une vieille réponse. Utilisez-vous une version supérieure à 10.0? Si oui, voir la réponse ci-dessous à propos de la propriété de symbologie de l'objet de couche.
MJ
@MichaelJackson J'utilise la propriété de symbologie mais il semble qu'elle ne soit pas prise en charge dans tous les cas, comme lorsque la couche utilise plus d'un champ pour la symbologie. J'ai besoin d'obtenir les noms des champs utilisés, mais je ne trouve pas de méthode.
panda
10
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.
malheureusement, la symbologie d'une couche est en lecture seule (selon la cinquième instance de "symbologie" sur cette page , ainsi que celle que vous avez citée).
Roland
1
Cependant "Tous les types de classe de symbologie de couche ne sont pas pris en charge; pour ceux qui ne le sont pas, le mot clé OTHER est renvoyé." . Les types non pris en charge incluent les valeurs uniques raster, les valeurs uniques de nombreux champs et la densité de points. Cela est toujours vrai dans ArcGIS 10.5. Si vous avez la chance d'avoir un SymbologyType pris en charge, voir le script dans gis.stackexchange.com/questions/184133/…
with zipfile.ZipFile(msdPath) as zz:
.list index out of range
. c'est parce que lesymbologyElement.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.
la source
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.
la source