Auflisten aller Feature-Classes in File Geodatabase, einschließlich Feature-Datasets?

24

Wie kann ich mit Python eine Liste aller Feature-Classes in einer File-Geodatabase (* .gdb) erstellen, auch innerhalb von Feature-Datasets? Im Standardbeispiel werden nur Feature-Classes auf der obersten Ebene der Geodatabase aufgelistet:

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

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

for fc in fcs:
    print fc

Bitte geben Sie an, auf welche ArcGIS Desktop-Version Ihre Antwort zutrifft (ich suche nach 9.3, wir können jedoch auch alle Versionen an einem Ort sammeln).

Matt Wilkie
quelle
1
Eine verwandte, aber aktuellere Frage und Antwort (einschließlich der Verwendung von arcpy.da.Walk) lautet: Wie erstelle ich ein GIS-Inventar?
blah238

Antworten:

34

Diese Routine für arcgis10 gibt alle fcs (Standalone-OR in einem Feature-Dataset) in einer GDB zurück. Legen Sie einfach Ihren arcpy.env.workspace fest und führen Sie dann eine for-Schleife aus

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
quelle
Schön und sauber!
Chad Cooper
1
danke gotchula! Das war das erste Mal, dass ich auf die Ertragsaussage gestoßen bin und ein bisschen lesen musste, um es herauszufinden. Sie haben vergessen zu notieren, dass Ihr Beispiel für arcgis v10 ist.
Matt Wilkie
1
Entschuldigung, ja das ist für 10.x. und ja, die Ausbeute ist großartig, sorgt für sauberen Code.
Gotchula
Danke Gotchula, ich weiß, dass dies ein alter Beitrag ist, aber ich fand ihn gerade sehr hilfreich für die Verwaltung einer Datenbank, die ich jede Woche hinzufüge. Kann ich Sie fragen, was das + ['']: in der 3. Zeile bewirkt?
Dylan Warburg
1
ich rufe arcpy.ListFeatureClasses innerhalb einer Schleife von arcpy.ListDatasets auf. Ich muss die Feature-Classes einbeziehen, die sich NICHT in einem Feature-Dataset (auch als eigenständige Feature-Class bezeichnet) befinden. Daher füge ich der Liste der Datasets '' hinzu, wodurch ListFeatureClasses mit '' als fds-Variable aufgerufen wird.
Gotchula
12

Am Ende habe ich die Antwort von gotchula verwendet , aber ohne Rendite, da ich die erstellten FC-Handles im Allgemeinen wieder verwende und die Rendite-Handles einmal verwendet und dann verworfen habe. Es ist für mich einfacher zu lesen und zu verstehen, was getan fcs.append()wird, als 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            

Ergebnisse:

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
...

Dies ist jetzt in einem Modul, das ich arcplus * nenne . Platzieren Sie mit Ihrem anderen Code oder PYTHONPATH und dann:

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

Arcplus fügt außerdem eine Platzhalterfilterung hinzu. nur Feature-Classes verarbeiten, die mit "HD_" beginnen, in Feature-Datasets, die "Hydro" enthalten

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

. * jetzt auf Github, aktualisiert auf 10.x. Arcgis 9.3 finden Sie hier .

Matt Wilkie
quelle
1
Ich bin nicht sicher, ob ich die Gründe verstehe, die dahinter stecken, die Verwendung yieldhier zu vermeiden . Zum einen sind die "Handles", auf die Sie sich beziehen, überhaupt keine Handles, sondern nur Zeichenfolgen. Wenn Sie die Liste der Feature-Classes für mehrere Iterationen beibehalten möchten, können Sie sie dennoch als Generatorfunktion beibehalten und nur "auflisten": my_list = list(generator_function(args))Dadurch wird der Generator ausgewertet und das Ergebnis in einer Listenvariablen gespeichert .
blah238
@ blah238: oh. Ich glaube, ich habe dann immer noch keinen Grok Yield. Ich verstehe, wie eine Aussage fcs = fcs.append(...)viel schneller geht als fcs = list(yield(...)).
Matt Wilkie
8

Mir ist klar, dass diese Frage mit 9.3 markiert ist, aber wer ab 10.1 nach der gleichen Antwort sucht, ist mit arcpy.da.Walk besser aufgehoben . Es ist schneller und genauer als ListDatasets / FeatureClasses / Raster / 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)

Die Walk-Funktion funktioniert genauso wie der Python- Walk . Es durchläuft die Verzeichnisse im angegebenen Pfad und bei jeder Iteration stellt root den vollständigen Pfad des Verzeichnisses dar und Verzeichnisse und Datasets sind Listen der darin enthaltenen Unterverzeichnisse und Dateien.

Beim Durchlaufen einer Geodatabase werden Feature-Datasets wie Verzeichnisse behandelt. Wenn Sie nur die Datasets und Feature-Datasets im Stammordner auflisten und die Feature-Datasets nicht öffnen möchten, um den Inhalt anzuzeigen, haben Sie folgende Möglichkeiten:

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
quelle
Ich werde als gegeben schneller nehmen; Können Sie jedoch genauer auf "genauer" eingehen? Vielen Dank.
Matt Wilkie
ListDatasets, ListFeatureClasses usw. geben nicht immer die richtigen Datensätze zurück. Außerdem erhalten Sie unterschiedliche Ergebnisse zwischen SDE und der Datei GDB. Ich kann mich nicht genau an das Problem erinnern, aber wir haben die Verwendung von arcpy.List eingestellt ... weil wir den Ergebnissen nicht vertrauen konnten.
jon_two
5

Die ListDatasets Methode ist genau das, wonach Sie suchen. Diese FGDB enthält eine FD namens "Wells" und 3 FCs. Für 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
quelle