Використовуючи ArcPy для отримання символіки шару?


16

Оскільки ArcGIS 10 поставляється з пакетом ArcPy, мені цікаво, чи можна використовувати функції ArcPy для отримання символіки (тобто кольору, ширини ...) шару?

Відповіді:


15

Для ArcGIS 10.0, якщо ви можете використовувати підхід лише для читання, наступний зразок коду розкриває поле (та об'єднану таблицю), що є основою для символіки шару. Він експортує тимчасовий msd (zip, що містить файли xml) і завантажує конкретні атрибути в об’єкт. Ці класи можуть бути розширені, щоб отримати доступ до додаткових атрибутів рівня.

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

Використовуйте менеджер контексту для цього поштового файлу: 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)порожній. Але чому він порожній? Я припускав, що це альтернатива методу лір.симбології, але він все ще не працює.
панда

@panda Це стара відповідь. Ви використовуєте версію, що перевищує 10,0? Якщо так, див. Відповідь нижче про властивість символіки об'єкта шару.
MJ

@MichaelJackson Я використовую властивість символіки, але, здається, вона не підтримується у всіх випадках, як, наприклад, коли шар використовує більше одного поля для символіки. Мені потрібно отримати назви використовуваних полів, але я не можу знайти метод.
панда


6

У ArcGIS 10.1 та новіших версіях існує прямий доступ до симвології через властивість символіки об'єкта шару .

Для ArcGIS 10.0 згадані способи вирішення справи працювали для мене.


на жаль, символіка шару є лише для читання (згідно з п’ятою інстанцією «символіки» на цій сторінці , а також тієї, яку ви цитували).
Роланд

1
Однак "Не всі типи класів символіки шарів підтримуються; для тих, хто їх немає, повертається ключове слово OTHER." . Непідтримувані типи включають унікальні значення растрових значень, унікальні значення багатьох полів та щільність точок. Це все ще вірно в ArcGIS 10.5. Якщо вам пощастило мати підтримуваний SymbologyType, дивіться сценарій у gis.stackexchange.com/questions/184133/…
matt wilkie
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.