레이어 기호를 얻기 위해 ArcPy를 사용합니까?


16

ArcGIS 10은 ArcPy 패키지와 함께 제공되므로 ArcPy 함수를 사용하여 레이어의 심볼로지 (예 : 색상, 너비 ...)를 얻을 수 있는지 궁금합니다.

답변:


15

ArcGIS 10.0의 경우 읽기 전용 접근 방식을 사용할 수있는 경우 다음 코드 샘플은 레이어 심볼로지의 기초를 형성하는 필드 (및 조인 된 테이블)를 나타냅니다. 임시 msd (xml 파일이 포함 된 zip)를 내보내고 특정 속성을 개체에로드합니다. 이러한 클래스는 추가 레이어 속성에 액세스 할 수 있도록 확장 될 수 있습니다.

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 

테스트 출력 예 :

Layer Name:  Amphibian Species Richness Average of 30m Cells
Layer Symbology Field Name:  biodiversity.AmphAve

해당 zip 파일에 대한 컨텍스트 관리자를 사용하십시오 with zipfile.ZipFile(msdPath) as zz:.
jpmc26

@MichaelJackson 귀하의 코드에서 mxd 경로 만 바꿨습니다. 하지만`lyr.symbologyFieldName = symbologyElement.getElementsByTagName (self.LYR_FIELD_NODE) ​​[0] .childNodes [0] .nodeValue` 줄에 오류가 list index out of range있습니다. 이 symbologyElement.getElementsByTagName(self.LYR_FIELD_NODE)비어 있기 때문 입니다. 그러나 왜 비어 있습니까? 나는 이것이 lyr.symbology 방법의 대안이라고 가정했지만 여전히 작동하지 않습니다.
팬더

@ 팬더 이것은 오래된 답변입니다. 10.0보다 높은 버전을 사용하고 있습니까? 그렇다면 아래 레이어 객체의 symbology 속성에 대한 답변을 참조하십시오.
MJ

@MichaelJackson symbology 속성을 사용하지만 레이어가 symbology에 둘 이상의 필드를 사용하는 경우와 같이 모든 경우에 지원되지 않는 것 같습니다. 사용 된 필드의 이름을 가져와야하지만 메소드를 찾을 수 없습니다.
팬더

10

ArcPy는 기존 .lyr 파일 로만 기호를 변경할 수 있으며 모듈을 읽은 결과에 따라 코드에서 직접 기호를 지정하지 않습니다.


6

ArcGIS 10.1 이상 에서는 레이어 객체symbology 속성을 통해 심볼에 직접 액세스 할 수 있습니다.

ArcGIS 10.0의 경우 언급 된 해결 방법이 저에게 효과적이었습니다.


불행히도, 레이어의 기호는 읽기 전용입니다 ( 이 페이지 의 "기호"의 다섯 번째 인스턴스와 인용 한 것에 따름 ).
Roland

1
그러나 "모든 레이어 기호 클래스 유형이 지원되는 것은 아니며, 그렇지 않은 경우 키워드 OTHER가 반환됩니다." . 지원되지 않는 유형에는 래스터 고유 값, 고유 값 많은 필드 및 도트 밀도가 포함됩니다. ArcGIS 10.5에서도 마찬가지입니다. 당신이있는 거 운이 충분이 가지고있는 경우 지원 SymbologyType가에서 스크립트를 참조 gis.stackexchange.com/questions/184133/...
매트 윌키
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.