arcpy.mapping模块可以实现地图制图的自动化,它的具体功能包括管理地图文档、数据框架、图层文件以及上述元素中的数据。此外,还可用于地图自动化打印和输出。
地图文档(MXD)在磁盘中的后缀名是.mxd。ArcPy制图模块可以打开并操作地图文档(.mxd)和图层文件(.lyr)。
读取地图文档主要有一下两种方法:
(1)从当前ArcMap会话中使用地图文档
(2)引用存储在磁盘中的地图文档。
这两种方法都可以通过MapDocument函数实现,语法如下:
MapDocument(mxd_path)
下面的代码可以打开一个地图文档:
mapdoc = arcpy.mapping.MapDocument("C:/Mapping/Study_Areas.mxd")
如果要使用当前ArcMap中的地图文档,就要使用关键字CUTTENT(全部大写):
mapdoc = arcpy.mapping.MapDocument("CURRENT")
使用CURRENT关键字时,必须保证ArcMap处于运行状态。
使用Save时,更改的内容会保存在原地图文档中;
使用Save As时,更改后的地图文档将会保存成一个新的mxd文件。
脚本环境中没有Save as选项,MapDocument对象只有save和saveACopy两种方法,其中saveACopy方法同ArcMap中的save As功能一样。
修改后的地图文档并不会进行实时的更新,函数RsfreshActiveView
和RefreshToc
可以用于刷新。
在脚本引用了MapDocument对象之后,对应的地图文档会被锁定,因此当骄傲本不再需要时,建议使用del语句删除它。因此制图脚本有一种结构化的编码方式,如下所示:
import arcpy
mapdoc = arcpy.mapping.MapDocument("C:/Mapping/Study_Areas.mxd")
mapdoc.save()
del mapdoc
MapDocument对象的大部分属性都可以在Map Document Properties
对话框中找到。这些属性包括标题、作者、上次保存时间以及是否存储数据源的相对路径名等。
除了属性外,MapDocument对象还提供很多方法,save
和saveACopy
,以及处理缩略图的方法(deleteThumbnail
和makeThumbnail
)和修改工作空间的方法(findAndReplaceWorkspacePaths
和replaceWorkspace
)。
下面的代码首先使用CURRENT关键字获取ArcMap的当前地图文档,然后通过filePath属性打印出.mxd文件的系统路径。
import arcpy
mapdoc = arcpy.mapping.MapDocument("CURRENT")
path = mapdoc.filePath
print path
del mapdoc
运行这段代码将会输出一个系统路径。
del语句用于解除地图文档的锁定。下面的代码更新了当前地图文档的标题并保存该地图文档。
import arcpy
mapdoc = arcpy.mapping.MapDocument("CURRENT")
mapdoc.title = "Final map of study areas"
mapdoc.save()
del mapdoc
地图文档可以包含一个或者多个数据框,每个数据框又可以包含一个或多个图层。数据框和图层都可以储存在列表中。ListDataFrames函数以列表形式返回地图文档中的数据框对象,其语法如下:
ListDataFrames(map_document, {whild_crad})
获取地图文档中的数据框列表,就可以浏览或修改她们的属性。运行下面的代码将输出地图文档中所有数据框的名称。
import arcpy
mapdoc = arcpy.mapping.MapDocument("CURRENT")
listdf = arcpy.mapping.ListDataFrames(mapdoc)
for df in listdf:print df.name
del mapdoc
如果仅需要使用其中一个数据框,则需要引用该数据框的索引值。数据框列表中数据框的排序和它们在ArcPy内容列表中的排序都是一样的。
DataFrame对象中的地图范围、比例尺、旋转、空间参考等属性使用地图单位,其他属性泽使用页面单位来衡量页面布局中数据框的位置和大小。数据框也可以访问其他对象,ListLayers
函数用于访问每个数据框中的图层。
在处理地图文档的过程中,可能不需要改变所有的数据框属性,而仅仅修改其中几个常见的属性。
例如,下面的代码将地图文档中所有数据框的空间参考设置成某个shapefile的空间参考,并且将所有数据框的比例尺都设置为1:2400.
import arcpy
dataset = "C:/map/boundary.shp"
spatialRef = arcpy.Describe(dataset).spatialReference
mapdoc = arcpy.mapping.MapDocument("C:/map/final.mxd")
for df in arcpy.mapping.ListDataFrames(mapdoc):df.spatialReference = spatialRefdf.scale = 24000
del mapdoc
除了前面提到的属性,DataFrame对象还有两个方法:panToExtent
和zoomToSelected Features
。
panToExtent方法在保持数据框比例尺的前提下,根据Extent对象的属性,将数据框范围居中显示。Extent对象是一个矩形,可以通过地图单位中左下角和右上角坐标来设置。在大多数情况下,范围是从一个现有对象中获取,例如一个要素或者一个图层。getExtent
方法可以获取一个图层的范围。
下面的代码将数据框df的显示范围设置成图层lyr的显示范围。
df.panToExtent(lyr.getExtent())
zoomToSelected Features方法类似于ArcMap菜单栏中的Selection>Zoom to Selected Features。运行下面的代码可以将数据框df缩放至所选要素的范围:
df.zoomToSelectedFeatures()
如果没有要素被选中,那么会缩放至所有图层的完整范围。
一个数据框通常包含一个或几个图层。Layer对象可以管理这些图层。
Layer对象具有很多属性和方法,有两种访问Layer对象的方法。
(1)第一种是使用Layer函数去访问磁盘上现有的.lyr文件。语法如下:
Layer(lyr_file_path)
使用Layer函数的参数是一个.lyr文件的路径名加文件名,例如:
Lyr = arcpy.mapping.Layer("C:/Mapping/study.lyr")
(2)第二种方法是使用ListLayers函数来访问.mxd文件的图层,或者是地图文档中某个数据框内的图层,或者是.lyr文件里的图层。ListLayers函数的语法如下:
ListLayers(map_document_or_layer, {wild_crad}, {data_frame})
其中,唯一的一个必选参数是地图文档或图层文件。可选的通配符参数可限制输出到图层列表中的结果。另一个可选参数可以用来调用某一个DataFrame对象。下面的代码将以列表的形式返回地图文档中所有的图层:
import arcpy
myDoc = arc.,apping.MapDocument("CURRENT")
lyrlist = arcpy.mapping.ListLayers(mapdoc)
for lyr in lyrlist:print lyr.name
仅仅访问某个数据框中的图层,则需要引用DataFrame对象作为参数。在下面的代码中,ListLayers函数仅返回地图文档中索引为0的数据框里的图层。通配符参数使用空字符来省略。
import arcpy
myDoc = arcpy.mapping.MapDocument("CURRENT")
dflist = arcpy.mappingListDataFrame(mapdoc)
lylist = arcpy.mapping.ListLayers(mapdoc, "", dflist[0])
for lyr in lyrlist:print lyr.name
下面的代码块说明了如何访问磁盘上.lyr文件中的图层,并输出它们的名称:
import arpcy
lyrfile = arcpy.mapping.Layer("C:/Data/mylayers.lyr")
lyrlist = arcpy.mapping.ListLayers(lyrfile)
for lyr in lyrlist:print lyr.name
ArcMap中有很多类型的图层,不同的类型有不同的访问方式。常见的图层类型有三种,分别是要素图层、栅格图层和图层组。Layer对象的属性可以用于辨认正在访问图层的类型,supports
方法可以用于测试一个图层支持的属性。
Layers对象有很多属性,包括图层名称、图层数据集名称、透明度、定义查询、显示标注以及一些与显示相关的属性,例如亮度、对比度、透明度。
下面的代码将使用showLabels属性显示当前地图文档中所有图层的标注。
import arcpy
myDoc = arcpy.mapping.MapDocument("CURRENT")
dflist = arcpy.mapping.ListDataFrames(mapDoc)
lyrlist = arcpy.mappingListLayers(mapDoc, "", dflist[0])
for lyr inlyrlist:lyr.showLabels = True
del lyrlist
图层属性还可以用于查找具有特定名称的图层。,下面的代码用于查询一个名为“hospitals”的图层。
import arcpy
myDoc = arcpy.mapping.MapDocument("CURRENT")
lyrlist = arcpy.mappingListLayers(mapDoc)
for lyr in lyrlist:if lyr.name == "hospitals":lyr.showLabels = True
del lyrlist
图层名称是区分大小写的,为了让语句对大小写都通用,可以对图层名称使用相关字符串操作。如下所示:
if lyr.name.lower() == “hospitals”
datasetName
属性将返回工作空间中图层数据集的名称,dataSource
属性返回图层数据集的全路径。只有datasetName和dataSource的属性是只读的。longname
属性用于图层组,因为它既包含了图层组的名称,也包含了子图层的名称。
并非所有类型都支持同一属性,support方法测试属性是否支持,语法如下:
supports(layer_property)
supports方法参数为属性,返回布尔值。测试Showlabels属性是否可用的代码如下:
import arcpy
myDoc = arcpy.mapping.MapDocument("CURRENT")
dflist = arcpy.mapping.ListDataFrames(mapdoc)
for lyr in lyrlist:if lyr.supports("SHOWLABELS") == True:lyr.showLabels = True
del lyrlist
除了图层对象的属性和方法外,还有一些函数专门用于管理数据框中的图层。如下:
AddLayer
–根据通用位置参数向地图文档中的数据框里加载图层。
AdLayerToGroup
–根据通用位置参数向地图文档的图层组里加载图层。
InsertLayer
–向地图文档中的图层组或数据框里加载图层。该方法可以根据一个参考图层来设置索要插入的图层的位置。
MoveLayer
–移动地图文档中某一图层组或某一数据框里图层的位置。
RemoveLayer
–删除地图文档中的某一个图层
UpdateLayer
–通过从原图层提取信息,更新地图文档中所有图层属性或仅更新图层的符号系统。
这些函数访问的必须是一个现有的图层。
在介绍如何修复数据链接之前,需要先熟悉一些定义:
ListBrokenDataSources
函数可以检测数据链接是否断开,该函数以列表形式返回断开链接的图层,语法如下:
ListBrokenDataSources(map_document_or_layer)
下面的代码将输出地图文档中存在数据链接损坏的图层的名称:
import arcpy
mapdoc = arcpy.mapping.MapDocument("CURRENT")
brokenlist = arcpy.mapping.ListBrokenDataSources(mapdoc)
for lyr in borkenlist:print lyr.name
del mapdoc
findAndReplaceWorkspacePaths和replaceWorkspace是分别用来查找和替换工作空间路径和工作空间。该方法不会改变数据集的名称。
replaceDataSource可以同时修改工作空间和数据集,或者仅仅修改数据集。针对MapDocument、Layer、TabView三种不同的类,总共有六种不同的方法:
(1)MapDocument.findAndReplaceWorkspacePaths
(2)MapDocument.replaceWorkspace
(3)Layer.findAndReplaceWorkspacePaths
(4)Layer.replaceWorkspace
(5)TableView.findAndReplaceWorkspacePaths
(6)TableView.replaceWorkspace
其中MapDocument.findAndReplaceWorkspacePaths的语法如下:
MapDocument.findAndReplaceWorkspacePaths(find_workspace_pat, replace_workspace_path, {valudate})
该方法可以查找并替换地图文档中所有图层和属性表的工作空间路径。例如,下面的代码替换了当前工作空间的路径。
import arcpy
mapdoc = arcpy.mapping.MapDocument("CURRENT")
mapdoc.findAndReplaceWorkspacePaths("C:/mydata", "c:/newdata")
mapdoc.save()
del mapdoc
MapDocument.findAndReplaceWorkspacePaths可以处理多种工作空间类型,包含shapefile,文件地理数据库以及其他文件,但是无法改变工作空间的类型。
MapDocument.replaceWorkspace方法既可以用来修改工作空间路径,也可以用来修改工作空间类型。
MapDocument.replaceWorkspace的语法如下:
MapDocument.replaceWorkspace(old_workspace_path, old_workspace_type, new_workspace_path, new_workspace_type, {validate})
下面的代码,将shapefile指向地理数据库中的要素类。
import arcpy
mapdoc = arcpy.mapping.MapDocument("C:/maydata/project.mxd")
mapdoc.replaceWorkspace("C:/mydata/shapes", "SHAPEFILE_WORKSPACE", "C:/mydata/database.gdb", "FILEGDB_WORKSPACE")
mapdoc.save()
del mapdoc()
有效的工作空间类型如下所示:
Layer.findAndReplaceWorkspacePaths方法就是对Layer对象进行操作,它用来查找并替换某个地图文档或者图层文件里一个图层的工作空间路径,语法如下:
Layer.findAndReplaceWorkspacePaths(find_workspace_path, replace_workspace_path, {validate})
下面的代码,使用了一个新的个人地理数据库替换了原来的数据库。
import arcpy
mapdoc = arcpy.mapping.MapDocument("C:/mydata/project.mxd")
lyrlist = arcpy.mapping.ListLayers(mapdoc)
for lyr in lyrlist:if lyr.supports("DATASOURCE"):if lyr.dataSource == "C:/mydata/database.gdb/hospitals":lyr.findAndReplaceWorkspacePaths("database.gdb", "newdata.gdb")
mapdoc.save()
del mapdoc
Layer.findAndReplaceWorkspacePaths方法假定数据集不变。replaceWorkspacePaths方法既可以修改工作空间,也可以修改数据集,其语法如下:
Layer.replaceWorkspace(workspace_path, workspace_type, dataset_name, {validate})
下面的代码可以替换一个数据源:
import arcpy
mapdoc = arcpy.mapping.MapDocument("C:/mydata/project.mxd")
lyrlist = arcpy.mapping.ListLayers(mapdoc)
for lyr in lyrlist:if lyr.supports("DATASOURCE"):if lyr.dataSource == "C:/mydata/database.gdb/hospitals":lyr.replaceWorkspacePaths("C:/mydata/hospitals.shp", “SHAPEFILE_WORKSPACE”, "newdata.gdb")
mapdoc.save()
del mapdoc
制图脚本也可以用来处理页面布局,包括图形、图例、图片、文本和其他元素。这些元素常见的属性包括名字、大小、位置,都可以被修改。
类似于地图文档,布局元素不能用脚本创建,所以它们必须是地图文档中以及存在的元素。ListLayoutElements
函数可以用来确定地图文档的页面布局以及存在了哪些元素。其语法如下:
ListLayoutElements(map_document, {element_type}, {wild_card])
ListLayoutElements函数返回一个Python元素列表。可选参数element_type可以将元素限定为以下某种类型:
每个元素对应着arcpy.mapping模块中的一个类。下面的代码创建了一个布局元素的列表并且输出它们的名字和类型:
import arcpy
mapdoc = arcpy.mapping.MapDocument(r"C:\mydata\project.mxd")
elemlist = arcpy.mapping.ListLayoutElements(mapdoc)
for elem in elemlist:print elem.name & " " & elem.type
del mapdoc
从概念上看,任何与数据框有关联的布局元素都是一个MAPSURROUND_ELEMENT对象。它们包括指北针、比例尺及其标注。
一旦确定需要使用哪种布局元素,就可以通过以下几种方法选择元素:
(1)根据元素索引值选择
title = arcpy.mapping.ListLayoutElements(mapdoc)[3]
(2)根据element_type参数进行选择
arcpy.mapping.ListLayoutElements(mapdoc, "TEXT_ELEMENT")[0]
(3)根据wild_card参数进行选择
arcpy.mapping.ListLayoutElements(mapdoc,"", "Title")[0]
一旦使用了某种页面布局元素,就可以访问它的属性,例如元素名称、类型高度等等。下面的代码将页面布局中标题的文本改成了一个新的字符串:
import arcpy
mapdoc = arcpy.mapping.MapDocument("C:/mydata/project.mxd")
title = arcpy.mappingListLayoutElements(mapdoc, "TEXT_ELEMENT")[0]
title.text = "New Study Area"
mapdoc.save()
del mapdoc
PictureElement对象有一个sourceImage属性,用来表示图像数据源的路径。下面的代码说明了如何修改这个路径:
import arcpy
mapdoc = arcpy.mapping.MapDocument("CURRENT")
elemlist = arcpy.mapping.ListLayoutElements(mapdoc, "PICTURE_ELEMENT")
for elem in elemlist:if elem.name == "photo1":elem.sourceImage = "C:/myphotos/newimage.jpg"
mapdoc.save()
del mapdoc
LegendElement对象有一个autoAdd的属性,当使用AddLayer函数向数据框中添加图层时,该属性可以控制这个图层是否可以自动添加到图例中去。下面的代码说明如何使用autoAdd属性来控制向图例中添加哪个图层:
import arcpy
mapdoc = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mapdoc)[0]
lyr1 = arcpy.mapping.Layer("C:/mydata/Streets.lyr")
lyr1 = arcpy.mapping.layer("C:/mydata/Ortho.lyr")
legend = arcpy.mapping.ListLayoutElements(mxd, "LEGEND_ELEMENT")[0]
legend.autoAdd = True
arcpy.mapping.AddLayer(df, lyr1, "BOTTOM")
legend.autoAdd = False
arcpy.mapping.AddLayer(df, lyr2, "BOTTOM")
mapdoc.save()
del mapdoc
LegendElement对象有一个属性为items
,可以返回一个表示图例项名称的字符串列表。以及一个方法adjustColumCount
,可以用来设置图例的列数。
arcpy制图模块有很多输出地图的函数:
这些函数都以相似的方式运行。输出函数的必选参数是地图文档的名称和路径,以及输出文件的名称,例如ExportToJPEG
函数的语法如下:
ExportToJPEG(map_document, out_jpeg, {data_frame}, {df_export_width}, {df_export_height}, {resolution}, {wprld_file}, {color_mode}, {jpeg_quality}, {progressive})
这些参数都有默认值,通常只有在需要的时候才对这些参数进行设置。下面的代码将地图文档的页面布局输出为JPEG格式的文件,并将像素设定为600dpi。
import arcpy
mapdoc = arcpy.mapping.MapDocument("C:/project/study.mxd")
arcpy.mapping.ExportToJPEG(mapdoc, "C:/project/final.jpg", "", "", "", 600)
def mapdoc