第二章 使用ArcPy编写脚本 ||| 第四章 查找和修复数据源
我们将在本章介绍以下案例:
- 引用当前地图文档
- 引用磁盘上的地图文档
- 访问数据框
- 获取地图文档中的图层列表
- 限制图层列表内容
- 更改地图显示范围
- 获取表数据列表
- 向地图文档中添加图层
- 向地图文档中插入图层
- 更新图层符号系统
- 更新图层属性
引言
ArcPy制图模块是ArcGIS 10新增加的功能模块,该模块提供了相当赞的自动化制图功能,包括管理地图文档和图层文件以及数据。制图模块提供了自动化地图输出和打印功能,可用于创建PDF地图册和发布ArcGIS Server地图服务。制图模块对于那些需要完成的许多日常地处理任务的GIS人员是很有用的。
在本章中,你将了解如何使用ArcPy制图模块来管理地图文档和图层文件。你会了解如何从地图文档文件中增加和删除图层和表,如何向数据框中插入图层,如何在地图文档内移动图层。最后你还会学习如何更新图层属性和符号化系统。
引用当前地图文档
当通过ArcGIS Python窗口或者自定义工具中执行地理处理脚本的时候,你通常需要获取当前加载到ArcMap中的地图文档的引用地址。在脚本中这通常是对地图文档中的图层和表执行地理操作前的第一步。在本案例中,你将会学习如何在Python地理处理脚本中引用当前地图文档。
Getting ready
对一个地图文档文件执行任何操作前,你首先需要在Python脚本中获得该地图文档的引用地址。这一操作可通过调用arcpy.mapping
模块中的MapDocument()
函数来实现。你可以引用当前活动的地图文档文件,也可以引用磁盘中的地图文档文件。你只要将关键字CURRENT
作为MapDocument()
函数的参数即可引用当前活动的地图文档,即当前ArcMap中打开的地图文档。下面的示例代码中展示了如何获取当前活动地图文档的引用:
mxd = arcpy.mapping.MapDocument("CURRENT")
当通过ArcGIS Python窗口或者自定义工具中执行地处理脚本的时候,你可以只使用
CURRENT
关键字。如果想在IDLE或者其他开发环境下运行脚本,使用CURRENT
关键字则不能访问当前加载到ArcMap中的地图文档文件。CURRENT
关键字大小写不敏感,你也可以写作current
。
如果要引用本地磁盘或远程磁盘上的地图文档的话,你只要将地图文档路径和文件名作为MapDocument()
函数的参数即可。比如,你想要引用c:\data
文件夹下的crime.mxd
地图文档文件就可以使用下面的代码:
arcpy.mapping.MapDocument("c:/data/crime.mxd")
How to do it...
按照以下步骤来学习如何获取ArcMap中当前活动的地图文档:
1.使用ArcMap打开c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.点击ArcMap主工具栏上的Python窗口按钮。
3.在Python窗口中导入arcpy.mapping
模块:
import arcpy.mapping as mapping
4.上一步中的代码下敲入以下代码来引用当前活动的地图文档(Crime_Ch3.mxd
)并将该引用赋值给变量:
mxd = mapping.MapDocument("CURRENT")
5.获取地图文档的标题并将结果输出到shell窗口中。代码执行时print
语句会将地图文档的标题打印到屏幕:
print mxd.title
6.为地图文档设置一个新的标题:
mxd.title = "Copy of Crime Project"
7.使用saveACopy()
方法保存一个地图文档文件的备份:
mxd.saveACopy("c:/ArcpyBook/Ch3/crime_copy.mxd")
8.运行脚本。
9.在ArcMap中打开刚才创建的crime_copy.mxd
文件,选择文件(File)|地图文档属性(Map Document Properties)来查看地图文档的新标题。
How it works...
MapDocument
类中的构造函数会创建该类的一个实例。在面向对象编程中,一个实例(instance)也就是通常说的一个对象(object)。MapDocument
的构造函数中的参数可以是CURRENT
关键字也可以是本地或者远程磁盘上的地图文档文件的路径。构造函数创建了一个对象并赋值给变量mxd
。你可以使用点标注符来获取对象的属性和方法。在本案例中,我们使用MapDocument.title
属性设置并输出地图文档的标题,同时我们也使用MapDocument.saveACopy()
方法保存了一个新的地图文档文件。
引用磁盘上的地图文档
除了能够引用ArcMap中当前活动的地图文档文件,你还可以使用MapDocument()
函数来获取保存在本地磁盘或远程磁盘中的地图文档文件。在本案例中,你将会学习如何获取这些地图文档。
Getting Ready
正如之前所述,你可以引用计算机中或在共享服务器上的地图文档文件。只要在MapDocument()
中提供文件的路径就可以实现。由于该操作可以不通过ArcGIS Python窗口或自定义脚本工具来运行,因此这是获取地图文档引用的更为灵活的方式。
How to do it...
按照以下步骤来学习如何访问本地或远程磁盘上保存的地图文档:
1.通过开始菜单|所有程序|ArcGIS|Python2.7|IDLE打开IDLE开发环境。
2.在IDLE窗口中选择New|New Window创建一个新的IDLE脚本窗口。
3.导入arcpy.mapping
模块:
import arcpy.mapping as mapping
4.引用在上一个案例中创建的crime_copy.mxd
地图文档:
mxd=mapping.MapDocument("c:/ArcpyBook/Ch3/crime_copy.mxd")
5.打印地图文档的标题:
print mxd.title
6.运行脚本可以看到如下结果显示:
Copy of Crime Project
How it works...
本案例同前一案例唯一的区别在于我们提供了本地或远程磁盘上的地图文档文件的引用地址而不是使用CURRENT
关键字。这也是我们推荐的引用地图文档文件的方式,除非你确定地理处理脚本将在ArcGIS中的Python窗口或是自定义脚本工具中执行。
访问数据框
ArcMap的内容列表(table of content)由一个或多个数据框(data frame)组成。每一个数据框均可包含图层和表。数据框还可以用来筛选像ListLayers()
这样的列表函数返回的列表内容。比如说DataFrame
对象可以作为输入参数用来限制ListLayers()
函数仅返回位于某一特定的数据框中的图层数据。你还可以使DataFrame
对象来设置或获取当前地图的地理范围,这在创建地图册的时候非常有用。在本案例中你将学习如何在Python脚本中访问数据框。
Getting Ready
ListDataFrames()
会返回一个包含DataFrame
对象的列表。每一个数据框均可包含图层和表,同时也可以作为参数用来限制ListLayers()
函数和ListTableViews()
函数返回的列表内容。
How to do it...
按照以下步骤来学习如何获取一个地图文档中的数据框列表:
1.在ArcMap中打开c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.点击ArcMap主工具栏上的Python窗口按钮。
3.导入arcpy.mapping
模块:
import arcpy.mapping as mapping
4.引用当前活动的地图文档(Crime_Ch3.mxd
)并将该引用赋值给变量:
mxd = mapping.MapDocument("CURRENT")
5.调用ListDataFrames()
函数并将地图文档的引用地址参数以及通配符参数传递给该函数,其中通配符用来查找以字母C开头的数据框:
frames = mapping.ListDataFrames(mxd,"C*")
6.使用for
循环语句打印输出返回的每一个数据框的名称:
for df in frames:
print df.name
7.运行脚本将看到如下的结果的显示:
Crime
Crime_Inset
How it works...
ListDataFrames()
函数会返回一个包含ArcMap内容列表中所有数据框的列表。跟其他的列表一样,你可以使用for
循环语句来迭代遍历列表中的内容。在for
循环中,每一个数据框会动态地赋值给df
变量并将数据框的名称打印输出到屏幕上。
获取地图文档中的图层列表
地理处理脚本中通常开始的几个步骤中就需要获取地图文档中的图层列表。一旦获取了图层列表,脚本可能就要循环遍历每一个图层执行一些处理操作。制图模块中的ListLayers()
函数提供了获取图层列表的功能。在本案例中,你就会学习如何获取包含在地图文档中的图层列表。
Getting Ready
arcpy.mapping
模块包含了多个列表函数用来返回图层列表,数据框列表,损坏数据源列表,表单视图列表以及页面元素列表。这些列表函数通常是多步骤处理中的第一步,多步骤处理脚本中往往需要获取一个或多个列表元素来执行下一步的处理。每一个列表函数都会返回一个Python列表,你已经在前面的内容了解到列表是保存信息一种非常高效的数据结构。
列表函数通常是多步骤处理中的一部分,而在这些处理过程中创建列表仅仅只是开始。在脚本中,后续的处理步骤会迭代列表中一个或多个元素。比如你可能先获取一个地图文档中的图层列表,之后遍历所有图层来查找一个指定的图层名称,随后会进行下一步的处理过程。
在本案例中,你将学习如何获取地图文档文件中的图层列表。
How to do it...
按照以下步骤来学习如何获取地图文档文件中的图层列表:
1.在ArcMap中打开c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.点击ArcMap主工具栏上的Python窗口按钮。
3.导入arcpy.mapping
模块:
import arcpy.mapping as mapping
4.引用当前活动的地图文档(Crime_Ch3.mxd
)并将该引用赋值给变量:
mxd = mapping.MapDocument("CURRENT")
5.调用ListLayers()
函数并将地图文档的引用地址参数传递给该函数:
layers = mapping.ListLayers(mxd)
6.使用for
循环语句打印输出地图文档中每一个图层的名称:
for lyr in layers:
print lyr.name
7.运行脚本将看到如下结果显示:
Burglaries in 2009
Crime Density by School District
Bexar County Boundary
Test Performance by School District
Bexar County Boundary
Bexar County Boundary
Texas Counties
School_Districts
Crime Surface
Bexar County Boundary
How it works...
ListLayers()
函数返回地图文档中,或指定的数据框中或图层文件中的图层列表。在本案例中我们将当前的地图文档的引用传递给ListLayers()
函数,该函数将获取地图文档中的图层列表。返回的结果被保存在变量layers
中,该变量是一个包含了一个或多个Layer
对象的Python列表,可使用for
循环语句进行迭代遍历。
There's more...
ListLayers()
函数只是arcpy.mapping
模块提供的众多列表函数中的一个。每一个列表函数返回一个包含某类型数据的Python列表。其他列表函数中包括返回Table
对象的ListTableViews()
函数,返回DataFrame
对象的ListDataFrames()
函数以及返回地图文档中书签列表的ListBookmarks()
函数。本书后面的章节中会介绍其他大部分内容。
限制图层列表内容
在上一个案例中,你学习了如何使用ListLayers()
函数获取图层列表。有时候你不需要地图文档中的所有图层,而只需要这些图层中的一部分。ListLayers()
函数允许限制生成的图层列表内容。在本案例中,你将学习如何使用通配符和指定的数据框来限制返回的图层。
Getting Ready
默认情况下,如果你只传递一个地图文档或图层文件的引用参数,ListLayers()
函数会返回包含所有图层的列表。不过你可以在函数中使用可选的通配符参数或者传递指定的数据框的引用参数来限制返回的图层列表内容。
如果你处理的对象为图层文件(.lyr),那么就不能使用数据框参数来限制返回结果。因为图层文件不支持数据框。
在本案例中,你将学习如何使用通配符和数据框参数来限制ListLayers()
函数返回的图层列表内容。
How to do it...
按照以下步骤来学习如何限制返回的地图文档中的图层列表内容:
1.在ArcMap中打开c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.点击ArcMap主工具栏上的Python窗口按钮。
3.导入arcpy.mapping
模块:
import arcpy.mapping as mapping
4.引用当前活动的地图文档(Crime_Ch3.mxd
)并将该引用赋值给变量:
mxd = mapping.MapDocument("CURRENT")
5.获取地图文档中的数据框列表并查找一个名称Crime
的数据框。注意文本字符串一定要包含在单引号或者双引号之内:
for df in mapping.ListDataFrames(mxd):
if (df.name == 'Crime'):
6.调用ListLayers()
函数并将地图文档的引用参数,用于限制查找范围的通配符参数以及数据框参数传递给该函数,其中数据框参数在本案例中位上一步指定的数据框。ListLayers()
函数一定要在上一步的if
语句的缩进范围内:
layers = mapping.ListLayers(mxd,'Burg*',df)
7.使用for
循环语句打印输出返回的每一个图层名称:
for layer in layers:
print layer.name
8.完整代码如下:
import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
for df in mapping.ListDataFrames(mxd):
if (df.name == 'Crime'):
layers = mapping.ListLayers(mxd,'Burg*',df)
for layer in layers:
print layer.name
9.运行脚本将看到如下结果显示:
Burglaries in 2009
How it works...
你在前面的案例中了解到ListDataFrames()
函数是arcpy.mapping
提供的一个列表函数。该函数返回一个包含地图文档中所有的数据框的列表。之后我们循环遍历返回的数据框列表来查找名称为Crime
的数据框。如果找到了符合条件的数据框,我们就可以调用ListLayers()
函数,同时使用一个通配符"Burg*"作为该函数的第二个参数以及Crime
数据框的引用参数。其中通配符(*
)匹配任何数量的字符。
在本案例中,我们查找Crime
数据框中所有以Burg
开头的图层。任何满足条件的图层会显示到屏幕中。值得注意的是,我们在本案例中只是打印输出了图层名称,然而在大多数情况下你需要调用其他工具或其他函数来执行其他地理处理任务。
更改地图显示范围
在很多情况下,比如当你进行自动化制图过程中需要创建许多不同范围或要素地图的时候,就会需要更改地图的显示范围。利用arcpy
,你就可以通过多种方式来更改地图显示范围。在本案例中,我们将学习如何使用条件查询表达式来更改地图显示范围。
Getting Ready
你可以使用DataFrame
类中的extent
属性来设置地理范围。它通常与
Layer.definitionQuery
属性一起使用,其中的definitionQuery
属性来定义一个图层的查询条件。在本案例中,你会学习如何使用这些对象和属性来更改地图显示范围。
How to do it...
按照以下步骤来学习如何更改图层的地图显示范围:
1.在ArcMap中打开c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.点击ArcMap主工具栏上的Python窗口按钮。
3.导入arcpy.mapping模块:
import arcpy.mapping as mapping
4.引用当前活动的地图文档(Crime_Ch3.mxd
)并将该引用赋值给变量:
mxd = mapping.MapDocument("CURRENT")
5.创建for
循环语句来循环遍历地图文档中的所有数据框:
for df in mapping.ListDataFrames(mxd):
6.找到名称为Crime
的数据框并指定一个图层来应用自定义查询条件语句:
if (df.name == 'Crime'):
layers = mapping.ListLayers(mxd,'Crime Density by School District',df)
7.创建for
循环语句来循环遍历返回的图层。在for
循环语句中,我们还创建一个自定义查询语句并设置数据框新的显示范围:
for layer in layers:
query = '"NAME" = \'Lackland ISD\''
layer.definitionQuery = query
df.exent = layer.getExtent()
8.完整代码如下:
import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
for df in mapping.ListDataFrames(mxd):
if (df.name == 'Crime'):
layers = mapping.ListLayers(mxd,'Crime Density by School District',df)
for layer in layers:
query = '"NAME" = \'Lackland ISD\''
layer.definitionQuery = query
df.extent = layer.getExtent()
9.保存并运行脚本。数据视图(data view)中显示的范围更新至满足查询条件的要素的范围,如下图所示:
How it works...
在本案例中,我们针对图层使用定义表达式更新了地图显示范围。在临近脚本结束位置,创建了一个新的变量query
来保存定义表达式。定义表达式来查找名称为Lackland ISD
的学区。该查询字符串赋值给definitionQuery
属性。最后df.extent
属性设置为layer.getExtent()
值。
获取表数据列表
arcpy.mapping
模块还提供了一个ListTableViews()
函数用于返回地图文档中表数据列表。在本案例中,你会学习如何使用ListTableViews()
函数来创建表数据列表。
Getting Ready
arcpy.mapping
模块除了提供能够返回地图文档或数据框中图层列表的函数之外,还提供了一个ListTableViews()
函数来生成表数据列表。
ListTableViews()
函数只处理包含表数据的地图文档文件和数据框。图层文件(.lyr)中不能包含表数据。
How to do it...
按照以下步骤来学习如何获取地图文档中的表数据列表:
1.在ArcMap中打开c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.点击ArcMap主工具栏上的Python窗口按钮。
3.导入arcpy.mapping
模块:
import arcpy.mapping as mapping
4.引用当前活动的地图文档(Crime_Ch3.mxd
)并将该引用赋值给变量:
mxd = mapping.MapDocument("CURRENT")
5.获取地图文档中的表数据列表:
for tableview in mapping.ListTableViews(mxd):
print tableview.name
6.运行脚本将看到如下结果显示:
Crime2009Table
How it works...
ListTableViews()
函数非常类似于arcpy.mapping
模块提供的其他列表函数。正如ListLayers()
案例中一样,ListTableViews()
函数也接受一个地图文档引用参数(不能引用图层文件)以及可选的通配符参数和数据框参数。该函数返回的表数据列表可使用for
循环进行迭代。
向地图文档中添加图层
很多情况下,你需要向地图文档文件中添加一个图层。制图模块中的AddLayer()
函数提供该功能。在本案例中,你将学习如何使用AddLayer()
函数向地图文档中添加图层。
Getting Ready
arcpy.mapping
模块提供了向现有地图文档文件中添加图层或图层组的功能。你可以利用ArcMap的“自动排列”(auto-arrange)功能,该功能会自动安排数据框中的图层位置。这与通过ArcMap中的添加数据(Add Data)按钮的功能一样,数据框中的图层位置基于几何类型和图层权重规则来确定。
不能向图层文件中(
.lyr
)添加图层
向地图文档中添加图层时,该图层必须引用已有的图层文件中的图层,可以是同一地图文档或同一数据框中的图层,也可以是同一地图文档不同数据框中的图层或者完全不同的地图文档中的图层。图层可以是地图文档中的图层也可以是.lyr
文件中的图层。如果想向一个地图文档中添加图层,你必须首先创建一个Layer
类的实例之后再调用AddLayer()
函数,并将图层要放置的数据框引用参数和位置规则参数传递给该函数。
How to do it...
按照以下步骤来学习如何向地图文档中添加图层:
1.在ArcMap中打开c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.点击ArcMap主工具栏上的Python窗口按钮。
3.导入arcpy.mapping
模块:
import arcpy.mapping as mapping
4.引用当前活动的地图文档(Crime_Ch3.mxd
)并将该引用赋值给变量:
mxd = mapping.MapDocument("CURRENT")
5.获取Crime
数据框的引用,该数据框是ListDataFrames()
函数返回的数据框列表中的第一个元素。语句最后的[0]
指定ListDataFrames()
返回的数据框列表的第一个元素。列表是从零值开始索引,因为我们使用索引值0
来访问第一个元素。
df = mapping.ListDataFrames(mxd)[0]
6.通过引用一个.lyr
文件来创建一个Layer
对象。
layer = mapping.Layer(r"c:\ArcpyBook\data\School_Districts.lyr")
7.向数据框中添加图层:
mapping.AddLayer(df,layer,"AUTO_ARRANGE")
8.运行脚本。School_Districts.lyr
文件就添加到数据框中,如下图所示:
How it works...
在开始的两行中,我们导入了arcpy.mapping
模块并获取了当前活动的地图文档的引用。接下来我们创建了一个新的变量df
用来保存Crime
数据框的引用地址。该引用地址通过ListDataFrames()
函数来获取。之后我们使用列表索引值来访问返回的数据框列表中的第一个元素即Crime
数据框。通过一个School_Districts.lyr
的图层文件,我们创建了一个变量名为layer
的Layer
对象实例。最后我们调用了AddLayer()
函数,并将图层要放置的数据框引用参数以及用来指定AUTO_ARRANGE位置参数传递给该函数。除了自动排列之外,我们还可以使用BOOTOM
或TOP
关键字参数来指定将图层放置在数据框的底层或者顶层位置。
There's more...
arcpy.mapping
模块除了提供了向地图文档中添加图层的功能,还提供了一个
AddLayerToGroup()
函数,该函数可用于向图层组中添加图层。图层可以添加到图层组中的顶层或顶层位置,也可以使用自动排列来放置图层。你还可以向一个空的图层组中添加图层。不过跟其他常规的图层对象一样,图层组不能添加到图层文件中。
向地图文档中插入图层
AddLayer()
函数可用来向地图文档中添加图层,添加进来的图层在数据框中的位置可以根据ArcMap提供的自动排列的位置,也可以是数据框中的顶层或底层位置。不过,该函数并没有提供将图层插入到数据框中的指定位置的控制机制。对于这样情况,你可以使用InsertLayer()
函数来实现。在本案例中,你将学习如何将图层添加到数据框中的指定位置。
Getting Ready
AddLayer()
函数只是简单地将图层添加到一个数据框或者图层组中,要么利用自动排列来放置图层要么将图层放置在数据框或图层组的顶部或末端特定位。InsertLayer()
函数允许将新添加到数据框或图层组中的图层放置在更为精准的位置。该函数使用一个参考图层来指定一个位置,可以在代码中指明图层是插入到该参考位置的前面还是后面。由于InsertLayer()
函数需要使用一个参考图层,因此你不能在空的数据框下使用该函数。
下图可以说明InsertLayer()
的工作模式,图中的District_Crime_Join
图层是参考图层,School_Districts
是要添加进来的图层。调用InsertLayer()
可以将School_Districts
图层放置到参数图层的前面或者后面。
How to do it...
按照以下步骤来学习如何调用InsertLayer()
函数向数据框中插入图层:
1.在ArcMap中打开c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.点击ArcMap主工具栏上的Python窗口按钮。
3.导入arcpy.mapping
模块:
import arcpy.mapping as mapping
4.引用当前活动的地图文档(Crime_Ch3.mxd
)并将该引用赋值给变量:
mxd = mapping.MapDocument("CURRENT")
5.获取Crime
数据框的引用:
df = mapping.ListDataFrames(mxd,"Crime")[0]
6.定义一个参考图层:
refLayer = mapping.ListLayers(mxd,"Burglaries*",df)[0]
7.定义一个要插入的图层:
insertLayer=mapping.Layer(r"c:\ArcpyBook\data\CityOfSanAntonio.gdb\Crimes2009")
8.向数据框中插入图层:
mapping.InsertLayer(df,refLayer,insertLayer,"BEFORE")
9.运行脚本。如下图所示Crimes2009
要素类添加到数据框中:
How it works...
导入arcpy.mapping
模块并获取当前地图文档文件和Crime
数据框的引用之后,之后我们定义了一个参考图层。在本案例中,我们调用ListLayers()
函数以及“Burglaries*”
通配符参数和Crime
数据框参数来限制返回的数据列表中只有一个元素。该元素即Burglaries in 2009
图层。我们使用索引值0
来访问返回的列表中的Burglaries in 2009
图层并赋值给一个Layer
对象变量。接下来,我们定义一个插入图层,该图层是一个新的Layer
对象,该图层对象引用了CityOfSanAntonio
地理数据库中的Crimes2009
要素类。最后,我们调用了InsertLayer()
函数并将数据框,参考图层,插入图层以及插入位置关键字参数传递给该函数。结果如下图所示:
There's more...
你还可以重新调整已经在数据框或图层组中的图层的位置。MoveLayer()
函数提供了这样的功能。图层的移动必须是在同一个数据框中进行。你不能将图层从一个数据框移动到另一个数据框中。跟InsertLayer()
一样,MoveLayer()
也使用一个参考图层来定义调整图层的位置。
更新图层符号系统
也许有时候,你需要更改地图文档中某个图层的符号系统。该操作可以使用
UpdateLayer()
函数来完成,该函数用来更改图层的符号系统以及图层的其他属性。在本案例中,你将会使用UpdateLayer()
函数来更新图层的符号系统。
Getting ready
arcpy.mapping
模块中的UpdateLayer()
函数可以在脚本中用来更新图层的符号系统。举个例子,如下图示你可能想通过脚本将图层的符号系统系统由渐变色更改为渐变符号。UpdateLayer()
函数还可以用于更新其他的图层属性,其默认功能是更新符号系统属性。由于UpadateLayer()
是一个功能强大的函数,可以修改符号系统和其他属性,因此你需要理解多个输入参数的意义。
How to do it...
按照以下步骤来学习如何调用UpdateLayer()
函数来更新图层的符号系统:
1.在ArcMap中打开c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.点击ArcMap主工具栏上的Python窗口按钮。
3.导入arcpy.mapping
模块:
import arcpy.mapping as mapping
4.引用当前活动的地图文档(Crime_Ch3.mxd
)并将该引用赋值给变量:
mxd = mapping.MapDocument("CURRENT")
5.获取Crime
数据框的引用:
df = mapping.ListDataFrames(mxd,"Crime")[0]
6.定义将要更新的图层:
updateLayer = mapping.ListLayer(mxd,"Crime Density by School District",df)[0]
7.定义用于更新符号系统的图层:
sourceLayer =mapping.Layer(r"C:\ArcpyBook\data\CrimeDensityGradSym.lyr")
8.调用UpdateLayer()
函数更新符号系统:
mapping.UpdateLayer(df,updateLayer,sourceLayer,True)
9.运行脚本。如下图所示,Crime Density by School District
图层会使用渐变符号来替代渐变色。
How it works...
在本案例中,我们使用UpdateLayer()
函数更新了图层的符号系统。我们并没有更改其他属性,不过我们将在下一个案例中会涉及更改其他属性的内容。UpdateLayer()
函数需要以下几个参数,包括更新图层所在的数据框,更新图层以及参考源图层,其中参考源图层的符号系统将会应用到更新图层中。在我们的代码中,updataLayer
变量引用了要进行符号系统更新的图层Crime Density by School District。参考源图层是一个图层文件(CrimeDensityGradSym.lyr
),该图层中的渐变符号系统将会应用到更新图层中。
如果要更新一个图层的符号系统,你必须首先保证更新图层和参考源图层具有相同的几何类型(点,线或面)。考虑到渲染器的因素,你还需要核实更新图层和源图层的属性定义是否一致。比如,渐变色符号系统和渐变符号系统都是基于一个特定的属性字段。在本案例中,两个图层都是多边形且都包含一个犯罪案发密度信息的CrimeDens
字段。
一旦获取更新图层和源图层后,我们就可以调用UpdateLayer()
函数并将数据框参数以及两个图层参数和第四个参数传递给该函数,其中第四个参数用来指明我们只更新符号系统属性。我们将第四个参数设置为True
,即说明我们只要求更新符号系统而不更新其他属性。
mapping.UpdateLayer(df,updateLayer,sourceLayer,True)
There's more...
UpdateLayer()
还可以删除图层并在该位置添加一个新图层。删除的图层和添加的图层是完全无关的,因此当重新定义图层符号系统时也就不需要保证两个图层具有相同的几何类型以及相同的属性字段。图层的这种转换实际上相当于把先调用RemoveLayer()
函数再调用AddLayer()
函数的两个操作合并为一个操作来执行。要使用此功能,你必须将symbology_only
参数设置为False
。
更新图层属性
在前一个案例中,你学习了如何更新一个图层的符号系统。正如我前面提到的,UpdateLayer()
函数还可以用来更新图层的其他属性,比如字段别名,定义查询及其他属性。在本案例中,你将使用UpdateLayer()
函数来更改图层的多个属性。
Getting ready
你还可以使用UpdateLayer()
函数来更新一部分图层属性。调用UpdateLayer()
函数可以更新包括像字段别名,选择符号,定义查询,标注字段及其他一些特定的图层属性。同一个图层出现在多个地图文档中是常见的情况,在这种情况下要对所有地图文档中该图层的某一属性进行变更。如果要完成这一任务,你需要在ArcMap中修改该图层的属性后保存为一个图层文件。该图层文件会作为参考源图层来更新其他需要更新图层的属性。在本案例中,你将会使用ArcMap来修改一个图层的属性,之后保存为图层文件(.lyr
),然后编写Python脚本调用UpdateLayer()
函数来应用到其他图层中。
How to do it...
按照以下步骤来学习如何使用UpdateLayer()
来更改图层属性:
1.在ArcMap中打开c:\Arcpybook\Ch3\Crime_Ch3.mxd
。在本案例中,我们将处理Burglaries in 2009要素类,如下图所示:
2.双击Crime数据框下的Burglaries in 2009要素弹出图层属性对话框(Layer Properties)(如下图所示)。每一个选项卡中的属性都可以设置:
3.点击常规(General)选项卡,将图层名称(Layer Name)中信息按照下图修改:
4.点击定义查询(Definition Query)选项卡,按照下图定义查询条件语句。你可以使用查询构造器(Query Builder)来定义查询语句也可以直接输入条件语句:
5.如下图所示将OFFDESC
字段别名修改为Offense Description
。
6.点击图层属性对话框(Layer Properties)中的字段(Field)选项卡,按照下图所示将勾选的字段设为可见。
7.点击OK按钮,关闭图层属性对话框(Layer Properties)。
8.右键单击Burlaries-No Forced Entry图层选择另存为图层文件(Save as Layer File)。
9.将文件保存为c:\Arcpybook\data\BurglariesNoForcedEntry.lyr
。
10.右键单击Burlaries-No Forced Entry图层选择移除(Remove)。
11.使用添加数据(Add Data)按钮,添加CityOfSanAntonio
地理数据库中的Crime2009要素类数据。如下图所示,该要素类添加到数据框中:
12.打开ArcMap中的Python窗口。
13.导入arcpy.mapping
模块:
import arcpy.mapping as mapping
14.引用当前活动的地图文档(Crime_Ch3.mxd
)并将该引用赋值给变量:
mxd = mapping.MapDocument("CURRENT")
15.获取Crime
数据框的引用:
df = mapping.ListDataFrames(mxd,"Crime")[0]
16.定义要更新属性图层:
updateLayer = mapping.ListLayer(mxd,"Crime2009",df)[0]
17.定义用于更新属性的图层:
sourceLayer=mapping.Layer(r"c:\Arcpybook\data\BurglariesNoForcedEntry.lyr")
18.调用UpdateLayer()
函数来更新属性:
mapping.UpdateLayer(df,updateLayer,sourceLayer,False)
19.运行脚本。
20.如下图所示,Crime2009图层属性会更新为BurglariesNoForcedEntry.lyr
文件中的属性。我们可以看到图层的定义查询条件也已经应用。你还可以打开图层属性对话框(Layer Properties)来查看已经应用到Crime2009图层中的属性更新: