关于制图,是一项非常庞大的部分,这里只简单的介绍如何读取文档,设置图例、标题以及出图。
arcpy.mapping
arcpy.mapping
是ArcPy中用于操作地图文档 (.mxd) 和图层文件 (.lyr) 的的模块,可以使用arcpy.mapping
很方便的创建专题地图册等。
读取mxd文档
arcpy.mapping
读取地图文档,使用的是arcpy.mapping.MapDocument
方法,其定义非常简单:
MapDocument(mxd_path)
mxd_path就是mxd文档的路径。MapDocument
打开一个地图文档后,将会返回一个MapDocument对象。
示例:
mxd_file = arcpy.mapping.MapDocument(mxdFilePath)
# do something
del mxd_file
注1:有一点需要指出,arcpy中一些方法在官网上都没有看到返回值的说明,但是其会一个返回值。一般对于操作而言,返回值的就是这个操作的结果。
注2:使用完MapDocument后记得释放资源
获取地图文档中数据框
ArcGIS中允许定义多个数据框,数据框的获取,是通过arcpy.mapping.ListDataFrames
方法来实现的。arcpy.mapping.ListDataFrames
方法可以获取到指定地图文档中的所有数据框列表,其语法如下:
ListDataFrames(map_document, {wildcard})
其参数的意义如下:
map_document: 用于查看数据框的MapDocument对象
wildcard: 数据库名通配符,与之前讲到的类似。
ListDataFrames
返回的是所有的数据框的列表,可以通过索引来获取指定的数据框,如果要获取map_document中激活的数据框,则可以通过map_document.activeDataFrame
来获取
获取数据框中的图层
获取图层是通过arcpy.mapping.ListLayers
来实现的。ListLayers
可以获取到当前地图文档的所有图层,要获取指定的数据框中的图层,需要将该数据框作为一个参数传递到方法里面。ListLayers
的语法如下:
ListLayers(map_document_or_layer, {wildcard}, {data_frame})
其参数定义如下:
map_document_or_layer:地图文档或则是lyr图层(注:凡是未指定为lyr图层的图层均为普通图层)
wildcard:图层名通配符
data_frame:数据框
例如,获取某个地图文档中的第一个数据框中第一个图层:
import arcpy
mxd = arcpy.mapping.MapDocument(r"xxx\xxx\x.mxd")
df = arcpy.mapping.ListDataFrames(mxd)[0]
print arcpy.mapping.ListLayers(mxd, "", df)[0].name
del mxd
制图
说实话,直接通过ArcPy来对地图进行符号化等设置是比较麻烦的,还好ArcGIS提供lyr图层文件。与普通的shapefile文件和要素类等相比,lyr图层文件可以将数据及符号化的结果都保存在一起(注意,lyr图层对数据的保存仅仅是保存的是数据的路径,其主要保存的内容为符号系统的设置)。因此我们可以先使用ArcGIS定义好符号系统,在通过ArcPy来进行操作,因此这里将不在讲讲解。
制图有三大不可缺少的东西:方向、比例尺、图例,合称为地图三要素。
制作地图册时,如果直接通过ArcPy来创建三要素,对于要素的摆放位置是难以可视化调整的,我们可以通过预先摆放好三要素,然后在通过ArcPy动态的更新其内容显示的地图图层内容即可,尤其是方向、比例尺,我们基本可以不用改变,仅仅来控制图例以及地图标题即可。
对于三要素以及标题等这些,在ArcGIS中统称为布局要素。获取布局要素,使用的是arcpy.mapping.ListLayoutElements
方法,其语法定义如下:
ListLayoutElements (map_document, {element_type}, {wildcard})
其中参数的意义如下:
map_document:用于操作的MapDocument对象
element_type:筛选返回的布局元素列表的元素类型的字符串。其可选择如下:DATAFRAME_ELEMENT
、GRAPHIC_ELEMENT
、LEGEND_ELEMENT
、MAPSURROUND_ELEMENT
、PICTURE_ELEMENT
、TEXT_ELEMENT
。
wildcard:用于筛选返回结果的通配符
我们的图中往往有标题,但是我们并没在element_type发现标题布局元素,这因为标题也是属于文本元素TEXT_ELEMENT
。假如我们地图中只有一个文本类型的元素——标题,那我们可以使用如下方法更改地图的标题:
def adjust_the_title(mxd_file, titleText):
# 获取布局元素标题
titleEle = arcpy.mapping.ListLayoutElements(mxd_file, "TEXT_ELEMENT")[0]
# 更改标题内容
titleEle.text = titleText
再来看个动态修改图例的例子:
def adjust_the_legend(mxd_file, data_frame, layer, colCount):
# 获取布局元素图例
legendEle = arcpy.mapping.ListLayoutElements(mxd_file, "LEGEND_ELEMENT")[0]
# 向数据框中添加图层
arcpy.mapping.AddLayer(data_frame, layer, "TOP")
# 调整图例中列数
if colCount > 1:
legendEle.adjustColumnCount(colCount)
在ArcGIS中,如果向数据框中添加图层,图例中会自动显示该图层;如果从数据框移出图层,图例中会自动移除该图层。因此,我们不用管图例中图层的显示问题。因此,我们只需要在需要的时候对图例的列数进行调整即可。
导出地图
arcpy.mapping
下有一系列的ExportTo*
方法用于导出地图,例如:ExportToPDF
,ExportToPng
,ExportToJPEG
等,分别用来将地图导出为pdf、png、和jpg文件。这些方法虽然参数比较多,但是其最简单的使用如下:
# 导出为pdf
arcpy.mapping.ExportToPDF(mxd_file_object, r"C:\xx\xxx\xxxx.pdf")
# 导出为png
arcpy.mapping.ExportToPNG(mxd, rr"C:\xx\xxx\xxxx.png")
# 导出为jpg
arcpy.mapping.ExportToJPEG(mxd, rr"C:\xx\xxx\xxxx.jpg")
各个方法的具体语法请见ArcGIS的官网
“https://desktop.arcgis.com/zh-cn/arcmap/10.3/analyze/arcpy-mapping/exportXXX.htm”
批量制图
在制作系列专题地图时,我们可能会要求图例、比例尺不变,仅仅是数据的数据源发生变化,比如对某一地区的各类POI数据进行制图,并使得各类POI各出图一张。在ArcPy中操作符号系统是一件比较困难的事情,这时我们可以使用arcpy.mapping.UpdateLayer
函数,其语法如下:
UpdateLayer (data_frame, update_layer, source_layer, {symbology_only})
其参数定义如下:
data_frame:一个数据框DataFrame
对象
update_layer:要被进行的图层
source_layer:用于更新 update_layer 图层的图层
symbology_only:是否只更新 update_layer 图层的符号系统,默认是True
例如,用已经做号符号系统的lyr图层文件去动态生成多个地图并导出,其示例代码如下:
source_layer = arcpy.mapping.Layer("base.lyr")
···
# shp_list 为一系列shapefile文件路径
for shp_file in shp_list:
# 创建一个图层,并将其加入到数据框中
add_layer = arcpy.mapping.Layer(shp_file)
add_layer.visible = True
arcpy.mapping.AddLayer(data_frames, add_layer)
# 更新图层的符号系统
update_layer = arcpy.mapping.ListLayers(map_document, "*", data_frames)[0]
arcpy.mapping.UpdateLayer(data_frames, update_layer, source_layer, True)
# 获取shapefile的文件名(不带扩展名)
file_name = get_file_name(shp_file)
# 导出为png
out_file = arcpy.env.workspace + "/png/" + get_parent_dir(shp_file) + '/' + file_name + ".png"
dir_path = os.path.dirname(out_file)
if not os.path.exists(dir_path):
os.makedirs(dir_path)
arcpy.mapping.ExportToPNG(map_document, out_file)
# 将刚刚加入到数据框中的图层移除
# 注意,不能直接移除add_layer,因为添加到数据框后 add_layer 与 data_frames)[0] 是两个对象
arcpy.mapping.RemoveLayer(data_frames, arcpy.mapping.ListLayers(map_document, "*", data_frames)[0])
该示例的完整代码与数据可见示例代码下 5/batchMapping 文件夹。
制作地图册
创建一个pdf的地图册可以使用PDFDocumentCreate
方法,将多个pdf地图文件合并为一个地图册:
pdf_atlas = arcpy.mapping.PDFDocumentCreate(r"C:\xx\xxx.pdf")
pdf_atlas.appendPages(r"C:\xx\a.pdf")
pdf_atlas.appendPages(r"C:\xx\b.pdf")
pdf_atlas.saveAndClose()
del pdf_atlas
注:使用完PDFDocumentCreate
后记得释放资源
将数据驱动页面和PDFDocumentCreate
结合,可以很方便的创建一系列专题地图册。
该示例的完整代码与数据可见示例代码下 5/atlas 文件夹。