ArcGIS Pro中如何用arcpy自动创建图层并批量导出地图图片
ArcGIS Pro 逐点位生成多环缓冲区打印地图实现指引
ArcGIS Pro 已移除旧版ArcMap 对应的arcpy.mapping模块,所有布局操作、地图导出功能都整合在arcpy.mp模块下,ExportToJPEG对应布局对象的exportToJPEG()方法。对入门用户来说,不用从零用代码搭建所有布局元素,提前做好固定模板再循环批量生成的方式调试成本最低,具体实现步骤如下:
前置准备
- 手动搭建基础布局模板:在当前Pro项目中新建布局,提前放入固定的通用要素:地图框、比例尺、指北针(按需)、图例(按需)。将点位图层、多环缓冲区图层提前加载到地图框绑定的地图中,提前设置好缓冲区的分层符号、点位的ID标注样式(直接在图层属性里把ID字段设为标注字段即可,无需代码控制标注),调整好图层显示顺序。
- 确认所有数据使用投影坐标系(单位为米,比如对应区域UTM投影、高斯克吕格投影),不要使用经纬度类的地理坐标系,否则缓冲区距离、比例尺、地图范围计算都会出错。
- 提前创建好用于存储导出JPG的空文件夹,避免路径不存在触发报错。
- 确认点位要素类、多环缓冲区要素类都带有点位ID字段,方便后续过滤单个点位的对应数据。
核心实现逻辑
不需要为每个点位单独新建布局,只需要在循环中每次完成3个操作即可:
- 通过定义查询过滤图层,只显示当前点位、该点位对应的4个环形缓冲区
- 调整地图框的显示范围,以当前点位为中心,范围刚好覆盖1000m缓冲区并预留少量打印边距,也可以直接固定打印比例尺保证所有成果样式统一
- 调用布局的导出方法生成JPG文件
可直接运行的参考代码(在ArcGIS Pro内置Python窗口运行即可)
import arcpy import os # ========== 以下参数修改为自己的实际路径和字段名 ========== aprx_path = "CURRENT" # 直接在当前打开的Pro项目中运行时固定填CURRENT即可 point_fc = r"你的点位要素类全路径" # 示例:r"C:\proj\data.gdb\observation_points" ring_buffer_fc = r"你的多环缓冲区要素类全路径" # 示例:r"C:\proj\data.gdb\ring_buffers" point_id_field = "POINT_ID" # 存储点位ID的字段名 output_dir = r"导出图片存储文件夹路径" # 示例:r"C:\proj\output_maps" target_layout_name = "布局" # 你创建的布局的名称,在内容面板可直接复制 target_mapframe_name = "地图框 1" # 布局内地图框的名称,在内容面板可直接复制 export_dpi = 300 # 打印用途设300DPI足够 # ======================================================== # 读取项目、布局、地图框对象 aprx = arcpy.mp.ArcGISProject(aprx_path) target_layout = aprx.listLayouts(target_layout_name)[0] target_mapframe = target_layout.listElements("MAPFRAME_ELEMENT", target_mapframe_name)[0] bind_map = target_mapframe.map # 通用工具函数:给指定图层设置定义查询,过滤显示要素 def set_layer_filter(layer_full_path, filter_sql): layer_name = os.path.basename(layer_full_path) target_layer = bind_map.listLayers(layer_name)[0] target_layer.definitionQuery = filter_sql # 逐点位遍历生成地图 with arcpy.da.SearchCursor(point_fc, [point_id_field, "SHAPE@XY"]) as cur: for pid, (pt_x, pt_y) in cur: # 1. 过滤图层:仅显示当前点位和对应缓冲区 # 注意:如果ID字段是数值类型,把下面条件里的单引号去掉,比如f"{point_id_field} = {pid}" set_layer_filter(point_fc, f"{point_id_field} = '{pid}'") set_layer_filter(ring_buffer_fc, f"{point_id_field} = '{pid}'") # 2. 设置地图框范围:以当前点为中心,半边长设1200米(覆盖1000m缓冲区+200米边距) # 数据为米单位投影坐标系时直接用该计算即可 half_length = 1200 map_extent = arcpy.Extent( pt_x - half_length, pt_y - half_length, pt_x + half_length, pt_y + half_length, spatial_reference=target_mapframe.spatialReference ) target_mapframe.camera.setExtent(map_extent) # 如果需要固定统一比例尺,注释掉上面的范围设置,放开下面这行改对应比例尺即可 # target_mapframe.camera.scale = 25000 # 3. 导出JPG out_jpg = os.path.join(output_dir, f"观测点_{pid}.jpg") target_layout.exportToJPEG(out_jpg, export_dpi) print(f"点位{pid}地图导出完成,保存路径:{out_jpg}") # 全部导出完成后清空图层过滤条件,恢复全量显示 set_layer_filter(point_fc, "") set_layer_filter(ring_buffer_fc, "") print("所有点位地图导出完毕")
常见注意事项
- 不要尝试用代码从零创建布局、比例尺、图例这类固定元素,手动在Pro界面拖好模板的效率比写代码高10倍,还不容易出现样式错位问题,代码只需要处理批量循环的重复操作即可。
- 如果点位数量较多,不需要提前生成所有点位的多环缓冲区,可以在循环内部临时调用
arcpy.analysis.MultipleRingBuffer为当前点位生成缓冲区,导出完成后删除临时数据即可,能减少前期数据准备工作量。 - 如果运行时提示找不到布局、地图框、图层,直接去Pro的内容面板复制对应元素的准确显示名,不要手动拼写避免空格、字符大小写不匹配。
- 运行前一定要确认数据坐标系:如果是经纬度坐标系,先通过投影工具转成米单位的投影坐标系,否则代码里的距离参数会被识别为度,导致地图范围完全错误。
内容的提问来源于stack exchange,提问作者Thomasv
相关产品推荐
相关产品推荐

