批量对MXD文件的页面布局设置修改
功能说明:
MXD的页面设置包括尺寸设置,要素布局设置,比例尺设置等,本文以批量处理土地利用现状分幅图为例。
土地利用现状分幅图较为常见,一般成果图为600*600尺寸,图幅框居中显示,四周空白区较为平均。
本代码目标为:
- 1 缩放页面布局至对应的图幅框范围居中
- 2 设置页面布局比例尺
- 3 导出JPG图片
- 4 保存MXD布局
1 修改前的分幅图状态
分幅图生成一般有几种方式,一种方式是专业建库软件的分幅图输出功能,此类分幅图一般幅面较为标准不需要调整;
一种方式是arcgis插件工具生成分幅图,此类产出的分幅图有个别幅面不居中,或者布局尺寸错误,需要调整一下。
如下图:
2 代码分段
(1)设置工作空间,获取MXD文件 。
// 设置工作空间
arcpy.env.workspace = r"D:\临时";
// 获取所有mxd文件的路径
mxd_files = arcpy.ListFiles("*.mxd")
我的分幅图列表如上图,是以分幅图编号为名称的,方便查找。
(2)循环遍历每个mxd文件 。
// 循环遍历每个mxd文件
for mxd_file in mxd_files:
mxd_name = mxd_file[:-4];
print(mxd_name) # 方便查看进度
(3)打开mxd文档 。
// 打开mxd文档
mxd = arcpy.mapping.MapDocument(os.path.join(arcpy.env.workspace, mxd_file))
打开遍历的当前MXD文档,准备修改页面布局。
(4)设置页面布局,使目标要素居中显示 。
修改页面布局,主要是修改 dataframe 的范围和位置。
arcpy.Extent() 方法用于创建一个表示地理范围的对象,如下代码:
// 修改页面布局
df.extent = arcpy.Extent(41427034, 4605727, 41429662, 4608015)
表示一个矩形范围,该矩形范围的左下角坐标为 (41427034, 4605727),右上角坐标为 (41429662, 4608015)。即页面布局将该坐标围成的区域,居中显示在页面布局中心位置。
本文以分幅图为例子,居中显示的范围应该是图幅号对应的分幅区域,如何实现让页面布局居中显示该分幅区域?
思路如下:
- 1 生成一个全域覆盖的图幅结合图表,要素设置名称字段以图幅编号命名;
- 2 通过属性选择,使分幅图对应的分幅结合图要素处于选择状态,即选中该要素
(本文实际操作是复制粘贴该要素到一个闲置空白图层,复制粘贴过程期间该要素一直为选择状态); - 3 使用 .getSelectedExtent() 方法将页面布局,缩放至当前选择的要素范围;
- 4 清除 要素选择状态。
// 复制粘贴指定要素 到 指定图层
// 选择要素
in_layer_name = 'JFB' # 图幅结合图
out_data_name = "LSM_" + mxd_name # 闲置空白图层,粘贴的目标层
in_layer = arcpy.mapping.ListLayers(mxd, in_layer_name)[0]
out_data = arcpy.mapping.ListLayers(mxd, out_data_name)[0]
name = 'MapName =\'' + mxd_name + '\'' # 属性选择要素,字段名称为 [MapName]
arcpy.SelectLayerByAttribute_management(in_layer, "NEW_SELECTION", name) # 选择要素
//追加要素 复制所选要素到 LSM 图层
schemaType = "NO_TEST" # "TEXT" 检查字段匹配性
fieldMappings = ""
subtype = ""
arcpy.Append_management(in_layer, out_data, schemaType, fieldMappings, subtype)
//获取第一个数据框
df = arcpy.mapping.ListDataFrames(mxd)[0]
//缩放至 当前选择要素
df.extent = in_layer.getSelectedExtent(True) # 缩放至当前选择的要素范围
arcpy.SelectLayerByAttribute_management(in_layer, "CLEAR_SELECTION") # 清除 选择
arcpy.arcpy.DeleteFeatures_management(out_data) # 删除清空 LSM层的 过程要素
(5)设置页面布局的比例尺 。
// 设置视图比例尺
df.scale = 5000 # 示例修改比例尺为5000
(6)设置页面布局的位置和尺寸 。
常用的纸张A4纸的尺寸为 210×297mm,常用的绘图仪卷筒纸的尺寸 宽度为 620mm,打印一张分幅图的尺寸为
600×600mm ,两侧保留装订区域。
页面布局的要素称为dataframe,该区域是显示数据要素的区域,范围可以在打印机纸张范围内部,也可以超出打印机纸张范围外(但是超出纸张范围如果有要素,那么打印或导出图片的时候该超出部分将丢失)。
dataframe的定位点为坐下角,此点向上为高度,此地向右为宽度,单位为MXD地图页面大小显示单位,默认为mm毫米。
本文显示区域为分幅图区域,居中显示,外围无数据,故设置左下角定位点坐标为 纸张外。
// 定位点设置
df.elementPositionX, df.elementPositionY = 10.5, -20.5 # 元素左下角位置 X坐标 Y坐标;
dataframe尺寸设置为 600×600 mm。
// 尺寸设置
df.elementWidth, df.elementHeight = 600, 580 # 元素宽度,高度;
(7)导出图片 。
同步导出图片,方便检查工作。
// 导出图片
arcpy.mapping.ExportToJPEG(mxd, os.path.join(arcpy.env.workspace, mxd_name), resolution=300) #分辨率300;
修改后状态,页面布局居中显示。如下图:
(8)保存MXD并关闭 。
上述的修改设置,最终需要保存修改,否则MXD的状态还是设置前的状态。
// 保存修改后的mxd文档
mxd.save();
// 释放mxd文档对象
del mxd;
3 完整代码
# coding=utf-8
import time
import arcpy
import os
# 设置工作空间
arcpy.env.workspace = r"D:\临时"
# 获取所有mxd文件的路径
mxd_files = arcpy.ListFiles("*.mxd")
# 循环遍历每个mxd文件
for mxd_file in mxd_files:
mxd_name = mxd_file[:-4]
print(mxd_name) # 方便查看进度
# 打开mxd文档
mxd = arcpy.mapping.MapDocument(os.path.join(arcpy.env.workspace, mxd_file))
# 复制粘贴指定要素 到 指定图层
# 选择要素
in_layer_name = 'JFB' # 图幅结合图
out_data_name = "LSM_" + mxd_name # 闲置空白图层,粘贴的目标层
in_layer = arcpy.mapping.ListLayers(mxd, in_layer_name)[0]
out_data = arcpy.mapping.ListLayers(mxd, out_data_name)[0]
name = 'MapName =\'' + mxd_name + '\''
arcpy.SelectLayerByAttribute_management(in_layer, "NEW_SELECTION", name) # 选择要素
# 追加要素 复制所选要素到 LSM 图层
schemaType = "NO_TEST" # "TEXT" 检查字段匹配性
fieldMappings = ""
subtype = ""
arcpy.Append_management(in_layer, out_data, schemaType, fieldMappings, subtype)
# 获取第一个数据框
df = arcpy.mapping.ListDataFrames(mxd)[0]
# 缩放至 当前选择要素
df.extent = in_layer.getSelectedExtent(True) # 缩放至当前选择的要素范围
arcpy.SelectLayerByAttribute_management(in_layer, "CLEAR_SELECTION") # 清除 选择
arcpy.arcpy.DeleteFeatures_management(out_data) # 删除清空 LSM层的 过程要素
df.scale = 5000 # 示例修改比例尺为 1:5000
df.elementPositionX, df.elementPositionY = 10.5, -20.5 # 元素左下角位置 X坐标 Y坐标
# 600 纸张的尺寸(按卷筒打印纸 尺寸 600*600)
df.elementWidth, df.elementHeight = 600, 600 # 元素宽度,高度
arcpy.mapping.ExportToJPEG(mxd, os.path.join(arcpy.env.workspace, mxd_name), resolution=300)
print("完成") # 方便查看进度
# 保存修改后的mxd文档
mxd.save()
# 释放mxd文档对象
del mxd
time.sleep(5) # 暂停 休息几秒钟,释放缓存
4 后记
关于默认打印机和默认纸张设置,我的MXD文档在制作时已经设置过纸张标准大小 :
我有尝试使用arcpy设置页面纸张,未能成功。我的软件环境为 ArcGIS Desktop 10.8.1,网上搜索结果说 ArcGIS Pro可实现该功能。欢迎各位对以上功能进行完善,大家互相交流学习。syq