Python程序实现批量创建/重建空间索引


在创建一个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关闭后,重新打开再执行程序。

附件:源代码和配置文件

转载自:https://blog.csdn.net/warrenjiang/article/details/49641585

You may also like...