ArcGIS Python编程案例(4)-查找和修复数据源

第三章 管理地图文档和图层 ||| 第五章 自动化地图生产和打印


我们将在本章介绍以下案例:

  • 查找地图文档和图层文件中损坏的数据源
  • 调用MapDocument.findAndReplaceWorkspacePaths()方法修复损坏的数据源
  • 调用MapDocument.replaceWorkspaces()方法修复损坏的数据源
  • 调用replaceDataSource()方法修复单个图层和表
  • 查找文件夹中所有地图文档中损坏的数据源

引言

GIS数据的移动,格式转换以及删除等操作是很普遍的情况。这些操作过程会导致许多地图文档或图层文件中数据源损坏。这些受损的数据源修复之后才能正常使用,如果涉及到大量的地图文档,修复数据源将会是一个巨大的工程。你可以使用arcpy.mapping模块来自动化完成损坏数据源的查找和修复工作,而且不用打开受影响的地图文档。使用ListBrokenDataSources()函数来查找损坏的数据源是一个简单的处理过程,该函数返回一个包含地图文档或者图层文件中所有损坏的数据源列表。在脚本中通常会先调用ListBrokenDataSources()函数,之后迭代返回的列表数据并修复数据源。修复损坏的数据源的工作既可以针对单独的数据图层也可以针对一个工作空间内的所有图层。

查找地图文档和图层文件中损坏的数据源

数据源损坏是地图文档中常见问题。你可以使用arcpy.mapping模块来查找已经移动或删除或转换格式的数据源。

Getting ready

在ArcMap中,数据源损坏的图层会在图层名称前面用红色感叹号来标识(如下图所示)。arcpy.mapping模块中的ListBrokenDataSources()函数会返回地图文档或图层文件中受损的图层对象列表:

How to do it...

按照以下步骤来学习如何查找地图文档文件中的损坏的数据源:
1.在ArcMap中打开C:\ArcpyBook\Ch4\Crime_BrokenDataLinks.mxd
你会看到该文档中的所有图层的数据源都已经损坏。在本案例中,地图文档中的数据移动到了其他文件夹中,数据删除或者转换为其他格式的话,你也会看到相同的提示符号。比如说,数据从个人地理数据库中迁移到文件地理数据库:

2.关闭ArcMap。
3.打开IDLE,创建一个新的脚本窗口。
4.导入arcpy.mapping模块:

import arcpy.mapping as mapping

5.引用Crime_BrokenDataLinks.mxd地图文档:

mxd=mapping.MapDocument(r"c:\ArcpyBook\Ch4\Crime_BrokenDataLinks.mxd")

6.获取损坏数据源列表:

lstBrokenDS = mapping.ListBrokenDataSources(mxd)

7.迭代列表并打印图层名称:

for layer in lstBrokenDS:
    print layer.name

运行结果如下:

District_Crime_Join
Bexar_County_Boundary
District_Crime_Join
Bexar_County_Boundary
Bexar_County_Boundary
Texas_Counties_LowRes
School_Districts
Crime_surf
Bexar_County_Boundary
Crime2009Table

8.脚本保存为c:\ArcpyBook\Ch4文件夹下的FindFixBrokenData.py

How it works...

ListBrokenDataSources()函数返回一个损坏数据源的图层列表。我们可以使用for循环语句迭代列表内容并对每个图层执行操作。在本案例中,我们只是简单地显示图层名称来说明函数返回的数据情况。在下一个案例中,我们将编写脚本来修复这些损坏的数据源。

There's more...

ListBrokenDataSources()函数不仅可以返回地图文档中损坏的数据源图层列表,还可以查找图层文件(.lyr)中损坏的数据源。只要简单地将图层文件的路径参数传递给该函数就可以查看该图层文件中是否存在损坏的数据源。需要说明一点的是打包好的地图文档或图层文件不需要这些函数来查找损坏的数据源,这是因为不同于图层文件,这类文件和数据是绑定在一起的。

