Używasz ArcPy, aby uzyskać symbolikę warstw?

16

Ponieważ ArcGIS 10 jest dostarczany z pakietem ArcPy, zastanawiam się, czy można użyć funkcji ArcPy, aby uzyskać symbolikę (tj. Kolor, szerokość ...) warstwy?

VietThanh Le
źródło

Odpowiedzi:

15

W przypadku ArcGIS 10.0, jeśli można skorzystać z metody tylko do odczytu, poniższy przykład kodu ujawnia pole (i tabelę połączoną), które stanowią podstawę dla symboliki warstwy. Eksportuje tymczasowy msd (zip zawierający pliki xml) i ładuje określone atrybuty do obiektu. Klasy te można rozszerzyć, aby uzyskać dostęp do dodatkowych atrybutów warstw.

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 

Przykładowy wynik testu:

Layer Name:  Amphibian Species Richness Average of 30m Cells
Layer Symbology Field Name:  biodiversity.AmphAve
MJ
źródło
Użyć menedżera kontekstowe dla tego pliku zip: with zipfile.ZipFile(msdPath) as zz:.
jpmc26
@MichaelJackson W twoim kodzie zastąpiłem tylko ścieżkę mxd. Ale dostałem błąd w linii `lyr.symbologyFieldName = symbologyElement.getElementsByTagName (self.LYR_FIELD_NODE) ​​[0] .childNodes [0] .nodeValue`, mówiąc list index out of range. to dlatego, że symbologyElement.getElementsByTagName(self.LYR_FIELD_NODE)jest pusty. Ale dlaczego jest pusty? Zakładałem, że jest to alternatywa dla metody lyr.symbology, ale nadal nie działa.
panda
@panda To jest stara odpowiedź. Czy używasz wersji wyższej niż 10.0? Jeśli tak, zobacz odpowiedź poniżej dotyczącą właściwości symboliki obiektu warstwy.
MJ
@MichaelJackson Korzystam z właściwości symbology, ale wygląda na to, że nie jest obsługiwana we wszystkich przypadkach, na przykład gdy warstwa używa więcej niż jednego pola do symboliki. Muszę uzyskać nazwy użytych pól, ale nie mogę znaleźć metody.
panda
10

ArcPy pozwala zmienić symbolikę, ale tylko w przypadku istniejących plików .lyr , i nie określa symboli bezpośrednio w kodzie na podstawie mojego odczytu modułu.

scw
źródło
6

W ArcGIS 10.1 i nowszych istnieje bezpośredni dostęp do symboliki poprzez właściwość symboliki obiektu warstwy .

W przypadku ArcGIS 10.0 wspomniane obejścia działały dla mnie.

Bernd
źródło
niestety symbolika warstwy jest tylko do odczytu (zgodnie z piątym wystąpieniem „symboliki” na tej stronie , a także tym, który zacytowałeś).
Roland
1
Jednak „Nie wszystkie typy klas symboli symboliki warstw są obsługiwane; dla tych, które nie są, zwracane jest słowo kluczowe OTHER”. . Nieobsługiwane typy obejmują unikatowe wartości rastrowe, unikatowe wartości wiele pól i gęstość kropek. Jest to nadal prawdą w ArcGIS 10.5. Jeśli masz szczęście, że masz obsługiwaną funkcję SymbologyType, zobacz skrypt w gis.stackexchange.com/questions/184133/…
matt wilkie