来自:https://blog.csdn.net/gisinfo/article/details/6675390
在许多情况下,您都可能需要修复数据源或重定向数据源至其他位置。然而,如果是在每个相关的地图文档中手动进行更改,则会显得异常麻烦。arcpy.mapping 脚本环境提供了多种方法使得您无需打开地图文档即可自动进行更改。您可针对各个图层逐一更新数据源,也可一次更新同一工作空间中的所有图层。各方法的帮助主题都提供了简要介绍,而此文档的目的在于对这些方法进行概括和比较。
实际上,基本存在两种不同的方法用于处理 MapDocument、Layer 和 TableView 类。这些方法的功能相互间互有重复;因此,可通过多种方法更新图层或表的工作空间或数据集。此文档的目的在于讨论所有方法并针对许多常见情景提供最佳操作建议。
以下是本文档中所使用的一些术语的定义:
个人地理数据库的通配符为星号 (*) 和问号 (?),而文件地理数据库的通配符则为百分号 (%) 和下划线 (_)。
个人地理数据库中的字符串搜索不区分大小写,但在文件地理数据库中则区分大小写。
个人地理数据库使用 UCASE 和 LCASE 转换字符串大小写。文件地理数据库使用 UPPER 和 LOWER。
个人地理数据库使用井号 (#) 分隔日期和时间,而在文件地理数据库中它们以单词 date 开头。
映射的网络驱动器字母或数据位置的文件夹结构发生了更改,或出现了一些其他情况导致与需要更新的现有数据的连接中断。在这种情况下,仅需将相同数据源重定向到新的文件夹位置或驱动器名称。这种情况几乎适用于包括空间数据库连接文件的所有基于文件的数据结构(例如,shapefile、CAD 数据、个人地理数据库和文件地理数据库以及基于文件的栅格)。
在此情景中,原本直接位于 C:\Project\Data 文件夹下的数据被移到称为 Data2 的子文件夹下。此脚本将更新单个地图文档。
import arcpy mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd") mxd.findAndReplaceWorkspacePaths(r"C:\Project\Data", r"C:\Project\Data2") mxd.saveACopy(r"C:\Project\Project2.mxd") del mxd
在此情况下,用户希望与可访问其驱动器的其他员工共享地图文档,并且希望员工不必将数据复制到本地驱动器上即可成功打开地图文档。
这种情况涉及到将本地系统路径更改为 UNC 路径。以下脚本将更新文件夹中的所有地图文档。
import arcpy, os folderPath = r"C:\Project" for filename in os.listdir(folderPath): fullpath = os.path.join(folderPath, filename) if os.path.isfile(fullpath): basename, extension = os.path.splitext(fullpath) if extension.lower() == ".mxd": mxd = arcpy.mapping.MapDocument(fullpath) mxd.findAndReplaceWorkspacePaths(r"C:\Project\Data", r"\\ComputerName\Project\Data") mxd.save() del mxd
出现这种情况的原因有很多 - 可能是服务器名称和/或端口号发生更改;连接包括登录凭据,但出于安全考虑需要将其移除;密码被更改;连接由 3 层连接更改为 2 层直连;或者希望将图层指向不同的版本。无论哪种情况,修改空间数据库连接属性时,只需将路径传递到连接文件即可。
在此情景中,用户希望更改所有地图图层的地理数据库版本。用户仅需创建一个新的空间数据库连接文件,然后将原始连接文件替换为新的空间数据库连接文件。
import arcpy mxd = arcpy.mapping.MapDocument(r"C:\Project\Project_default.mxd") mxd.findAndReplaceWorkspacePaths(r"C:\Project\Connection to Default.sde", r"C:\Project\Connection to Version1.sde") mxd.saveACopy(r"C:\Project\Project_V1.mxd") del mxd
在此情况下,用户希望移除地图文档中保存的密码信息。地图文档中的数据源来自于一个保存有密码信息的连接文件。接下来,用户为同一数据库创建了新的 SDE 连接文件,但这次未保存密码信息。在以下脚本中,必须将 validate 参数设置为 False 才能成功移除密码信息。脚本运行完毕后,用户需要登录才能打开生成的地图文档。
import arcpy mxd = arcpy.mapping.MapDocument(r"C:\Project\Project_default.mxd") mxd.findAndReplaceWorkspacePaths(r"C:\Project\Connection with password info saved.sde", r"C:\Project\Connection with no password info saved.sde", False) mxd.saveACopy(r"C:\Project\Project_NP.mxd") del mxd
某些通常情况下,用户需要将 shapefile 和个人地理数据库等数据迁移到文件地理数据库或从文件地理数据库迁移到企业级 SDE 连接。由于各地理数据库工作空间存在着细微的差别,因此建议您查看上述“已知局限性”部分以便更好地了解其他可能需要解决的问题。
这种情况涉及在一个地图文档中更新两个不同的工作空间。首先,将 shapefile 重定向到一个称为 Parcels.gdb 的文件地理数据库。然后,将个人地理数据库中的图层重定向到另一个名为 Transportation.gdb 的文件地理数据库。
import arcpy mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd") mxd.replaceWorkspaces(r"C:\Project\Data", "SHAPEFILE_WORKSPACE", r"C:\Project\Data\Parcels.gdb", "FILEGDB_WORKSPACE") mxd.replaceWorkspaces(r"C:\Project\Data\Transportation.mdb", "ACCESS_WORKSPACE", r"C:\Project\Data\Transportation.gdb", "FILEGDB_WORKSPACE") mxd.saveACopy(r"C:\Project\Project2.mxd") del mxd
除了所有数据源被定向到单个文件地理数据库外,此示例与上面的示例完全相同。如果使用值 NONE 代替 old_workspace_factory_type 参数,则可以将多个工作空间类型重定向到单个工作空间类型。
import arcpy mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd") mxd.replaceWorkspaces(r"C:\Project\Data", "NONE", r"C:\Project\Data\BackgroundData.gdb","FILEGDB_WORKSPACE") mxd.saveACopy(r"C:\Project\Project2.mxd")
在以下情景中,将个人地理数据库中的所有图层重定向到文件地理数据库。它还可以修复图层的 definitionQuery 属性和标注类的 SQLQuery 属性的 SQL 表达式。例如,个人地理数据库的字段名称用方括号 ([]) 括起来,而文件地理数据库则使用双引号 ("")。通配符也将被替换。
import arcpy mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd") mxd.replaceWorkspaces(r"C:\Project\Data\Parcels.mdb", "ACCESS_WORKSPACE", r"C:\Project\Data\Parcels.gdb", "FILEGDB_WORKSPACE") for lyr in arcpy.mapping.ListLayers(mxd): if lyr.supports("DEFINITIONQUERY"): lyr.definitionQuery = lyr.definitionQuery.replace("[", "\"") lyr.definitionQuery = lyr.definitionQuery.replace("]", "\"") lyr.definitionQuery = lyr.definitionQuery.replace("*", "%") if lyr.supports("LABELCLASSES"): for lblClass in lyr.labelClasses: lblClass.SQLQuery = lblClass.SQLQuery.replace("[", "\"") lblClass.SQLQuery = lblClass.SQLQuery.replace("]", "\"") lblClass.SQLQuery = lblClass.SQLQuery.replace("*", "%") mxd.saveACopy(r"C:\Project\Project2.mxd") del mxd
有些情况下,用户只需要移动单个数据集而不是整个工作空间。有时,不用尝试更新地图文档中的所有图层,仅仅集中处理已移动的各项目就可以达到目的。
在该情景中,将名为 MapIndex 的要素类从 Data 文件夹下的文件地理数据库移到 Data2 文件夹下的文件地理数据库副本。
import arcpy mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd") for lyr in arcpy.mapping.ListLayers(mxd): if lyr.supports("DATASOURCE"): if lyr.dataSource == r"C:\Project\Data\Parcels.gdb\MapIndex": lyr.findAndReplaceWorkspacePath(r"Data", r"Data2") mxd.saveACopy(r"C:\Project\Project2.mxd") del mxd
要素数据集是工作空间的组成部分,而且它们的名称不应包括在工作空间路径中。如果在同一工作空间中将要素类移入或移出要素数据集,则不应更新地图文档或图层文件数据源。如果将数据集移到同一类型的其他工作空间,则只需提供新工作空间的路径而无需要素数据集名称。如果工作空间类型不同,则对图层调用 findAndReplaceWorkspacePath 将不起作用,您需要改为调用 replaceDataSource。
在此情景中,某个文件地理数据库中的独立要素类会被移动到其他文件地理数据库(但是位于不同的文件夹)中的要素数据集。
import arcpy mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd") for lyr in arcpy.mapping.ListLayers(mxd): if lyr.supports("DATASOURCE"): if lyr.dataSource == r"C:\Project\Data\Parcels.gdb\MapIndex": lyr.findAndReplaceWorkspacePath(r"Data", r"Data2") mxd.saveACopy(r"C:\Project\Project2.mxd") del mxd
方案变更很普遍,有时要素类的名称也会发生更改。这种情况下,指向该数据集的所有图层必然会发生损坏。
在此情景中,将要素类由 MajorRoads 重命名为 Highways,从而导致地图文档或图层文件中的各图层发生了损坏。该脚本将调用ListBrokenDataSources() 函数查找损坏的数据源,并执行相应的修复操作。
import arcpy mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd") for lyr in arcpy.mapping.ListBrokenDataSources(mxd): if lyr.supports("DATASOURCE"): if lyr.dataSource == r"C:\Project\Data\Transportation.gdb\MajorRoads": lyr.replaceDataSource(r"C:\Project\Data\Transportation.gdb", "FILEGDB_WORKSPACE", "Highways") lyr.name = "Highways" mxd.saveACopy(r"C:\Project\Project2.mxd") del mxd
原文:https://www.cnblogs.com/gisoracle/p/10846809.html