调用MapDocument.findAndReplaceWorkspacePaths()方法修复损坏的数据源

MapDocument.findAndReplaceWorkspacePaths()方法用于在地图文档中进行全局查找并替换所有图层和表的工作空间路径。你还可以一次替换多个工作空间类型的路径。

Getting ready

我们在学习修复数据集的方法前需要先介绍几个概念。你会发现涉及到修复损坏数据源的方法的时候,这些术语会经常提起,因此你需要理解在这些概念的含义。工作空间(workspace)可以简单地理解为数据的容器。它可以是一个文件夹(针对shapefile文件来说),个人地理数据库,文件地理数据库或是ArcSDE连接。工作空间路径(workspace path)是工作空间的系统路径。对于地理空间数据库来说,工作空间路径是包含地理数据库的名称在内的。数据集(dataset)则可以简单地理解为工作空间内的要素类或是表,而数据源(data source)则是工作空间和数据集的组合。不要混淆数据集和要素数据集两个概念,前者只是针对数据来说的一个笼统的概念,而后者则是地理数据库中的一个对象,作为要素类或其他数据集的容器。
arcpy.mapping中有三个与修复受损数据源相关的类,分别是MapDocument类,Layer类以及TableView类。每一个类中包含的方法都可以用于修复数据源。在本案例中,我们将看一下如何使用MapDocument类中的findAndReplaceWorkspacePaths()方法对地图文档中的图层和表执行全局的查找和替换操作。

How to do it...

按照以下步骤来学习如何使用findAndReplaceWorkspacePaths()方法来修复地图文档中的图层和表:
1.在ArcMap中打开C:\ArcpyBook\Ch4\Crime_BrokenDataLinks.mxd
2.右键单击任意图层选择属性(Properties)
3.点击源(Source)选项卡,你会注意到该图层引用的位置为
C:\ArcpyBook\Ch4\Data\OldData\CityOfSanAntonio.gdb。文件地理数据库位置已经不存在了;数据已经移至C:\ArcpyBook\data文件夹中了。
4.打开IDLE,创建一个新的脚本窗口。
5.导入arcpy.mapping模块:

import arcpy.mapping as mapping

6.引用Crime_BrokenDataLinks.mxd地图文件文件:

mxd=mapping.MapDocument(r"c:\ArcpyBook\Ch4\Crime_BrokenDataLinks.mxd")

7.使用findAndReplaceWorkspacePaths()方法来修复该地图文档中所有数据源的路径:

mxd.findAndReplaceWorkspacePaths(r"C:\ArcpyBook\Ch4\OldData\CityOfSanAntonio.gdb",r"C:\ArcpyBook\data\CityOfSanAntonio.gdb")

8.保存为一个新的mxd文件:

mxd.saveACopy(r"C:\ArcpyBook\Ch4\Crime_DataLinksFixed.mxd")

9.脚本保存为C:\ArcpyBook\Ch4\MapDocumentFindReplace.py
10.运行脚本。
11.在ArcMap中打开C:\ArcpyBook\Ch4\Crime_DataLinksFixed.mxd文件。如下图所示,所有的数据源已经修复完成:

How it work...

MapDocument.findAndReplaceWorkspacePaths()方法用于在地图文档中进行全局查找并替换所有图层和表的工作空间路径。你还可以一次替换多个工作空间类型的路径。

There's more...

Layer类和TableView类同样可以使用findAndReplaceWorkspacePaths()方法来执行相同的操作。对于LayerTableView对象来讲,该方法用于修复地图文档文件中的单个损坏的数据源而不进行全局查找和替换。

使用MapDocument.replaceWorkspaces()方法修复损坏的数据源

