¿Listado de todas las clases de entidades en la Geodatabase de archivos, incluso dentro de los conjuntos de datos de entidades?

24

Desde python, ¿cómo puedo crear una lista de todas las clases de entidad en una geodatabase de archivos (* .gdb), incluidos los conjuntos de datos de entidades internas? El ejemplo estándar solo enumera las clases de entidad en el nivel superior de la 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 qué versión de ArcGIS Desktop se aplica su respuesta (estoy buscando 9.3 pero también podríamos recopilar todas las versiones en un solo lugar).

wilkie mate
fuente
1
Un Q&A relacionado pero más actualizado (incluido el uso de arcpy.da.Walk) es ¿Cómo hacer un inventario SIG?
blah238

Respuestas:

34

Esta rutina para arcgis10 devuelve todos los fcs (OR independiente dentro de un conjunto de datos de características) dentro de un gdb. Simplemente configure su arcpy.env.workspace y luego haga un bucle 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
fuente
¡Bonito y limpio!
Chad Cooper
1
gracias gotchula! Esa es la primera vez que me encuentro con la declaración de rendimiento, tuve que leer un poco para descubrirlo. Olvidó notar que su muestra es para arcgis v10.
Matt Wilkie
1
lo siento, sí, esto es para 10.x. y sí, el rendimiento es excelente, hace un código limpio.
gotchula
Gracias gotchula, sé que esta es una publicación antigua, pero me pareció muy útil para administrar una base de datos a la que agrego cada semana. ¿Puedo preguntarte qué logra el + ['']: en la tercera línea?
Dylan Warburg el
1
Llamo a arcpy.ListFeatureClasses dentro de un bucle de arcpy.ListDatasets. Necesito incluir las clases de características que NO están dentro de ningún conjunto de datos de características (también conocido como clase de entidad independiente), por lo que agrego '' a la lista de conjuntos de datos que hace que se llame a ListFeatureClasses con '' como la variable fds.
gotchula
12

Terminé usando la respuesta de Gotchula , pero sin rendimiento porque generalmente reutilizo las manijas FC creadas y las de rendimiento se usan una vez descartadas , es más fácil para mí leer y comprender qué fcs.append()está haciendo 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
...

Esto está ahora en un módulo que llamo arcplus *. Coloque con su otro código o PYTHONPATH y luego:

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

Arcplus también agrega filtrado de comodines; para procesar solo clases de entidad que comienzan con "HD_" dentro de conjuntos de datos de entidades que contienen "Hydro"

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

. * ahora en Github, actualizado para 10.x. Para arcgis 9.3 ver aquí .

wilkie mate
fuente
1
No estoy seguro de entender la razón detrás de evitar el uso de yieldaquí. Por un lado, los "identificadores" a los que se refiere no son identificadores, son solo cadenas. Y si su intención es mantener la lista de clases de entidad para múltiples iteraciones, aún puede mantenerla como una función generadora y simplemente "listarla": my_list = list(generator_function(args))esto evalúa el generador y almacena el resultado en una variable de lista.
blah238
@ blah238: oh. Supongo que todavía no logro rendir. Entiendo lo que hace una declaración fcs = fcs.append(...)mucho más rápido que fcs = list(yield(...)).
Matt Wilkie
8

Me doy cuenta de que esta pregunta está etiquetada con 9.3, pero cualquier persona que busque la misma respuesta en 10.1 en adelante está mejor usando arcpy.da.Walk . Es más rápido y más preciso que 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)

La función de caminar funciona de la misma manera que la caminata de Python . Se itera a través de los directorios en la ruta dada y en cada iteración, la raíz representa la ruta completa del directorio, y los directorios y conjuntos de datos son listas de los subdirectorios y archivos contenidos dentro.

Al recorrer una geodatabase, los conjuntos de datos de entidades se tratan de la misma manera que los directorios. Si solo desea enumerar los conjuntos de datos y conjuntos de datos de características en la carpeta raíz y no abrir los conjuntos de datos de características para ver el contenido, puede hacer lo siguiente:

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
fuente
Tomaré más rápido como un hecho; sin embargo, ¿puedes ampliar "más preciso"? Gracias.
Matt Wilkie
ListDatasets, ListFeatureClasses, etc. no siempre devuelven los conjuntos de datos correctos. Además, obtiene resultados diferentes entre SDE y el archivo GDB. No recuerdo el problema exacto, pero dejamos de usar arcpy.List ... porque no podíamos confiar en los resultados.
jon_two
5

El ListDatasets método es lo que creo que estás buscando. Este FGDB tiene un FD llamado "Wells" y tiene 3 FC. 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
fuente