Listando todas as classes de recursos no Geodatabase de Arquivos, inclusive nos conjuntos de dados de recursos?

24

No python, como posso criar uma lista de todas as classes de recursos em um geodatabase de arquivo (* .gdb), incluindo conjuntos de dados internos de recursos? O exemplo padrão lista apenas as classes de recursos no nível superior do geodatabase:

import arcgisscripting, os
gp = arcgisscripting.create(9.3)

gp.workspace = 'd:\scratch.gdb'
fcs = gp.ListFeatureClasses()

for fc in fcs:
    print fc

Indique a qual versão do ArcGIS Desktop sua resposta se aplica (estou procurando a versão 9.3, mas podemos coletar todas as versões em um só lugar).

Matt Wilson
fonte
11
Uma sessão de perguntas e respostas relacionada, mas mais atualizada (incluindo o uso de arcpy.da.Walk) é Como fazer um inventário GIS?
blah238

Respostas:

34

Essa rotina do arcgis10 retorna todos os fcs (OR autônomo dentro de um conjunto de dados de recursos) dentro de um gdb. Apenas configure seu arcpy.env.workspace e faça um loop for

def listFcsInGDB():
    ''' set your arcpy.env.workspace to a gdb before calling '''
    for fds in arcpy.ListDatasets('','feature') + ['']:
        for fc in arcpy.ListFeatureClasses('','',fds):
            yield os.path.join(arcpy.env.workspace, fds, fc)
Gotchula
fonte
Legal e Limpo!
Chad Cooper
11
graças gotchula! Essa é a primeira vez que encontrei a declaração de rendimento, tive que ler um pouco para descobrir. Você esqueceu de observar que sua amostra é do arcgis v10.
226118 #
11
desculpe, sim, isso é para 10.x. e sim, o rendimento é ótimo, cria um código limpo.
gotchula
Obrigado gotchula, eu sei que este é um post antigo, mas eu achei isso muito útil para gerenciar um banco de dados que eu adiciono todas as semanas. Posso perguntar o que o + [''] realiza na terceira linha?
Dylan Warburg
11
Eu chamo arcpy.ListFeatureClasses dentro de um loop de arcpy.ListDatasets. Eu preciso incluir as classes de recurso que NÃO estão dentro de nenhum conjunto de dados de recurso (também conhecido como classe de recurso independente), então adiciono '' à lista de conjuntos de dados que faz com que ListFeatureClasses seja chamado com '' como a variável fds.
gotchula 27/02
12

Acabei usando a resposta de gotchula , mas sem rendimento, porque geralmente reutilizo os manipuladores FC criados e os rendimentos são usados ​​uma vez descartados. É mais fácil para mim ler e entender o quefcs.append() está fazendo do que fcs = yield(...).

def listFcsInGDB(gdb):
    ''' list all Feature Classes in a geodatabase, including inside Feature Datasets '''
    arcpy.env.workspace = gdb
    print 'Processing ', arcpy.env.workspace

    fcs = []
    for fds in arcpy.ListDatasets('','feature') + ['']:
        for fc in arcpy.ListFeatureClasses('','',fds):
            #yield os.path.join(fds, fc)
            fcs.append(os.path.join(fds, fc))
    return fcs

gdb = sys.argv [1]
fcs = listFcsInGDB(gdb)
for fc in fcs:
    print fc            

Resultados:

d:\> python list-all-fc.py r:\v5\YT_Canvec.gdb
Processing  r:\v5\YT_Canvec.gdb
Buildings_and_structures\BS_2530009_0
Buildings_and_structures\BS_2380009_2
Buildings_and_structures\Tower
Buildings_and_structures\Underground_reservoir
...

Isso agora está em um módulo que chamo de arcplus *. Coloque com seu outro código ou PYTHONPATH e depois:

import arcplus
fcs = arcplus.listAllFeatureClasses('d:\default.gdb')
for fc in fcs:
    print "magic happens with: ", fc

O Arcplus também adiciona filtragem de caracteres curinga; processar apenas classes de recursos que começam com "HD_" em conjuntos de dados de recursos que contêm "Hydro"

fcs = arcplus.listAllFeatureClasses(gdb, fd_filter='*Hydro*', fc_filter='HD_*')

. * agora no Github, atualizado para 10.x. Para o arcgis 9.3, veja aqui .

Matt Wilson
fonte
11
Não sei se entendi a lógica por trás de evitar o uso yielddaqui. Por um lado, as "alças" às quais você se refere não são alças, são apenas strings. E se sua intenção é manter a lista de classes de recursos por várias iterações, você ainda pode mantê-la como uma função de gerador e apenas "listificá-la": my_list = list(generator_function(args))isso avalia o gerador e armazena o resultado em uma variável de lista.
Blah238
@ blah238: oh. Eu acho que ainda não grok yield então. Eu entendo como uma declaração fcs = fcs.append(...)está fazendo muito mais rapidamente do que fcs = list(yield(...)).
27614 Matthew Matt wilkie
8

Sei que esta pergunta está com a tag 9.3, mas quem procura a mesma resposta a partir da 10.1 é melhor usar o arcpy.da.Walk . É mais rápido e preciso que o ListDatasets / FeatureClasses / Rasters / etc.

import arcpy
import os

for root, dirs, datasets in arcpy.da.Walk('d:\scratch.gdb'):
    for ds in datasets:
        print os.path.join(root, ds)

A função walk funciona da mesma maneira que a função python. walk . Ele itera pelos diretórios no caminho especificado e, a cada iteração, root representa o caminho completo do diretório, e dirs e conjuntos de dados são listas dos subdiretórios e arquivos contidos nele.

Ao percorrer um geodatabase, os conjuntos de dados dos recursos são tratados da mesma maneira que os diretórios. Se você deseja listar apenas os conjuntos de dados e os conjuntos de dados do recurso na pasta raiz e não abrir os conjuntos de dados do recurso para ver o conteúdo, é possível:

for root, dirs, datasets in arcpy.da.Walk('d:\scratch.gdb'):
    print 'feature datasets:'
    for fds in dirs:
        print os.path.join(root, fds)
    print 'datasets:'
    for ds in datasets:
        print os.path.join(root, ds)
    break
jon_two
fonte
Vou tomar mais rápido como um dado; você pode expandir para "mais preciso"? Obrigado.
22616 Matthew
ListDatasets, ListFeatureClasses, etc. nem sempre retornam os conjuntos de dados corretos. Além disso, você obtém resultados diferentes entre o SDE e o arquivo GDB. Não me lembro do problema exato, mas paramos de usar o arcpy.List ... porque não podíamos confiar nos resultados.
jon_two
5

O ListDatasets método é o que eu acho que você está procurando. Este FGDB possui um DF chamado "Wells" e possui 3 FCs. Para 9.3.1:

C:\WINDOWS\system32>python
Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import arcgisscripting
>>> gp=arcgisscripting.create(9.3)
>>> d='c:\data\Third_Party_Wells_PRD.gdb'
>>> gp.workspace = d
>>>
>>> fds=gp.ListDatasets('','Feature')
>>> for fd in fds:
...     print fd
...
Wells
>>> for fd in fds:
...     gp.workspace=d + '/' + fd
...     fcs=gp.ListFeatureClasses()
...     for fc in fcs:
...             print fc
...
Third_Party_Wells_BHL
Third_Party_Wells_LAT
Third_Party_Wells_SHL
>>>
Chad Cooper
fonte