在GIS操作课程中,数据从一种工作空间类型迁移到其他类型是相当普遍的操作。比如,许多组织机构会将数据从旧的个人地理数据库中迁移到新的文件地理数据库甚至是企业级的ArcSDE地理数据库中。你可以使用MapDocument.replaceWorkspaces()方法来自动化完成数据集更新至不同工作空间类型中的工作。

Getting ready

MapDocument.replaceWorkspaces()方法与MapDocument.findAndReplaceWorkspacePaths()方法类类似,不过前者允许更改工作空间类型。比如,你可以从一个文件地理数据库中转为个人地理数据库。不过一次操作只能针对一个工作空间。在本案例中,我们将使用MapDocument.replaceWorkspaces()方法将数据源从文件地理数据库转至个人地理数据库。

How to do it...

按照以下步骤来学习如何使用MapDocument.replaceWorkspaces()来修复损坏的数据源:
1.在ArcMap中打开C:\ArcpyBook\Ch4\Crime_DataLinksFixed.mxd
2.如下图所示,注意到所有的图层和表位于一个叫CityOfSanAntonio.gdb的文件地理数据库中:

3.打开IDLE,创建一个新的脚本窗口。
4.导入arcpy.mapping模块:

import arcpy.mapping as mapping

5.引用Crime_BrokenLinksFixed.mxd文件:

mxd=mapping.MapDocument(r"C:\ArcpyBook\Ch4\Crime_DataLinksFixed.mxd")

6.调用replaceWorkspaces()方法,并将新旧地理数据库类型关键字参数传递给该方法:

mxd.repalceWorkspaces(r"C:\ArcpyBook\data\CityOfSanAntonio.gbd","FILEGDB_WORKSPACE",r"C:\ArcpyBook\new_data\CityOfSanAntonio_Personal.mdb","ACCESS_WORKSPACE")

7.保存为一个新的mxd文件:

mxd.saveACopy(r:"C:\ArcpyBook\Ch4\Crime_DataLinksUpdated.mxd")

8.脚本保存为C:\ArcpyBook\Ch4\MapDocumentReplaceWorkspace.py
9.运行脚本。
10.在ArcMap中打开C:\ArcpyBook\Ch4\Crime_DataLinksUpdated.mxd文件。如下图所示,所有的数据源已经位于个人地理数据库中(扩展名为.mdb):

How it work...

MapDocument.replaceWorkspaces()方法接受的参数中包括新旧工作空间的路径以及工作空间类型。工作空间路径不言而喻,工作空间类型方面还是很有必要多阐述一下。工作空间类型是以字符串关键字(string keyword)的形式传递给方法。在本案例中,旧的工作空间类型为文件地理数据库因此使用了关键字FILEGDB_WORKSPACE。新的工作空间类型的关键字为ACCESS_WORKSPACE来表示个人地理数据库。个人地理数据库是存储在Mircrosoft的ACCESS文件中。还有一些不同的工作空间类型可以存储GIS数据。你要确保提供的工作空间类型与你的数据集相匹配。下面列出了一些可用的工作空间类型(许多人仍然会使用shapefile文件,这类文件的工作空间类型为SHAPEFILE_WORKSPACE):

  • ACCESS_WORKSPACE:个人地理数据库或Access工作空间
  • ARCINFO_WORKSPACE:Arcinfo coverage工作空间
  • CAD_WORKSPACE:CAD文件工作空间
  • EXCEL_WORKSPACE:Excel文件工作空间
  • FILEGDB_WORKSPACE:文件地理数据库工作空间
  • NONE:用于忽略该参数
  • OLEDB_WORKSPACE:OLE数据库工作空间
  • PCCOVERAGE_WORKSPACE:PC ARC/INFO Coverage工作空间
  • RASTER_WORKSPACE:栅格工作空间
  • SDE_WORKSPACE:SDE地理数据库工作空间
  • SHAPEFILE_WORKSPACE:shapefile文件工作空间
  • TEXT_WORKSPACE:文本文件工作空间
  • TIN_WORKSPACE:TIN工作空间
  • VPF_WORKSPACE:VPF工作空间

