开始学习Python有几天的时间了,这些天每天对着电脑看枯燥的代码,自己都快崩溃了,终于功夫不负有心人,写出了自己的第一个批量处理工具:将文件夹中的shape文件批量导入到ArcGIS的File GeoDatabase中。工具界面如图一:

从图一看到,工具的界面并不复杂,只需要制定shape文件所在的文件夹和File GDB保存的路径就可以了。通过该工具,可以将指定文件夹根目录下所有的Shape文件和第一级子目录中所有的Shape文件转换到与根目录同名的File GDB数据库中,第一级子目录会转换为FileGDB中同名的Feature Dateset。此工具要求根目录及一级子目录中只能有Shape文件,子目录可以为空,但是空子目录同样会被转换为Feature Dateset。一级子目录中的Shape文件最好都具有相同的坐标系统。FileGDB存储的路径不能与输入的存储shape数据的路径相同,最好也不要放在它的子目录中。
因为是第一次制作工具,所以将代码贴出来,大家一同学习,欢迎批评指正。
# 导入系统模块 # import sys import os import arcgisscripting gp = arcgisscripting.create(9.3) # 定义工作空间 # Workspace = sys.argv[1] gp.Workspace = Workspace # 定义输出路径 # Output_GDB_Path = sys.argv[2] # 覆盖已存在文件 # gp.OverWriteOutput = 1 # 定义File GDB位置和名称 # File_GDB = Output_GDB_Path + os.sep + os.path.basename(gp.Workspace) + ".gdb" # 创建File GDB # gp.CreateFileGDB(Output_GDB_Path, os.path.basename(File_GDB)) # 打印数据库创建成功信息 # gp.AddMessage("++++++++++++++++++++++++++++") gp.AddMessage("数据库创建成功") # 读取工作空间下的所有shape文件 # Feature_Classes = gp.ListFeatureClasses() # 计算shape文件个数 # count1 = len(Feature_Classes) # 如果文件夹下存在shape文件,则逐个读取文件,并存入上面新建的FIleGDB中 # if count1 > 0: for Feature_Class in Feature_Classes: gp.CopyFeatures_management(Feature_Class,File_GDB + os.sep + Feature_Class[:-4]) # 读取工作空间下的文件夹 # Folder_Lists = os.listdir(gp.Workspace) # 如果工作空间下存在文件夹,则逐个读取文件夹名称 # for Folder_List in Folder_Lists: List_Element = gp.Workspace + os.sep + Folder_List # 如果读取的文件夹确实存在,则用文件夹名称建立要素数据集 # if os.path.isdir(List_Element): gp.workspace = gp.workspace + os.sep + Folder_List gp.CreateFeatureDataset_management(File_GDB,Folder_List) gp.AddMessage("++++++++++++++++++++++++++++") gp.AddMessage("要素数据集" + str(Folder_List) + "创建成功!") # 读取子目录中的shape文件,并确定shape文件个数 # Feature_Classes = gp.ListFeatureClasses() count2 = len(Feature_Classes) # 如果确实存在shape文件,则将子目录中的shape文件导入到要素数据集中 # if count2 > 0: for Feature_Class in Feature_Classes: gp.CopyFeatures_management(Feature_Class,File_GDB + os.sep + Folder_List + os.sep + Feature_Class[:-4]) gp.AddMessage("++++++++++++++++++++++++++++") gp.AddMessage(str(Folder_List) + "中所有文件复制完毕!") # 读取shape文件的空间坐标系统 # Dateset_SF = gp.describe(Feature_Class).SpatialReference # 将shape文件的空间坐标系统赋予要素数据集 # gp.DefineProjection_management(File_GDB + os.sep + Folder_List, Dateset_SF) gp.AddMessage("++++++++++++++++++++++++++++") gp.AddMessage(str(Folder_List) + "坐标系统定义成功!") gp.workspace = Workspace
上述代码是基于ArcGIS 9.x平台,在ArcGIS 10.x平台上运行情况未知。为此,笔者重写了代码,使其可以运行在ArcGIS10及以上的版本中。程序要求各文件夹中准备导入FileGDB的shape文件不存在重名情况,这主要是受FileGDB的特性影响,因此在导入数据前,会先进行检查,如果存在重名情况,会强行终止程序。另外,程序会覆盖已存在的数据库及文件,因此建议不要提前建立数据库,让程序自己建立即可。对于没有shapefile的空文件夹,不会建立同名Dataset。
# -*- coding: utf-8 -*- import os,sys import arcpy from arcpy import env def check_in_shps(in_path): print(u"开始检查输入的shapefile...") shps_list = {} env.workspace = in_path root_shps = arcpy.ListFeatureClasses() for root_shp in root_shps: shps_list[root_shp] = in_path sub_folders = os.listdir(in_path) for sub_folder in sub_folders: if os.path.isdir(os.path.join(in_path,sub_folder)): env.workspace = os.path.join(in_path, sub_folder) sub_folder_shps = arcpy.ListFeatureClasses() for sub_folder_shp in sub_folder_shps: if sub_folder_shp not in shps_list.keys(): shps_list[sub_folder_shp] = os.path.join(in_path,sub_folder) else: print(u"文件夹\"%s\"中的\"%s\"与\"%s\"中的文件重名!\n" % (sub_folder, sub_folder_shp,shps_list[sub_folder_shp])) shps_list = None sys.exit() else: continue print(u"输入的shapefile符合要求,开始将数据导入FileGDB。\n") shps_list = None def copy_shps_to_filegdb(in_path, out_filegdb): check_in_shps(in_path) if arcpy.Exists(out_filegdb) == 0: arcpy.CreateFileGDB_management(os.path.split(out_filegdb)[0], os.path.split(out_filegdb)[1], "9.3") print(u"指定的数据库不存在,已为您创建!\n") env.overwriteOutput = True env.workspace = in_path root_shps = arcpy.ListFeatureClasses() print(u"开始处理根目录下的shapefile...") for root_shp in root_shps: out_shp_path = out_filegdb + os.sep + os.path.splitext(root_shp)[0] arcpy.CopyFeatures_management(root_shp, out_shp_path) print(u" -\"%s\"已成功导入数据库!" % root_shp) print(u"根目录下的shapefile已经处理完毕!\n") sub_folders = os.listdir(in_path) for sub_folder in sub_folders: if os.path.isdir(os.path.join(in_path,sub_folder)): env.workspace = os.path.join(in_path,sub_folder) env.overwriteOutput = True sub_folder_shps_list = [] sub_folder_shps = arcpy.ListFeatureClasses() for sub_folder_shp in sub_folder_shps: sub_folder_shp = os.path.join(env.workspace,sub_folder_shp) sub_folder_shps_list.append(sub_folder_shp) if len(sub_folder_shps_list) == 0: print(u"\"%s\"目录为空,不创建任何数据集!\n" % sub_folder) continue else: if arcpy.Exists(out_filegdb + os.sep + sub_folder): print(u"数据集\"%s\"已存在,将覆盖其中的数据!!!" % sub_folder) else: print(u"开始处理\"%s\"文件夹下的shapefile..." % sub_folder) arcpy.CreateFeatureDataset_management(out_filegdb, sub_folder, sub_folder_shps_list[0]) for sub_folder_shp in sub_folder_shps_list: out_fc_name = os.path.splitext(os.path.split(sub_folder_shp)[1])[0] arcpy.CopyFeatures_management(sub_folder_shp, os.path.join(out_filegdb,sub_folder,out_fc_name)) print(u" -\"%s.shp\"已成功导入数据库!" % out_fc_name) print(u"文件夹\"%s\"下的shapefile已经处理完毕!\n" % sub_folder) print(u"所有shapefile处理完毕!\n") if __name__ == "__main__": in_path = u"D:\\path\\to\\folder" out_filegdb = u"D:\\path\\to\\filegdb" copy_shps_to_filegdb(in_path, out_filegdb)
大家可以移步本站下载区下载该ArcToolbox工具,有任何问题欢迎反馈。该工具在ArcGIS 9.3.1下测试通过。
你好, 网站不能下载附件了,能否将 发送至我的邮箱呢? tanglili0991@qq.com 非常感谢
怎么还有密码啊
额~,你下载的时候没有往下拉网页啊,下面有密码的,同意都是:www.sunzx.net
谢谢站长 可以加你QQ吗?
网站下面有电子信箱,可以联系到我。谢谢对本站的支持。
按照你的方法,我是了一下,还是不行!可能和我的运行环境有关系吧!再次站长的帮助
好吧,我回头找个ArcGIS 9.3的测试一下。你也可以升级到ArcGIS 9.3.1 试试,升级补丁下载地址:ed2k://|file|%5BESRI.ArcGIS.Desktop.9.3.1.Patch%5D.%5BESRI.ArcGIS.Desktop.9.3.1.Patch%5D.%5BESRI.ArcGIS.Desktop.9.3.1.Patch%5D.%5BESRI.ArcGIS.Desktop.9.3.1.Patch%5D.%5BESRI.ArcGIS.Desktop.9.3.1.Patch%5D.%5BESRI.ArcGIS.Desktop.9.3.1.Patch%5D.%5BESRI.ArcGIS.Desktop.9.3.1.Patch%5D.ESRI_ArcGIS_Desktop_9.3.1.msp|565277696|9b0a9d2dbd577f560169856319dc2a8d|h=6jslg72arsdlzoogrxuuu2o7mrttydks|/
或者点击这里下载:http://www.verycd.com/topics/2812953/
嗯!好的,谢谢你的帮助~回头有时间我也试一下
今天换了台电脑运行没有问题了!非常感谢!
就是感觉运行速度稍微有点慢,呵呵!我想如果引用featureclass to geodatabase会不会快一点,呵呵!个人建议,没有试验过,呵呵!再次感谢站长的帮助!
呵呵,不客气。
这个工具很实用!本人刚刚接触python,菜鸟一个,我想请教一下:一个文件夹下有多个子文件,每个子文件中有多个shp,我想把每个子文件夹中的shp文件导入一个以子文件夹命名的mdb中!(即以子文件名创建mdb数据库,然后顺便名称(如ds等)建立数据集,我子文件中的shp导入mdb数据库的数据集(ds)中),最后就是实现了每个子文件夹中的shp文件都导入各自的mdb中,而不是把所有数据都导入一个数据库中,不知道这个代码应该怎样写?望赐教!!
https://blog.sunzexiang.com/archives/1576.html
非常感谢您的帮助,我刚刚试了一下,运行会提示错误
我在arcgis9.3 sp1的运行环境运行之后,刚刚创建数据库之后,就出现999998的错误。
下面是运行的结果!
Executing: shape2MDB D:tts “D:New Folder”
Start Time: Fri May 04 21:35:31 2012
Running script shape2MDB…
>>===============BEGIN=================
> WorkSpace: D:ttsG48
> Personal GeoDatabase “D:ttsG48” Create Successful!!!
ERROR 999998: Unexpected Error.
Failed to execute (shape2MDB).
End Time: Fri May 04 21:35:33 2012 (Elapsed Time: 2.00 seconds)
我是在ArcGIS 9.3.1下测试的。你是直接下载的ArcToolbox工具,还是通过源代码重新编译的?
参考一下这个:http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?topicname=tool_errors_and_warnings:999998-999999
你也可以这样,把那个py文件进行编译,直接运行,而不要用Toolbox工具。修改其中的
INPUT_fOLDER_PATH = gp.GetParameterAsText(0)
OUTPUT_FOLDER_PATH = gp.GetParameterAsText(1)
两行,将gp.GetParameterAsText(0)和gp.GetParameterAsText(1)改为输入和输出的文件地址,形式是这样的:r”D:ttsG48″
我在9.3.1下测试通过,下面是日志:
Executing: shape2MDB G:progSHP2GDB G:progaaaa
Start Time: Sat May 05 00:13:27 2012
Running script shape2MDB…
>>===============BEGIN=================
> WorkSpace: G:progSHP2GDBline
> Personal GeoDatabase “line.mdb” Create Successful!!!
> “geol.shp” Copy to line.mdb Successful!!!
> “geolstr5000.shp” Copy to line.mdb Successful!!!
> “line_Create.shp” Copy to line.mdb Successful!!!
> WorkSpace: G:progSHP2GDBpoint
> Personal GeoDatabase “point.mdb” Create Successful!!!
> “Export_Output_2.shp” Copy to point.mdb Successful!!!
> WorkSpace: G:progSHP2GDBpolygon
> Personal GeoDatabase “polygon.mdb” Create Successful!!!
> “standb4.shp” Copy to polygon.mdb Successful!!!
> “standb4_clip.shp” Copy to polygon.mdb Successful!!!
> “stbuff5000.shp” Copy to polygon.mdb Successful!!!
>>================END==================
Completed script shape2MDB…
Executed (shape2MDB) successfully.
End Time: Sat May 05 00:14:24 2012 (Elapsed Time: 57.00 seconds)
经过测试,之前的错误是因为有空文件夹的事情。