Como as pessoas estão usando estruturas e classes de dados Python no ArcPy?


16

Essa pergunta pode expor minha ignorância em programação, mas estou curioso sobre como as pessoas estão usando diferentes estruturas de dados python no ArcPy.

Esta página lista as estruturas de dados em Python. Entendo como as listas podem ser implementadas no GIS (lista de classes de recursos, lista de tipos de recursos, lista de quadros de dados, etc.). Entendo como os conjuntos também podem ser usados ​​(para remover duplicatas). Como as pessoas estão implementando tuplas, dicionários e outras estruturas de dados no ArcPy? Além disso, existem outros exemplos de listas e conjuntos que eu não listei?

Além disso, sem dúvida, as pessoas estão criando classes personalizadas no ArcPy. Em que circunstâncias e situações você precisa disso? Você pode fornecer exemplos? Alguém está criando classes personalizadas que herdam das classes arcpy internas?

Não preciso de respostas para todas essas perguntas, só estou curioso para saber como as pessoas estão usando o Python no GIS e quais fluxos de trabalho exigem essas personalizações.


4
Pergunta interessante, mas isso não tem uma resposta definitiva. Deve ser um wiki da comunidade.
RK

Respostas:


14

Muitas funções arcpy que recebem várias entradas aceitam objetos da lista Python.

Por exemplo, a Dissolve_managementfunção aceita uma lista de nomes de campos para dissolver:

arcpy.Dissolve_management("taxlots", "C:/output/output.gdb/taxlots_dissolved",
    ["LANDUSE", "TAXCODE"], "", "SINGLE_PART", "DISSOLVE_LINES")

Uma tupla pode ser usada no lugar de uma lista quando você não precisa modificar a ordem ou o número de elementos, pois as tuplas são imutáveis . Eles são uma estrutura de dados útil para dados heterogêneos, mas relacionados, como os elementos de um carimbo de data / hora ou as coordenadas de um ponto. Você verá frequentemente listas de tuplas, onde uma tupla serve como um registro distinto com um número fixo de atributos, enquanto a lista pode facilmente mudar de tamanho, ser reordenada (classificada) etc. Consulte esta pergunta do StackOverflow para obter mais informações sobre os usos. de listas vs. tuplas.

Um dicionário pode ser usado como uma tabela de pesquisa rápida para armazenar em cache um conjunto de pares de valores-chave relativamente pequeno, porém usado com frequência. Vi um exemplo interessante nos fóruns do ArcGIS: http://forums.arcgis.com/threads/55099-Update-cursor-with-joined-tables-work-around-w-dictionaries

O uso de um dicionário em vez de uma junção acelerou seu cálculo de 3,5 horas para 15 minutos.

Um exemplo mais simples pode ser se você tiver um milhão de registros de endereço com um atributo com o nome abreviado do estado (CA), mas, para fins de exibição, você deseja especificar o nome apropriado (Califórnia), você pode usar esse dicionário como uma tabela de pesquisa quando preenchendo um campo de nome completo do estado.

Eu não encontrei a necessidade de escrever uma classe em Python para uso no arcpy, mas isso não quer dizer que não exista esse caso de uso. Uma classe pode ser útil quando você tem um conjunto de funções intimamente relacionadas (comportamentos) que operam em alguma entrada (dados) e deseja poder usar esses dados e comportamentos de maneira orientada a objetos, mas isso é mais provavelmente será específico da lógica de negócios e não relacionado ao arcpy.


7

Blah238 aborda bem esse tópico, então apenas adicionarei alguns exemplos do meu próprio trabalho. Desenvolvo muitos dados do aeroporto, e uma das coisas que tenho que fazer regularmente é lida em ordem ao longo dos pontos centrais da pista pesquisada de uma pista. Você pensaria que esses pontos já estariam em ordem (no banco de dados GIS), mas raramente são. Os pontos da linha central ocorrem a cada 10 pés ao longo da linha central e são flanqueados de cada lado por duas outras linhas de pontos de levantamento espaçados 10 pés. Você entendeu: uma infinidade de pontos ... e geralmente todos misturados em banco de dados. Com o que estou fazendo nos meus scripts, geralmente é mais fácil selecionar os pontos da linha central por atributos (ou espacialmente, se necessário), ler as coordenadas de cada um e colocar os resultados em uma lista Python. Posso então classificar, pop, reverter etc.

Da mesma forma, eu uso dicionários Python extensivamente (provavelmente muito mais do que alguns aprovariam). Eu tenho que criar conjuntos de vetores de unidades 3D para cada extremidade da pista em um aeroporto, e eu os acesso constantemente a um script e faço isso em muitos dos meus scripts. Também guardo muitos outros conjuntos de dados acessados ​​regularmente em dicionários. Como listas, eles são rápidos e flexíveis. Altamente recomendado.

No que diz respeito às aulas, como Blah238, não encontrei a necessidade de criar nenhuma. Provavelmente existem alguns casos em que uma classe seria preferida em meus scripts, mas eu realmente não consegui identificar esses lugares. Alguém com mais experiência em programação provavelmente os encontraria rapidamente.


