Перечислить все классы объектов в Файловой базе геоданных, в том числе в наборах классов объектов?

24

Из python, как я могу построить список всех классов объектов в файловой базе геоданных (* .gdb), включая внутренние наборы классов объектов? В стандартном примере перечислены только классы пространственных объектов на верхнем уровне базы геоданных:

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

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

for fc in fcs:
    print fc

Укажите, к какой версии ArcGIS Desktop относится ваш ответ (я ищу 9.3, но мы могли бы также собрать все версии в одном месте).

Мэтт Уилки
источник
1
Связанный, но более актуальный вопрос и ответ (включая использование arcpy.da.Walk): Как сделать инвентаризацию ГИС?
blah238

Ответы:

34

Эта подпрограмма для arcgis10 возвращает все fcs (автономное ИЛИ в наборе классов объектов) внутри GDB. Просто установите свой arcpy.env.workspace и выполните цикл 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
источник
Красиво и чисто!
Чед Купер
1
спасибо, гучула! Это первый раз, когда я столкнулся с оператором yield, мне пришлось немного почитать, чтобы понять его. Вы забыли отметить, что ваш образец для ArcGIS V10.
Мэтт Уилки
1
извините, да, это для 10.х. и да, выход отличный, делает для чистого кода.
получил
Спасибо, я понял, что это старый пост, но я нашел его очень полезным для управления базой данных, к которой я добавляю каждую неделю. Могу ли я спросить вас, что делает + ['']: в 3-й строке?
Дилан Варбург
1
я вызываю arcpy.ListFeatureClasses внутри цикла arcpy.ListDatasets. Мне нужно включить классы объектов, которые НЕ находятся внутри какого-либо набора классов объектов (так называемый автономный класс объектов), поэтому я добавляю '' в список наборов данных, что вызывает вызов ListFeatureClasses с '' в качестве переменной fds.
Gotchula
12

Я закончил тем, что использовал ответ gotchula , но без выхода, потому что я, как правило, повторно использую созданные маркеры FC , а выходы используются один раз, а затем отбрасываются, мне легче читать и понимать, что fcs.append()делает 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            

Полученные результаты:

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

Теперь это в модуле, который я называю arcplus *. Поместите с другим кодом или PYTHONPATH, а затем:

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

Arcplus также добавляет фильтрацию по шаблону; обрабатывать только те классы объектов, которые начинаются с "HD_" в наборах классов объектов, содержащих "Hydro"

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

. * теперь на Github, обновлен до 10.x. Для arcgis 9.3 смотрите здесь .

Мэтт Уилки
источник
1
Не уверен, что понимаю причину отказа от использования yieldздесь. С одной стороны, «дескрипторы», на которые вы ссылаетесь, вовсе не дескрипторы, а просто строки. И если вы хотите сохранить список классов объектов для нескольких итераций, вы все равно можете сохранить его как функцию генератора и просто «прослушать» его: my_list = list(generator_function(args))это оценивает генератор и сохраняет результат в переменной списка.
blah238
@ blah238: ой. Я думаю, что я до сих пор не сдаюсь. Я понимаю, что такое утверждение fcs = fcs.append(...)делает гораздо быстрее, чем fcs = list(yield(...)).
Мэтт Уилки
8

Я понимаю, что этот вопрос помечен как 9.3, но всем, кто ищет тот же ответ в 10.1 и выше, лучше использовать arcpy.da.Walk . Это быстрее и точнее, чем 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)

Функция прогулки работает так же, как прогулка питона . Он выполняет итерацию по каталогам по заданному пути, и на каждой итерации root представляет полный путь к каталогу, а каталоги и наборы данных - это списки подкаталогов и файлов, содержащихся в них.

При обходе базы геоданных наборы классов объектов обрабатываются так же, как и каталоги. Если вы хотите перечислить только наборы данных и наборы классов объектов в корневой папке, а не открывать наборы классов объектов для просмотра содержимого, вы можете сделать следующее:

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
источник
Я возьму быстрее как данность; Вы можете расширить на "более точный", хотя? Спасибо.
Мэтт Уилки
ListDatasets, ListFeatureClasses и т. Д. Не всегда возвращают правильные наборы данных. Кроме того, вы получаете разные результаты между SDE и файлом GDB. Я не могу вспомнить точную проблему, но мы перестали использовать arcpy.List ... потому что мы не могли доверять результатам.
jon_two
5

ListDatasets Метод является то , что я думаю , что вы ищете. В этом FGDB есть FD, называемый "Wells", и в нем есть 3 FC. Для 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
>>>
Чед Купер
источник