基于Arcpy实现对MXD文件中图层数据源的批量更新

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名称是唯一的,不管它们是在要素数据集下还是数据库下。

猜你喜欢

转载自blog.csdn.net/u012413551/article/details/106579173