调用replaceDataSource()方法修复单个图层和表

本章前面几个案例介绍了针对MapDocument对象中用来修复数据链接的几种方法。Layer对象和TableView对象同样包含可用于修复数据链接的方法,不过这些方法只针对单个对象而不能作用于地图文档中的所有数据集。

Getting ready

Layer类和TableView类都有一个replaceDataSource()方法。该方法针对单个图层或表来更改工作空间路径,工作空间类型以及数据集名称。在本案例中,你将编写脚本来更改某个图层的工作空间路径和类型。replaceDataSource()方法适用于Layer类和TableView类。对于图层而言,既可以是地图文档中的图层也可以是图层文件中的图层。由于表不能包含在图层文件中,对表来讲只能是地图文档中的表。

How to do it...

按照以下步骤来学习如何使用replaceDataSource()方法来修复地图文档中单个Layer对象和TableView对象:
1.在ArcMap中打开C:\ArcpyBook\Ch4\Crime_DataLinksLayer.mxd文件。Crime数据框中包含一个Burglary的图层,该图层数据是位于CityOfSanAntonio文件地理数据库中的一个要素类。你要用一个包含相同数据的shapefile文件来替换该要素类:

2.打开IDLE,创建一个新的脚本窗口。
3.导入arcpy.mapping模块:

import arcpy.mapping as mapping

4.引用Crime_DataLinksLayer.mxd文件:

mxd=mapping.MapDocument(r"C:\ArcpyBook\Ch4\Crime_DataLinksLayer.mxd")

5.获取Crime数据框引用:

df = mapping.ListDataFrames(mxd,"Crime")[0]

6.查找Burglary图层并保存在一个变量中:

lyr = mapping.ListLayers(mxd,"Burglary",df)[0]

7.针对获取的Layer对象调用replaceDataSource()方法,并将shapefile文件的引用路径参数,shapefile工作空间类型的关键字参数以及shapefile文件名称传递给该方法:

lyr.replaceDataSource(r:"C:\ArcpyBook\data","SHAPEFILE_WORKSPACE","Burglaries_2009")

8.保存为一个新的地图文档文件:

mxd.saveACopy(r"C:\ArcpyBook\Ch4\Crime_DataLinksNewLayer.mxd")

9.脚本保存为C:\ArcpyBook\Ch4\LayerReplaceDataSource.py
10.运行脚本。
11.在ArcMap中打开C:\ArcpyBook\Ch4\Crime_DataLinksNewLayer.mxd文件。如下图所示,你会看到Burglary图层已经引用了新的工作空间:

12.右键单击Burglary图层选择属性(Properties)
13.点击源(Source)选项卡查看新的工作空间,工作空间类型和数据集名称:

How it work...

replaceDataSource()方法接受两个必选参数和两个可选参数。前两个参数定义用于要替换图层的工作空间路径和类型。第三个参数dataset_name是一个可选参数,该参数定义了用于替换的图层的数据集名称。该名称要求完全匹配。比如,在本案例中,我们Burglaries_2009传递给dataset_name参数,这个shapefile文件的名称将作为替换图层。如果该参数没有提供,那么arcpy将会尝试查找与当前图层数据集名称相同的数据来进行替换。最后一个可选参数是validate。默认情况下,该参数值为true。当validatetrue时,只有当workspace_path值是一个有效工作空间才会进行更新操作。如果validatefalse,不管workspace_path是否是一个有效的工作空间,该方法都会进行工作空间的更新操作。这将会导致损坏的数据源的情况出现,不过这在需要事先创建或修改一个为尚未存在的数据做准备的地图文档时会很有用。

There's more...

Layer类和TableView类还包含一个findAndReplaceWorkspacePath()方法,该方法与MapDocument.findAndReplaceWorkspacePaths()非常相似。两者唯一的区别在于前者只针对单个LayerTableView对象,而不是遍历整个地图文档或图层文件。

