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メソッドの代替であると想定しましたが、まだ機能しません。
パンダ

@pandaこれは古い答えです。10.0以降のバージョンを使用していますか?「はい」の場合、レイヤーオブジェクトのシンボルプロパティに関する以下の回答を参照してください。
MJ

@MichaelJacksonシンボルプロパティを使用しますが、レイヤーがシンボルに複数のフィールドを使用する場合など、すべてのケースでサポートされていないようです。使用されているフィールドの名前を取得する必要がありますが、メソッドが見つかりません。
パンダ

10

ArcPyは、既存の.lyrファイルでのみシンボルを変更できるように見えますが、モジュールの読み取りに基づいてコードでシンボルを直接指定することはできません。


6

ArcGIS 10.1以降では、レイヤーオブジェクトのsymbologyプロパティを介してシンボルに直接アクセスできます

ArcGIS 10.0の場合、上記の回避策はうまくいきました。


残念ながら、レイヤーのシンボルは読み取り専用です(このページの「シンボル」の5番目のインスタンス、およびあなたが引用したものによる)。
ローランド14

1
ただし、 「すべてのレイヤーシンボルクラスタイプがサポートされているわけではありません。サポートされていないものについては、キーワードOTHERが返されます。」。サポートされていないタイプには、ラスターの一意の値、多くのフィールドの一意の値、およびドット密度が含まれます。これは、ArcGIS 10.5にも当てはまります。あなたがしている幸運十分に持っている場合は、サポートSymbologyTypeは、スクリプトを参照してくださいgis.stackexchange.com/questions/184133/...
マットウィルキー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.