5

Eu também amo dicionários - use-os o tempo todo. Este método obtém algumas propriedades de referência espacial e armazena tudo em um ditado:

def get_coord_sys(self, in_dataset):
    """Get and return info on dataset coord sys/projection"""
    spatial_ref = arcpy.Describe(in_dataset).spatialReference
    # Get spatial ref props and put in dictionary
    spat_ref_dict = {}
    spat_ref_dict["name"] = spatial_ref.name
    spat_ref_dict["type"] = spatial_ref.type
    spat_ref_dict["gcs_code"] = spatial_ref.GCSCode
    spat_ref_dict["gcs_name"] = spatial_ref.GCSName
    spat_ref_dict["pcs_code"] = spatial_ref.PCSCode
    spat_ref_dict["pcs_name"] = spatial_ref.PCSName
    return spat_ref_dict

Esse snippet de método extrai geometrias de pontos de duas classes de recurso, depois utilizo as geometrias mais tarde para fazer alguns disparos:

def build_fields_of_view(self):
        """For all KOPs in a study area, build left, right, center FoV triangles"""
        try:    
            fcs = {os.path.join(self.gdb, "WindFarmArray"):[], os.path.join(self.gdb, "KOPs"):[]}
            # Build a dict of WTG and KOP array geometries, looks like:
            #  {'KOPs': [[1, -10049.2697098718, 10856.699451165374], 
            #            [2, 6690.4377855260946, 15602.12386816188]], 
            #   'WindFarmArray': [[1, 5834.9321158060666, 7909.3822339441513], 
            #                     [2, 6111.1759513214511, 7316.9684107396561]]}
            for k, v in fcs.iteritems():
                rows = arcpy.SearchCursor(k, "", self.sr)
                for row in rows:
                    geom = row.shape
                    point = geom.getPart()
                    id = row.getValue("OBJECTID")
                    v.append([id, point.X, point.Y])   

            kops = fcs[os.path.join(self.gdb, "KOPs")] # KOP array
            wtgs = fcs[os.path.join(self.gdb, "WindFarmArray")] # WTG array

MUITO do que estou trabalhando atualmente envolve extrair as coordenadas e os atributos das classes e rasters de recursos vetoriais, para que os dados possam ser transferidos para outro software que nem sabe o que são dados GIS. Então, eu uso muito listas e dicionários para isso.


obrigado pela resposta. Por que um dicionário é uma escolha melhor do que outra estrutura de dados nesses casos?
Fezter

Eu só gosto de poder chamar meus valores por minhas chaves.
Chad Cooper

2
outro motivo pelo qual os ditados podem ser preferíveis é porque eles são lidos muito mais rapidamente do que as listas, porque não são pedidos. portanto, listas muito longas podem demorar um pouco mais para serem processadas se tiverem muitas entradas.
Ndimhypervol

@gotanuki True, e se você precisar usar uma lista grande, use uma tupla, pois elas são mais rápidas que as listas também.
Chad Cooper

2

Leia isso enquanto prepara uma resposta e teve que fazer algumas edições.

Não sou especialista em Python, mas acho que a idéia por trás do uso de classes é que você pode instanciar um objeto que tenha vários métodos prontos, relacionados à estrutura de dados, além de centralizar seus métodos. Há também alguns benefícios de escopo variável com classes versus módulos, o link acima chega um pouco a esse ponto.

Eu tenho uma classe chamada featureLayer (provavelmente não chamada de forma pitônica ... ainda está aprendendo). eu posso fazer

sys.path.append(r"\\Path\To\Scripts")
import gpFuncs as gpF
fc = arcpy.GetParameterAsText(0)
featureLayer = gpF.featureLayer(fc)
points = featureLayer.featureVerticesToPoints(featureid, "", first_and_last)

A definição para fazer isso é um método de classe que apenas itera os recursos, partes e vértices. Então eu posso transformar meu objeto de pontos em uma instância featureLayer e fazer outras coisas que minha classe possui.

Eu acho que se as classes criadas corretamente devem desativar a funcionalidade. Por exemplo, em breve começarei a refatorar para que eu tenha uma classe featureLayer que possua métodos e atributos que todas as camadas de recurso possuem. Em seguida, herde-o para criar uma instância da classe featureLayerStrict que herdará todos os atributos / métodos featureLayers, mas será instanciada com um tipo de geometria específico, como polígono.


4
Confira o guia de estilo do Python (também conhecido como PEP 8) para convenções de nomenclatura.
precisa saber é o seguinte

0

Eu trabalho principalmente em VB .net, mas me pego usando python e arcpy cada vez mais. No VB eu gosto e tento usar o Enums, pois torna a leitura do código mais clara. As versões anteriores do python não implementavam Enums, portanto, um hack foi criar uma classe expondo algumas propriedades, vários exemplos são discutidos no Stack Overflow . Agora parece que a versão mais recente do python implementa esses itens, que são discutidos aqui .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.