来自:https://blog.csdn.net/gisinfo/article/details/6675390

在许多情况下,您都可能需要修复数据源或重定向数据源至其他位置。然而,如果是在每个相关的地图文档中手动进行更改,则会显得异常麻烦。arcpy.mapping 脚本环境提供了多种方法使得您无需打开地图文档即可自动进行更改。您可针对各个图层逐一更新数据源,也可一次更新同一工作空间中的所有图层。各方法的帮助主题都提供了简要介绍,而此文档的目的在于对这些方法进行概括和比较。

TableView 类。这些方法的功能相互间互有重复;因此,可通过多种方法更新图层或表的工作空间或数据集。此文档的目的在于讨论所有方法并针对许多常见情景提供最佳操作建议。

以下是本文档中所使用的一些术语的定义:

  • 工作空间是一种数据容器。工作空间可以是包含 shapefile、CAD 文件或栅格数据等内容的文件夹,也可以是 ArcInfo coverage、个人地理数据库、文件地理数据库和 SDE 连接等。
  • 工作空间路径是指工作空间的系统路径。对于基于文件的数据(如 CAD、shapefile 或栅格),工作空间路径包括了该数据所在的文件夹的名称。对于基于文件的地理数据库,工作空间路径包括地理数据库的名称。SDE 工作空间路径由 SDE 连接文件的系统路径所定义。
  • 数据集是指工作空间中的要素类或表。数据集的名称是工作空间中此对象的名称,而不是地图文档的内容列表中所显示的样式。
  • 图层或表的数据源是工作空间和数据集的组合。

用于更新和修复数据源的方法

  • MapDocument.findAndReplaceWorkspacePaths(find_workspace_path, replace_workspace_path, {validate})
    • findAndReplaceWorkspacePaths 方法专用于在共享某工作空间路径的地图文档中执行全局查找并替换所有图层和表的工作空间路径。此方法可一次替换多种工作空间类型的路径(例如,CAD 文件、shapefile、文件地理数据库)。
  • MapDocument.replaceWorkspaces(old_workspace_path, old_workspace_type, new_workspace_path, new_workspace_type, {validate})
    • findAndReplaceWorkspacePaths 方法类似,但是前者还允许用户从一种工作空间类型切换至另一工作空间类型(例如,从个人地理数据库切换至文件地理数据库)。通常,此方法一次只处理一种工作空间类型。如果需要替换多种工作空间类型,则只需针对每种工作空间类型重复调用此方法即可。有关其他用法,请参阅下面的“一般用法说明”。
  • Layer.findAndReplaceWorkspacePath(find_workspace_path, replace_workspace_path, {validate})
    • findAndReplaceWorkspacePath 方法专用于在地图文档或图层文件中执行查找并替换单个图层的工作空间路径。
  • Layer.replaceDataSource(workspace_path, workspace_type, dataset_name, {validate})
    • findAndReplaceWorkspacePath 方法类似,但除了可更改工作空间外,前者还可更改数据集。这是在工作空间内替换图层数据集的唯一方法。此方法在新的工作空间中数据集名称发生变化的情况下尤为有用。
  • TableView.findAndReplaceWorkspacePath(find_workspace_path, replace_workspace_path, {validate})
    • findAndReplaceWorkspacePath 方法专用于在地图文档中执行查找并替换单个表的工作空间路径。
  • TableView.replaceDataSource(workspace_path, workspace_type, dataset_name, {validate})
    • findAndReplaceWorkspacePath 方法类似,但除了可更改工作空间外,该方法还可以更改数据集。这是在工作空间内替换表数据集的唯一方法。此方法在新的工作空间中数据集名称发生更改的情况下尤为有用。

一般用法说明

  • ListBrokenDataSources() 函数对于确定地图文档或图层文件中损坏的图层或表很有用。
  • 这些方法对所有图层和表进行递归处理。这意味着,还会搜索和更新连接表和关联表(请参阅下面的“已知局限性”部分)。
  • 不要在工作空间路径中加入要素数据集的名称。要素数据集是工作空间的组成部分。例如,如果将要素类从独立要素类移到要素数据集中,则地图文档会忽略损坏图层而正常打开。
  • replaceDataSource 方法即可应对此种情况。
  • replaceDataSource 方法。
    • NONE 结合使用。