查找文件夹中所有地图文档文件中损坏的数据源

数据从一个工作空间迁移到另一个工作空间或是从某个工作空间类型迁移到其他工作空间类型中,这在许多机构部门是很普遍的事情。该情况发生时,所有地图文档或图层文件引用的这些数据源都会中断受损。如果是人工来查找每一个数据源,这会是一项巨大的工程。幸运的是,你可以创建一个地理处理脚本来查找一个或多个文件夹中所有损坏的数据源。

Getting ready

在本案例中,你将学习如何遍历搜索文件夹来查找在文件夹中的地图文档文件中所有损坏的数据源,并将这些图层的名称写入到文件中。

How to do it...

按照以下步骤来学习如何查找文件夹中所有地图文档文件中损坏的数据源:
1.打开IDLE,创建一个新的脚本窗口。
2.导入arcpyos包:

import arcpy.mapping as mapping,os

3.定义一个开始搜索的系统路径。在本案例中,我们会从C盘根目录开始搜索,之后遍历搜索C盘下面所有的目录。你也可以定义一个更为明确的路径:

path = "C:"

4.打开一个文件用来写入损坏的数据图层的名称:

f = open('BrokenDataLinks.txt','w')

5.使用os.walk()方法以及for循环语句来遍历目录树:

for root,dirs,files in os.walk(path):

6.在for循环语句中创建一个二级for循环语句来遍历所有返回的文件。对于每一个文件,调用os.path.splitext()方法来获取文件的文件名和扩展名:

for filename in files:
    basename,extension = os.path.splitext(filename)

7.查看文件扩展名来查看是否为地图文档文件。如果是的话,首先获取该地图文档文件的完整路径,之后使用该路径创建一个新的地图文档对象实例并将地图文档名写入文件中,最后循环遍历每一个损坏的数据源并写入文件中:

if extension = ".mxd":
    fullpath = os.path.join(root,filename)
    mxd = mapping.MapDoucment(fullpath)
    f.write("MXD:" + filename + "\n")
    brknList = mapping.ListBrokenDataSources(mxd)
    for brknItem in brknList:
        f.write("\t" +brknItem.name + "\n")

8.关闭文件:

f.close()

9.完整代码如下所示:

import arcpy.mapping as mapping,os
path = r"C:"
f = open("BrokenDataLinks.txt","w")
for root,dirs,files in os.walk(path):
    for filename in files:
        basename,extension = os.path.splitext(filename)
        if extension = ".mxd":
            fullpath = os.path.join(root,filename)
            mxd = mapping.MapDocument(fullpath)
            f.write("MXD:" + filename + "\n")
            brknList = mapping.ListBrokenDataSources(mxd)
            for brknItem in brknList:
                f.write("\t" + brknItem.name + "\n")
f.close()

10.运行脚本。
11.打开生成的文本文件查看结果。你的结果会由于定义的path变量中的路径不同而有区别。下图为我的结果:

How it work...

脚本中使用了Python的os包以及arcpy.mapping模块中的方法。os.walk()方法会从你定义的C盘目录作为根目录开始遍历目录树,并返回每次遍历目录的路径,目录列表和文件列表。其中根目录可以是任意目录。os.walk()方法返回一个包含根目录路径,目录列表和文件列表的三个元素的元组。之后我们循环遍历文件列表并调用os.path.splitext()方法将每一个文件分离成文件名和扩展名。其中扩展名用来查看是否匹配地图文档文件的扩展名.mxd字符串。判定为地图文档的文件的文件名会写入到一个文本文件中去,同时创建了一个新的地图文档对象实例。最后,我们调用ListBrokenDataSources()函数生成地图文档中损坏的数据源列表,同时这些损坏的数据源的图层名称也被写入到文本文件中。


第三章 管理地图文档和图层 ||| 第五章 自动化地图生产和打印

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容