列出文件地理数据库中的所有要素类,包括要素数据集中的所有要素类?


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)是如何制作GIS库存?
blah238 2014年

Answers:


34

arcgis10的此例程返回gdb中的所有fcs(要素数据集中的独立OR)。只需设置您的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)

干净整洁!
乍得·库珀,

1
谢谢gotchula!那是我第一次遇到yield语句,不得不做一些阅读才能弄清楚。您忘了注意样本是针对arcgis v10的。
马特·威尔基2011年

1
抱歉,是的,这是10.x版本。是的,产量很高,可以生成干净的代码。
gotchula 2011年

谢谢gotchula,我知道这是一篇老文章,但是我发现这对于管理每周添加的数据库非常有帮助。我可以问一下第三行中的[['']:完成什么吗?
迪伦·沃伯格

1
我在arcpy.ListDatasets循环内调用arcpy.ListFeatureClasses。我需要包括不在任何要素数据集中(也称为独立要素类)的要素类,因此我将''添加到数据集列表中,这导致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还添加了通配符过滤;在包含“ Hydro”的要素数据集中仅处理以“ HD_”开头的要素类

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

。* 现在在Github上,已升级为10.x。对于arcgis 9.3,请参见此处


1
不确定我是否了解避免使用yield此处的基本原理。首先,您所指的“句柄”根本不是句柄,它们只是字符串。而且,如果您打算保留要素类列表进行多次迭代,则仍然可以将其作为生成器函数保留并“列出”:my_list = list(generator_function(args))这将评估生成器并将结果存储在list变量中。
blah238 2014年

@ 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)

walk函数的工作方式与python的walk相同。它遍历给定路径中的目录,并且在每次迭代时,root代表目录的完整路径,而dirs和datasets是其中包含的子目录和文件的列表。

遍历地理数据库时,要素数据集的处理方式与目录相同。如果只想在根文件夹中列出数据集和要素数据集,而又不打开要素数据集以查看其内容,则可以执行以下操作:

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

我会更快一点。您可以扩展“更准确”吗?谢谢。
马特·威尔基

ListDatasets,ListFeatureClasses等并不总是返回正确的数据集。另外,您在SDE和文件GDB之间会得到不同的结果。我不记得确切的问题,但是我们停止使用arcpy.List ...,因为我们不信任结果。
jon_two

5

ListDatasets 方法是什么,我认为你正在寻找。该FGDB包含一个称为“ Wells”的FD,并且其中包含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
>>>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.