Câu trả lời:
Đối với ArcGIS 10.0, nếu bạn có thể sử dụng cách tiếp cận chỉ đọc, mẫu mã sau đây cho thấy trường (và bảng đã tham gia) tạo cơ sở cho hệ thống ký hiệu của một lớp. Nó xuất một msd tạm thời (một zip chứa các tệp xml) và tải các thuộc tính cụ thể vào một đối tượng. Các lớp này có thể được mở rộng để có quyền truy cập vào các thuộc tính lớp bổ sung.
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
Ví dụ đầu ra của thử nghiệm:
Layer Name: Amphibian Species Richness Average of 30m Cells
Layer Symbology Field Name: biodiversity.AmphAve
list index out of range
. Điều này là do symbologyElement.getElementsByTagName(self.LYR_FIELD_NODE)
trống rỗng. Nhưng tại sao nó lại trống rỗng? Tôi giả định rằng đây là một phương pháp thay thế cho phương pháp lyr.symbology, nhưng nó vẫn không hoạt động.
ArcPy có vẻ cho phép bạn thay đổi hệ thống ký hiệu, nhưng chỉ với các tệp .lyr hiện có và không chỉ định các ký hiệu trực tiếp trong mã của bạn dựa trên việc tôi đọc mô-đun.
Trong ArcGIS 10.1 và mới hơn có quyền truy cập trực tiếp vào hệ thống ký hiệu thông qua thuộc tính ký hiệu của đối tượng lớp .
Đối với ArcGIS 10.0, cách giải quyết được đề cập đã làm việc với tôi.
with zipfile.ZipFile(msdPath) as zz:
.