最近在做某区退耕还林验收项目,要求按每个村出比例尺1:10000的JPG格式的图片,由于村比较多(接近400个,很多村在1:10000比例尺下无法显示完整,需要出多张图片),所以考虑批量完成该工作。
1.设定好MXD模板布局视图,调整好所有图例,将标题设置为变量,可以根据某个村的名字自动变化;
2.一个村无法只导出一张图片的情况,需要生成辅助图层分幅,分幅使用FME,生成图形的外接矩形,计算矩形长宽以及长宽/出图的幅宽,向上取整为倍数,使用切片工具按照两个倍数值进行切片,然后使用裁剪工具对原图形进行裁剪,只取出inside部分;
分幅之后大约有1000个图幅,后续再用造林小班和分幅图叠加,筛选出有叠加部分并排序,生成唯一字段。
3.在进行2步骤的时候,因为矩形之间有交叉部分必须要单独对每个图形进行处理,因此可以使用FME WORKSPACERUNER转换器循环执行,写入GDB文件中;
4.将GDB所有属性值导出为EXCEL文件待用;
5.根据4生成的EXCEL文件使用PYTHON生成若干个(数量和GDB文件中的矢量图形数量相等,名称和GDB文件中唯一值对应)MXD文档,待用;
6.使用ARCPY选中要素,缩放至选中要素,清除所选要素(注意这里有坑),更改标题变量值;
7.使用ARCPY导出JPEG图片。
MXD模板制作有两个要点。
第一个是要对需要发生变化的文本、图例赋上唯一名称。右键选中文本或图例,点击“属性”→“大小和位置”→“元素名称”,自己按照需求添加。
第二个是要固定比例尺,因为不固定比例尺,在后续使用ARCPY缩放至选中要素功能时会自动缩放到不同的比例尺(每个村大小不同导致,也是因为如此需要分幅)。右键点击“图层”→“数据库”,设定“范围”为“固定比例”,比例调整为所需大小,此处我设置为1:10000.
下图为FME模板
考虑到需要对过程文件的记录,选择先生成MXD文档的方式(也可以在调整图形时直接生成),因为习惯用PYTHON3,所以这一步骤还是用的PYTHON3写的,比较简单,以下是代码。
# -*- coding: utf-8 -*-
import shutil,sys
from openpyxl import load_workbook
old_file_path=r"F:\arcgis\2018.mxd"
if __name__=='__main__':
workbook=load_workbook(r'F:\arcgis\TEST.xlsx')
sheet=workbook.get_sheet_by_name("CJ")
rows=sheet.rows
cols=sheet.columns
max_rows=sheet.max_row
max_columns=sheet.max_column
Lfile=[]
for i in sheet["H"]:
if i.value!='IID':
Lfile.append(i.value)
print(Lfile)
for i in Lfile:
new_file_path=r"F:\arcgis\{0}.mxd".format(i)
shutil.copyfile(old_file_path,new_file_path)
必须使用arcgis自带的python,我使用的是arcgis10.3,自带python2.7,以下是代码。
# -*- coding: utf-8 -*-
import arcpy,os,sys
reload(sys)
sys.setdefaultencoding( "utf-8" )
def resetmxd(iid):
filename="{0}.mxd".format(iid)
mxd = arcpy.mapping.MapDocument(filename)
lyr = arcpy.mapping.ListLayers(mxd)[0] # 需要改动的图层,这里是选择要素的图层
lyr1 = arcpy.mapping.ListLayers(mxd)[4] # 需要缩放高亮显示的图层,可选
df = arcpy.mapping.ListDataFrames(mxd)[0]
rows = arcpy.SearchCursor(lyr) #行数
for row in rows:
if row.getValue("IID")==iid:
title=u'2018年度{0}退耕还林'.format(row.getValue("title"))
query = "IID='{0}'".format(iid) #检索条件
print query
arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION", query) # 选中一个新的要素
df.zoomToSelectedFeatures() # 缩放至选中要素
el = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT")[-1]
el.text = title # 更新的是文本,不是教程上的元素名称
arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION") # 清除所选要素
#
# arcpy.SelectLayerByAttribute_management(lyr1, "NEW_SELECTION", "FID=8")
# # 选择是否高亮显示
arcpy.mapping.MapDocument.save(mxd) # 重新保存mxd
arcpy.RefreshActiveView() #刷新视图
arcpy.RefreshTOC()
del mxd
if __name__=='__main__':
L=['5002301002011', '5002301002001', '5002301002041', '5002301002042', '5002301002031', '5002301002032', '5002301002051', '5002301002052', '5002301002053']
for i in L:
resetmxd(i)
因为还在测试阶段,所以上述都是测试数据,比较乱,到时候拿到正式的小班数据后会对文档进行整理。
这里有个两个选择,第一高亮显示行政区(不能高亮显示分幅的行政区,看起来会很奇怪),第二不高亮显示行政区,这个按照自己的需求决定,所以这里有个坑:清除所选要素(不高亮显示)的方法还是SelectLayerByAttribute_management()不过第二个参数值需要改为“CLEAR_SELECTION”。
# -*- coding: utf-8 -*-
import arcpy,os,sys
reload(sys)
sys.setdefaultencoding( "utf-8" )
if __name__=='__main__':
L=['5002301002011', '5002301002001', '5002301002041', '5002301002042', '5002301002031', '5002301002032', '5002301002051', '5002301002052', '5002301002053']
for iid in L:
filename = "{0}.mxd".format(iid)
mxd = arcpy.mapping.MapDocument(filename)
new_path='{0}.jpg'.format(iid)
arcpy.mapping.ExportToJPEG(mxd,new_path,resolution=300)
ExportToJPEG方法参数参考文档:http://desktop.arcgis.com/zh-cn/arcmap/10.3/analyze/arcpy-mapping/exporttojpeg.htm
先记录大概的思路和过程,等项目完成再完善此文档,欢迎友好讨论!