在创建一个Geodatabase之后,我们通常会根据项目需求,在其中创建很多要素类(Feature Class),无论是电子地图空间数据,还是业务图层空间数据,这些Feature Class一旦创建完后,就需要为他们一一创建空间索引。特别是那些数据量很大的Feature Class,如果没有创建空间索引,则会导致将来发布出来的地图服务或者要素服务漫游和缩放是,查询和绘制非常慢,给用户感觉非常的不友好。创建空间索引,大家第一个想到的是在ArcMAP中,在要素类的属性中进行创建或重建,或者使用ArcToolbox工具中的Add Spatial Index工具。具体路径为:System Toolboxes -> Data Management Tools -> Indexes -> Add Spatial Index,如下图所示:


但上述两种方法,只能对单个要素类创建/重建空间索引,如果一个空间数据库中要素类很多,这样效率很慢。而且有些要素类中的数据量特别大,比如上百万条数据,导致创建索引耗时很长。如果通过人工职守的方式一个个建过来,效率太低了。

因此,想到通过Arcpy使用python程序,来创建一个批量创建索引的工具。这样可以大大降低我们的工作量。(注:本程序是本人第一个Arcpy程序,Python语言也是刚接触。通过此文,纪念一下里程碑式的第一次。)

createSpatialIndex.py程序代码如下:
import os
import arcpy
#import arcpy.env as ENV
from arcpy import env as ENV
import time
#获取当前时间
def getNowTime():
return time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()))
#批量创建空间索引
def createSpatialIndex():
# Set workspace
#连接SDE GDB写法,用于为GDB下的Feature Class创建索引
ENV.workspace = "Database Connections/shtfm_webgis_newgis70.sde"
#连接File GDB写法,用于为GDB下的Feature Class创建索引
#ENV.workspace = "G:\jrrfilegdb\jrr.gdb"
#连接目录写法,用于为该目录下的shapefile文件创建索引
#ENV.workspace = "C:\data"
# get filename
ls = os.linesep
fname = "featureclasslist.txt";
logfilename = "result.log";
spatial_grid_1 = 0
spatial_grid_2 = 0
spatial_grid_3 = 0
message="START... " + getNowTime() + "\n"
allmessage=[]
allmessage.append(message)
print message,
try:
fobj = open(fname,'r')
except IOError,e:
print "*** file open error:",e
else:
# display contents to the screen
for eachLine in fobj:
in_feature = eachLine;
try:
# Execute AddSpatialIndex
arcpy.AddSpatialIndex_management(in_feature, spatial_grid_1)
message = "ok " + getNowTime() + " " + in_feature
allmessage.append(message)
print message,
except:
message = "error " + getNowTime() + " " + in_feature + arcpy.GetMessages()
allmessage.append(message)
print message,
fobj.close()
message = "\nDONE! " + getNowTime()
allmessage.append(message)
try:
fobj = open(logfilename,'w')
except IOError,e:
print "*** file open error:",e
else:
fobj.writelines(['%s%s' % (m,ls) for m in allmessage])
fobj.close()
print message,
#仅当本python模块直接执行时,才执行如下语句,若被别的python模块引入,则不执行
if __name__ == '__main__':
createSpatialIndex()

程序本身应该不难理解,通过循环调用arcpy.AddSpatialIndex_management创建空间索引的地理处理工具方法,实现批量创建空间索引的功能。其中和.py程序所在同一目录下的两个本文文件说明如下:

1.featureclasslist.txt


该配置文件配置了需要创建空间索引的要素类名称,格式为:数据库用户名.Dataset名称/数据库用户名.要素类名称

若要素类没有放在Dataset中,则格式为:数据库用户名.要素类名称

在执行程序前,用户必须根据实际需要创建的要素类配置此文件。

2.result.log


此日志文件用于写入索引创建/重建的结果,供用户查看创建失败的要素类。要素类前面为“ok”表示改要素类创建空间索引成功。若为error,则表示创建失败。最后的DONE!表示已完成所有要素类的空间索引创建/重建工作。

关于如何执行该.py程序,在此特别要注意。我的代码是在ArcMap外部的Python开发工具IDLE开发并保存为.py文件的。因此原则是可以在ArcMap外部环境直接执行的。但是我执行后发现会报如下错误:


说找不到对应的要素类。

经过一番研究发现,这个Python程序由于要连接SDE GDB才能够执行创建索引操作,但是不在ArcMap环境是无法连接到SDE GDB的。反过来说,如果是要给File GDB或者是给shapefile创建空间索引,由于这些文件都在本机文件系统中,因此完全可以在ArcMap环境之外来直接执行此Python程序。

因此,只能老老实实在ArcMap中执行本程序。执行方法为,启动ArcMap,然后点击上方工具栏中的Python Window工具,打开Python窗口。在窗口的空白处点击右键菜单,在弹出的快捷菜单中选择“Load…”,然后载入保存在磁盘上的.py文件,如下所示:


然后在代码的最后,按回车即可成功执行。

经过试验,执行该程序前,无需先用Catalog连接上该GDB,也能成功执行创建索引。但是如果先用了Catalog中要素类属性窗口手工创建了索引,再执行本程序,会出错,报错信息为别的应用程序已经锁定了该要素类。此时需要把ArcMap关闭后,重新打开再执行程序。