news 2026/6/9 18:43:15

【教你用ArcPy批量输出图片并生成Mxd(零门槛小白版)】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【教你用ArcPy批量输出图片并生成Mxd(零门槛小白版)】

如何快速批量出图是GISer需要解决的问题,要实现逐栅格图层或矢量图斑的出图则是师妹最近期末作业遇到的难题。还好,Gemini回归,通过不断调试解决这个需求。希望能转发给更多的伙伴!

难点1

通过现有的Mxd工作空间能够实现逐栅格图层或矢量图斑的输出,但是不能保证每个栅格图层或矢量图斑出现在整个输出图幅的正中间。

已解决!!!(居中,且比例尺为动态)

难点2

如何将对应矢量数据与栅格数据同时输出,比如,在市域尺度上的栅格数据,叠加市域尺度的矢量数据作为边界。

已解决!!!(需要在图层中添加Shp,即矢量格式,空白填充,红色,1磅大小,里面包含要输出tif的name字段,如输出石家庄_Lucc.tif,矢量图层中name字段必须也有这个“石家庄” )

难点3

如何如何动态调整经纬度范围,且图名随文件进行变化。

已解决!!!经纬度范围也能够动态进行调整(唯一遗憾是不能自动调整经纬网的疏密)

现有状况,ArcGIS大多数数据驱动页面工具来实现批量出图,出图效果很难满足需要

出图模版

代码如下

(可直接在ArcGIS,Python中运行)

# -*- coding: utf-8 -*-import arcpyimport osimport sys# 强制环境编码reload(sys)sys.setdefaultencoding('utf-8')# --- 1. 参数配置 ---input_folder = r"D:\try\try"mxd_template_path = r"D:\try\try.mxd"output_root = r"D:\try\results"# 图层名称(务必与 MXD 中的 TOC 列表名完全一致)raster_lyr_name = u"石家庄_Lucc2000_reclass.tif"vector_lyr_name = u"京津冀_市级"match_field = "name"# 样式设置FONT_SIZE = 20LEFT_SHIFT = 2.12 # 20磅字偏左3个字的距离Y_OFFSET_FROM_TOP = 1.5 # 距离顶部的间距dpi = 300# --- 2. 文件夹初始化 ---output_jpg_folder = os.path.join(output_root, "JPG_Files")output_mxd_folder = os.path.join(output_root, "MXD_Files")for folder in [output_jpg_folder, output_mxd_folder]:if not os.path.exists(folder):os.makedirs(folder)def batch_process():try:# 获取所有 TIF 文件列表arcpy.env.workspace = input_folder# 同时匹配大写和小写后缀rasters = arcpy.ListRasters("*", "TIF") + arcpy.ListRasters("*", "tif")rasters = list(set(rasters)) # 去重total_count = len(rasters)# --- 调试信息:看看究竟抓到了几个文件 ---print "--------------------------------------------------"print u"正在扫描文件夹: {}".format(input_folder)print u"找到 TIF 文件数量: {}".format(total_count)if total_count > 0:for r in rasters: print " -> " + rprint "--------------------------------------------------"if total_count == 0:print u"错误:文件夹里没找到 TIF 文件,请检查路径或后缀名!"return# --- 开始循环处理 ---for index, raster_name in enumerate(rasters):# 重要:每次循环都重新打开一次模板,保证图层对象是新鲜的mxd = arcpy.mapping.MapDocument(mxd_template_path)df = arcpy.mapping.ListDataFrames(mxd)[0]# 1. 解析文件名if "_" in raster_name:city_key = raster_name.split("_")[0]else:city_key = os.path.splitext(raster_name)[0]raster_base_name = os.path.splitext(raster_name)[0]# 2. 获取图层对象# 放在循环内获取,防止对象失效raster_layer = arcpy.mapping.ListLayers(mxd, raster_lyr_name, df)[0]vector_layer = arcpy.mapping.ListLayers(mxd, vector_lyr_name, df)[0]# 3. 切换数据源raster_layer.replaceDataSource(input_folder, "RASTER_WORKSPACE", raster_base_name, True)# 4. 矢量匹配与缩放query = "{} = '{}'".format(match_field, city_key)vector_layer.definitionQuery = queryarcpy.SelectLayerByAttribute_management(vector_layer, "NEW_SELECTION", query)if int(arcpy.GetCount_management(vector_layer).getOutput(0)) > 0:df.extent = vector_layer.getSelectedExtent()df.scale = df.scale * 1.15else:df.extent = raster_layer.getExtent()arcpy.SelectLayerByAttribute_management(vector_layer, "CLEAR_SELECTION")# 5. 更新标题并精确定位 (保护底部文字)all_texts = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT")# 再次寻找最高文本作为标题target_elm = all_texts[0]max_y = target_elm.elementPositionYfor elm in all_texts:if elm.elementPositionY > max_y:max_y = elm.elementPositionYtarget_elm = elm# 计算坐标df_center_x = df.elementPositionX + (df.elementWidth / 2.0)final_title_x = df_center_x - LEFT_SHIFTdf_top_y = df.elementPositionY + df.elementHeightfinal_title_y = df_top_y - Y_OFFSET_FROM_TOPtarget_elm.text = city_key + u"土地利用分布图"target_elm.fontSize = FONT_SIZEtarget_elm.elementPositionX = final_title_xtarget_elm.elementPositionY = final_title_y# 6. 执行导出arcpy.RefreshActiveView()out_jpg = os.path.join(output_jpg_folder, raster_base_name + ".jpg")arcpy.mapping.ExportToJPEG(mxd, out_jpg, resolution=dpi)out_mxd = os.path.join(output_mxd_folder, raster_base_name + ".mxd")mxd.saveACopy(out_mxd)print u"[{}/{}] 成功生成: {}".format(index + 1, total_count, raster_base_name)# 释放当前 MXD 对象,为下一个循环腾出内存del mxdprint "=================================================="print u"全部完成!JPG 存放在: " + output_jpg_folderprint u"MXD 存放在: " + output_mxd_folderprint "=================================================="except Exception as e:import tracebackprint u"运行出错,详细信息如下:\n" + traceback.format_exc()if __name__ == "__main__":batch_process()

