Wymieniasz wszystkie klasy obiektów w geobazie plików, w tym w zestawach danych obiektów?

24

W Pythonie, jak mogę zbudować listę wszystkich klas elementów w geobazie pliku (* .gdb), w tym w wewnętrznych zestawach danych elementów? Standardowy przykład tylko wymienia m.in. zajęcia na poziomie górnej części geobazie:

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

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

for fc in fcs:
    print fc

Wskaż wersję ArcGIS Desktop, której dotyczy Twoja odpowiedź (szukam 9.3, ale równie dobrze możemy zebrać wszystkie wersje w jednym miejscu).

matowe wilkie
źródło
1
Powiązane, ale bardziej aktualne pytania i odpowiedzi (w tym wykorzystanie arcpy.da.Walk) brzmią: Jak sporządzić wykaz GIS?
blah238

Odpowiedzi:

34

Ta procedura dla arcgis10 zwraca wszystkie fcs (samodzielne OR w zestawie danych funkcji) w gdb. Wystarczy ustawić obszar roboczy arcpy.env., a następnie wykonać pętlę 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
źródło
Ładnie i czysto!
Chad Cooper
1
dzięki gotchula! To pierwszy raz, kiedy spotkałem się z deklaracją dochodu, musiałem trochę przeczytać, aby to zrozumieć. Zapomniałeś zauważyć, że twoja próbka dotyczy arcgis v10.
matt wilkie
1
przepraszam, tak to jest dla 10.x. i tak, wydajność jest świetna, zapewnia czysty kod.
gotchula
Dzięki gotchula, wiem, że to jest stary post, ale właśnie to bardzo pomogło mi w zarządzaniu bazą danych, do której co tydzień dodaję. Czy mogę zapytać, co osiąga + ['']: w 3. linii?
Dylan Warburg
1
nazywam arcpy.ListFeatureClasses wewnątrz pętli arcpy.ListDatasets. Muszę dołączyć klasy funkcji, które NIE znajdują się w żadnym zestawie danych funkcji (inaczej samodzielna klasa funkcji), więc dodaję „” do listy zestawów danych, co powoduje, że ListFeatureClasses jest wywoływana z „” jako zmienną fds.
gotchula
12

Skończyło się na tym, że użyłem odpowiedzi gotchuli , ale bez dochodu, ponieważ generalnie ponownie używam utworzonych uchwytów FC, a zyski są używane raz, a potem odrzucane , łatwiej mi jest czytać i rozumieć, co fcs.append()się dzieje niż 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            

Wyniki:

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

To jest teraz w module, który nazywam arcplus *. Wpisz swój drugi kod lub PYTHONPATH, a następnie:

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

Arcplus dodaje również filtrowanie symboli wieloznacznych; przetwarzać tylko klasy elementów rozpoczynające się od „HD_” w zestawach danych elementów zawierających „Hydro”

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

. * teraz w Github, zaktualizowany do wersji 10.x. Arcgis 9.3 patrz tutaj .

matowe wilkie
źródło
1
Nie jestem pewien, czy rozumiem uzasadnienie unikania użycia yieldtutaj. Po pierwsze, „uchwyty”, o których mówisz, wcale nie są uchwytami, są tylko łańcuchami. A jeśli twoim zamiarem jest utrzymanie listy klas elementów dla wielu iteracji, nadal możesz zachować ją jako funkcję generatora i po prostu „listify”: my_list = list(generator_function(args))to ocenia generator i zapisuje wynik w zmiennej listy.
blah238
@ blah238: och. Wydaje mi się, że nadal nie wydaję się tak. Rozumiem, jak to zdanie fcs = fcs.append(...)działa znacznie szybciej niż fcs = list(yield(...)).
matt wilkie
8

Zdaję sobie sprawę, że to pytanie jest oznaczone jako 9.3, ale każdemu, kto szuka tej samej odpowiedzi od 10.1, lepiej jest użyć arcpy.da.Walk . Jest szybszy i dokładniejszy niż ListDatasets / FeatureClasses / Rasters / itp.

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)

Funkcja chodzenia działa w taki sam sposób, jak chodzenie Pythona . Iteruje przez katalogi w podanej ścieżce, a przy każdej iteracji root reprezentuje pełną ścieżkę katalogu, a katalogi i zestawy danych są listami zawartych w nim podkatalogów i plików.

Podczas przechodzenia przez geobazę zestawy danych obiektów są traktowane w taki sam sposób jak katalogi. Jeśli chcesz tylko wyświetlić zestawy danych i zestawy danych funkcji w folderze głównym, a nie otwierać zestawów danych funkcji, aby zobaczyć zawartość, możesz:

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
źródło
Biorę pod uwagę szybciej; czy możesz rozwinąć „dokładniejsze”? Dzięki.
matt wilkie
ListDatasets, ListFeatureClasses itp. Nie zawsze zwracają poprawne zestawy danych. Otrzymujesz także różne wyniki między SDE a plikiem GDB. Nie pamiętam dokładnego problemu, ale przestaliśmy używać arcpy.List ... ponieważ nie mogliśmy ufać wynikom.
jon_two
5

ListDatasets Metody jest to, co myślę, że szukasz. Ten FGDB ma FD o nazwie „Wells” i zawiera 3 FC. Dla 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
źródło