Verwenden von ArcPy zum Abrufen der Layer-Symbologie
16
Da ArcGIS 10 mit dem ArcPy-Paket geliefert wird, frage ich mich, ob ArcPy-Funktionen verwendet werden können, um die Symbologie (dh Farbe, Breite ...) eines Layers abzurufen.
Wenn Sie in ArcGIS 10.0 einen schreibgeschützten Ansatz verwenden können, zeigt das folgende Codebeispiel das Feld (und die verknüpfte Tabelle) an, die die Grundlage für die Symbologie eines Layers bilden. Es exportiert eine temporäre MSD (eine ZIP-Datei mit XML-Dateien) und lädt die spezifischen Attribute in ein Objekt. Diese Klassen können erweitert werden, um Zugriff auf zusätzliche Ebenenattribute zu erhalten.
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
Beispielausgabe des Tests:
LayerName:AmphibianSpeciesRichnessAverage of 30mCellsLayerSymbologyFieldName: biodiversity.AmphAve
Verwenden Sie einen Kontext - Manager für diese Zip - Datei: with zipfile.ZipFile(msdPath) as zz:.
jpmc26
@MichaelJackson In deinem Code habe ich nur den mxd Pfad ersetzt. In der Zeile `lyr.symbologyFieldName = symbologyElement.getElementsByTagName (self.LYR_FIELD_NODE) [0] .childNodes [0] .nodeValue` ist ein Fehler aufgetreten list index out of range. Das liegt daran, dass das symbologyElement.getElementsByTagName(self.LYR_FIELD_NODE)leer ist. Aber warum ist es leer? Ich nahm an, dass dies eine Alternative zur Methode lyr.symbology ist, aber es funktioniert immer noch nicht.
Panda
@panda Dies ist eine alte Antwort. Verwenden Sie eine höhere Version als 10.0? Wenn ja, lesen Sie die Antwort unten über die Symbologieeigenschaft des Ebenenobjekts.
MJ
@MichaelJackson Ich verwende die Symbologieeigenschaft, aber es scheint, dass sie nicht in allen Fällen unterstützt wird, z. B. wenn der Layer mehr als ein Feld für die Symbologie verwendet. Ich muss die Namen der verwendeten Felder abrufen, kann aber keine Methode finden.
Panda
10
In ArcPy können Sie die Symbologie ändern, jedoch nur mit vorhandenen .lyr-Dateien , und die Symbole nicht direkt in Ihrem Code angeben, basierend auf dem Lesen des Moduls.
Leider ist die Symbologie einer Ebene schreibgeschützt (gemäß der fünften Instanz von "Symbologie" auf dieser Seite sowie der von Ihnen angegebenen).
Roland
1
"Es werden jedoch nicht alle Layer-Symbologie-Klassentypen unterstützt. Bei anderen wird das Schlüsselwort OTHER zurückgegeben." . Zu den nicht unterstützten Typen gehören "Raster Unique Values", "Unique Values Many Fields" und "Dot Density". Dies gilt auch in ArcGIS 10.5. Wenn Sie das Glück haben, einen unterstützten SymbologyType zu haben, lesen Sie das Skript in gis.stackexchange.com/questions/184133/…
with zipfile.ZipFile(msdPath) as zz:
.list index out of range
. Das liegt daran, dass dassymbologyElement.getElementsByTagName(self.LYR_FIELD_NODE)
leer ist. Aber warum ist es leer? Ich nahm an, dass dies eine Alternative zur Methode lyr.symbology ist, aber es funktioniert immer noch nicht.In ArcPy können Sie die Symbologie ändern, jedoch nur mit vorhandenen .lyr-Dateien , und die Symbole nicht direkt in Ihrem Code angeben, basierend auf dem Lesen des Moduls.
quelle
In ArcGIS 10.1 und höher können Sie über die Symbologieeigenschaft des Layer-Objekts direkt auf die Symbologie zugreifen .
Für ArcGIS 10.0 haben die genannten Problemumgehungen bei mir funktioniert.
quelle