成果图展示

其中第二个的图层不包括tif数据仅输出对应石家庄名称的shp,效果更为明显。(批量输出矢量数据的代码后续也会更新,整体上删除批量遍历栅格数据的过程)

原工程空间及案例数据获取方式

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 16:34:13

深入了解移动开发领域 CI_CD 的工作原理

深入了解移动开发领域 CI/CD 的工作原理 关键词:移动开发、CI/CD、持续集成、持续交付、工作原理 摘要:本文旨在深入剖析移动开发领域 CI/CD 的工作原理。首先介绍了 CI/CD 在移动开发中的背景,包括目的、适用读者等信息。接着阐述了 CI/CD 的核心概念与联系,以清晰的文本示…

作者头像 李华
网站建设 2026/6/10 15:25:21

5. enum(枚举)关键字在C/C++中的作用

enum(枚举)关键字本质是用来定义一组有名字的整数常量,替代直接使用魔法数字(比如 0、1、2),让代码更易读、易维护。 1. 什么是enum?(核心概念) enum(枚举类型…

作者头像 李华
网站建设 2026/6/9 22:28:19

MATLAB实现流形正则化主题模型LapPLSI算法详解

在文本挖掘和主题建模领域,传统的pLSA(Probabilistic Latent Semantic Analysis)和LDA模型假设文档独立同分布,但现实中文档往往存在内在关联(如引用关系、相似内容或社交网络)。为了利用这些文档间的流形结构,研究者提出了Laplacian Probabilistic Latent Semantic Ind…

作者头像 李华
网站建设 2026/6/10 14:56:54

操作mysql常用python脚本,强到爆炸

1.导出数据库指定表的所有字段(含有字段注释)和数据导出结果如下#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ MySQL数据导出工具 - 修复元组索引问题 """import pandas as pd import pymysql import openpyxl from openpyxl.utils impo…

作者头像 李华