Menggunakan ArcPy untuk mendapatkan simbologi layer?
16
Karena ArcGIS 10 hadir dengan paket ArcPy, saya ingin tahu apakah mungkin untuk menggunakan fungsi ArcPy untuk mendapatkan Symbology (yaitu warna, lebar ...) dari suatu lapisan?
Untuk ArcGIS 10.0, jika Anda dapat menggunakan pendekatan read-only, contoh kode berikut ini mengungkapkan bidang (dan tabel gabungan) yang membentuk dasar untuk simbologi lapisan. Ini mengekspor msd sementara (zip berisi file xml) dan memuat atribut spesifik ke objek. Kelas-kelas ini mungkin diperluas untuk mendapatkan akses ke atribut layer tambahan.
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
Contoh hasil uji:
LayerName:AmphibianSpeciesRichnessAverage of 30mCellsLayerSymbologyFieldName: biodiversity.AmphAve
Menggunakan manajer konteks untuk file zip: with zipfile.ZipFile(msdPath) as zz:.
jpmc26
@MichaelJackson Dalam kode Anda, saya hanya mengganti path mxd. Tapi saya mendapat kesalahan di baris `lyr.symbologyFieldName = symbologyElement.getElementsByTagName (self.LYR_FIELD_NODE) [0] .childNodes [0] .nodeValue`, mengatakan list index out of range. ini karena symbologyElement.getElementsByTagName(self.LYR_FIELD_NODE)kosong. Tetapi mengapa itu kosong? Saya berasumsi bahwa ini adalah alternatif untuk metode lyr.simbologi, tetapi masih tidak berhasil.
panda
@anda Ini adalah jawaban lama. Apakah Anda menggunakan versi lebih tinggi dari 10.0? Jika ya, lihat jawaban di bawah ini tentang properti simbologi dari objek layer.
MJ
@MichaelJackson Saya menggunakan properti simbologi tetapi tampaknya itu tidak didukung dalam semua kasus, seperti ketika layer menggunakan lebih dari satu bidang untuk simbologi. Saya perlu mendapatkan nama-nama bidang yang digunakan, tetapi saya tidak dapat menemukan metode.
panda
10
ArcPy terlihat untuk membiarkan Anda mengubah simbologi, tetapi hanya dengan file .lyr yang ada , dan tidak menentukan simbol secara langsung dalam kode Anda berdasarkan pembacaan saya atas modul.
Sayangnya, simbologi dari sebuah layer adalah read-only (sesuai dengan contoh kelima "simbologi" pada halaman ini , serta yang Anda kutip).
Roland
1
Namun "Tidak semua jenis kelas simbologi lapisan didukung; untuk yang tidak, kata kunci OTHER dikembalikan." . Jenis yang tidak didukung termasuk Nilai Unik Raster, Nilai Unik Banyak Bidang, dan Dot Density. Ini masih berlaku di ArcGIS 10.5. Jika Anda cukup beruntung memiliki SymbologyType yang didukung, lihat skrip di gis.stackexchange.com/questions/184133/…
with zipfile.ZipFile(msdPath) as zz:
.list index out of range
. ini karenasymbologyElement.getElementsByTagName(self.LYR_FIELD_NODE)
kosong. Tetapi mengapa itu kosong? Saya berasumsi bahwa ini adalah alternatif untuk metode lyr.simbologi, tetapi masih tidak berhasil.ArcPy terlihat untuk membiarkan Anda mengubah simbologi, tetapi hanya dengan file .lyr yang ada , dan tidak menentukan simbol secara langsung dalam kode Anda berdasarkan pembacaan saya atas modul.
sumber
Dalam ArcGIS 10.1 dan yang lebih baru ada akses langsung ke simbologi melalui properti simbologi dari objek layer .
Untuk ArcGIS 10.0 solusi yang disebutkan berhasil untuk saya.
sumber