Используя ArcPy для получения символов слоя?

16

Поскольку ArcGIS 10 поставляется с пакетом ArcPy, мне интересно, можно ли использовать функции ArcPy для получения символов (т. Е. Цвета, ширины ...) слоя?

VietThanh Le
источник

Ответы:

15

Для ArcGIS 10.0, если вы можете использовать подход только для чтения, в следующем примере кода раскрывается поле (и объединенная таблица), которое формирует основу для символов слоя. Он экспортирует временный msd (почтовый индекс, содержащий файлы 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
MJ
источник
Используйте менеджер контекста для этого почтового файла: 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 , и не указывать символы непосредственно в вашем коде на основе моего прочтения модуля.

SCW
источник
6

В ArcGIS 10.1 и новее есть прямой доступ к символике через свойство символики объекта слоя .

Для ArcGIS 10.0 упомянутые обходные пути работали для меня.

Бернд
источник
к сожалению, символика слоя доступна только для чтения (в соответствии с пятым экземпляром «символики» на этой странице , а также той, которую вы цитировали).
Роланд
1
Однако «Не все типы классов символов слоя поддерживаются; для тех, которые не поддерживаются, возвращается ключевое слово OTHER». , К неподдерживаемым типам относятся уникальные значения растра, уникальные значения, много полей и плотность точек. Это все еще верно в ArcGIS 10.5. Если вам повезло иметь поддерживаемый SymbologyType, посмотрите скрипт в gis.stackexchange.com/questions/184133/…
Мэтт Уилки