可选参数 validate

  • 此参数用于验证是否成功更改或替换了图层或表的数据源。
  • True(默认值)且新数据源有效,则更新原始数据源;否则,将继续指向原始数据源。
  • False。
    • replace_workspace_path 参数中。
    • False,则图层或表所使用的数据集不必保存在新的工作空间中。

使用 SDE 连接

  • 脚本中使用的 SDE 连接文件信息必须与用来将数据添加到地图文档或图层文件的 SDE 连接相同。例如,两个不同的位置可以具有两个相同的 SDE 连接。如果已使用第一个连接文件路径将数据添加到地图中,但在脚本中使用的是第二个连接文件路径,则数据源将不会按预期进行更新。
    • Layer 和 TableView 对象的 dataSource 属性可用于确定地图文档或图层文件中所用的路径。使用此值有助于确定应使用哪个 SDE 连接文件路径。
  • validate=False;否则,密码信息仍将存在,因为操作将会失败。

已知局限性

  • 由于逻辑示意图数据集设计中包含隐藏表,因此无法对其更新。
  • 目前不支持直接与 SQL Server Express 数据库建立数据库服务器连接。一种解决办法是,改为创建与 SQL Server Express 数据库的空间数据库连接并加以使用。
  • 与栅格图层有关的连接和关联不会进行更新。
  • definitionQuery 属性可更正语法。可通过简单的 Python 字符串函数来执行基本的搜索和替换操作。例如,
    • _)。

    • 个人地理数据库中的字符串搜索不区分大小写,但在文件地理数据库中则区分大小写。

    • LOWER。

    • date 开头。

  • expression 属性可更正语法。
  • 设置数据源时也是如此)。除了手动重新创建地图文档要素选择外,目前没有其他解决方法。
  • 使用图层名称隔离数据源并非完全可靠,因为可能存在多个数据源具有相同图层名称的情况。可能有必要使用其他图层属性来唯一隔离图层。
  • 将地图文档或图层文件中的图层或表移入或移出要素数据集时,应确保其连接不会受到损坏。地图文档和图层文件可在同一地理数据库工作空间中自动重映射这些更改。不要在工作空间路径中加入要素数据集名称。这种方法不可行。提供包括要素数据集的工作空间的路径即可。

常见情景

基于文件的数据被移至其他文件夹或放到其他网络驱动器中

映射的网络驱动器字母或数据位置的文件夹结构发生了更改,或出现了一些其他情况导致与需要更新的现有数据的连接中断。在这种情况下,仅需将相同数据源重定向到新的文件夹位置或驱动器名称。这种情况几乎适用于包括空间数据库连接文件的所有基于文件的数据结构(例如,shapefile、CAD 数据、个人地理数据库和文件地理数据库以及基于文件的栅格)。

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 路径

在此情况下,用户希望与可访问其驱动器的其他员工共享地图文档,并且希望员工不必将数据复制到本地驱动器上即可成功打开地图文档。

这种情况涉及到将本地系统路径更改为 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

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 连接。由于各地理数据库工作空间存在着细微的差别,因此建议您查看上述“已知局限性”部分以便更好地了解其他可能需要解决的问题。

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

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")

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

将单个数据集移到新的文件夹位置

有些情况下,用户只需要移动单个数据集而不是整个工作空间。有时,不用尝试更新地图文档中的所有图层,仅仅集中处理已移动的各项目就可以达到目的。

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

将单个数据集移入和移出要素数据集

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

要素类被重命名

方案变更很普遍,有时要素类的名称也会发生更改。这种情况下,指向该数据集的所有图层必然会发生损坏。

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

相关文章:

  • 2021-10-17
  • 2022-02-01
  • 2022-12-23
  • 2021-11-22
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-11-01
  • 2021-08-19
  • 2021-11-05
  • 2021-10-06
相关资源
相似解决方案