1、常规方法
ArcGIS中批量更新数据源一般可以在ArcCatalog中进行,如下图:
通常情况下,我们的mxd数据源从一个文件夹或者数据库, 迁移到另一个文件夹或者数据库,数据根目录发生了变化,图层名并没有变化,可使用此方法。
2、基于Arcpy
偶然也有一些特殊情况,如老的数据源和新数据源均在同一数据库,但是图层名称有变化,通常有经验的老GISER会用一些前缀或者后缀来区分新老数据。这个时候,如果要更新数据源,可参考下来方法。
以下代码实现:
1、getTabList方法获取SDE连接中第一个数据集里面的所有表(图层)
2、replaceSource方法读取mxd中的图层并替换其中的图层数据源,新数据源来自getTabList方法,替换规则:将"SZ_"开头的图层替换为"GZ_"开头的图层。
import arcpy
ws = r'SDE Connection'
# 获取数据源列表
def getTabList():
arcpy.env.workspace = ws
dataSets = arcpy.ListDatasets(feature_type = 'feature')
ds = dataSets[0]
tbList = []
if(ds):
tbList = arcpy.ListFeatureClasses(feature_dataset=ds)
return tbList
# 检查打印数据源
def check(mxdPath):
mxd = arcpy.mapping.MapDocument(mxdPath)
for lyr in arcpy.mapping.ListLayers(mxd):
if lyr.supports('DATASOURCE'):
source = lyr.dataSource
print source
# 替换mxd的数据源
def replaceSource(mxdPath):
mxd = arcpy.mapping.MapDocument(mxdPath)
tbList = getTabList()
for lyr in arcpy.mapping.ListLayers(mxd):
if lyr.supports('DATASOURCE'):
source = lyr.dataSource
if(source.startswith('SZ_')):
workspace = lyr.workspacePath
datasetName = lyr.datasetName
newDatasetName = datasetName.replace('SZ_', 'GZ_')
if(newDatasetName in tbList):
lyr.replaceDataSource(workspace, 'SDE_WORKSPACE', newDatasetName)
lyr.name = newDatasetName
else:
print 'not found table %s'%newDatasetName
if __name__ == "__main__":
maxPath = r'E:\work\city.mxd'
replaceSource(maxPath)
代码里lyr.replaceDataSource方法的参数,有三个:
1、workspace_path,工作空间路径
2、workspace_type,工作空间类型
3、dataset_name,数据集名称
4、validate(可选,布尔型),验证workspace_path。当值为True(默认值)时,仅当如果workspace_path为有效值时才更新工作空间,无效则不会更新;如果为False时,则不管workspace_path是否有效都会更新,这个可能导致数据源无效。
arcpy里的replaceDataSource方法参数介绍如下:
注意参数:
如果数据源是在数据库中的要素数据集Feature Dataset下面的要素类Feature Class:
workspace_path参数依然是数据连接路径(不包含要素数据集Feature Dataset这一层)
dataset_name参数: 要素类Feature Class的名字(也不包含要素数据集Feature Dataset这一层)
我曾担心,如果数据库中还有同名的要素集(并不在同一个要素数据集Feature Dataset里),那怎么区分?
答案是在同一个数据库中,要素类Feature Class名称是唯一的,不管它们是在要素数据集下还是数据库下。