#coding=utf8
# -*- coding: utf-8 -*-
# ============================================================
# 按分幅框批量生成公示图 - 脚本工具版 (.tbx 调用)
# 参数由用户在 ArcMap 工具属性对话框中自行定义
# 位置约定(建议按此顺序配置, 可自行调整):
#参数0: 源地图文档(mxd)必填
#参数1: 分幅框要素类必填
#参数2: 纸张模板文件夹必填
#参数3: 输出文件夹必填
#参数4: 地块图层名(可选,留空自动)选填
#参数5: PNG分辨率dpi(可选,默认200) 选填
# 注: 若只想配4个必填参数, 参数4/5留空不配也可正常运行
# ============================================================
importarcpy
importos
importsys
# ============ 字段配置区(字段名不同时改这里) ============
F_FENFU= u"图名"# 分幅编号字段
F_SCALE= u"比例尺"# 比例尺字段
F_PAPER= u"纸张大小"# 纸张大小字段(1.2/1.5)
F_ORIENT = u"纸张方向"# 纸张方向字段(横/竖)
SKIP_LAYER_NAME = u"分幅框"# 自动查找地块图层时跳过的图层名
# ========================================================
def get_param(i, default=None):
"""读取工具参数(arcpy 命令行/工具模式均映射 sys.argv[i+1])
返回unicode, 避免中文路径/字段编码问题"""
try:
v= arcpy.GetParameterAsText(i)
if v:
ifisinstance(v, str):
for enc in ('utf-8', 'gbk'):
try:
return v.decode(enc)
exceptException:
continue
return v
return default
exceptException:
return default
def main():
src_mxd= get_param(0)
ffb_fc= get_param(1)
tpl_dir= get_param(2)
out_dir= get_param(3)
dk_name= get_param(4, u"") oru""
png_res= int(get_param(5, 200) or200)
# ---------- 校验 ----------
ifnot src_mxd ornot ffb_fc ornot tpl_dir ornot out_dir:
raisearcpy.ExecuteError(u"缺少必填参数: 需要 源mxd/分幅框要素类/模板文件夹/输出文件夹")
ifnotos.path.exists(src_mxd):
raisearcpy.ExecuteError(u"源地图文档不存在: %s" % src_mxd)
ifnotarcpy.Exists(ffb_fc):
raisearcpy.ExecuteError(u"分幅框要素类不存在: %s" % ffb_fc)
ifnotos.path.isdir(tpl_dir):
raisearcpy.ExecuteError(u"模板文件夹不存在: %s" % tpl_dir)
ifnotos.path.isdir(out_dir):
os.makedirs(out_dir)
# ---------- 坐标系: 从分幅框要素类读取 ----------
sr= arcpy.Describe(ffb_fc).spatialReference
arcpy.AddMessage(u"坐标系: %s" % sr.name)
# ---------- 读取分幅框 ----------
frames= []
witharcpy.da.SearchCursor(ffb_fc, [F_FENFU, F_SCALE, F_PAPER, F_ORIENT, "SHAPE@"]) as cur:
for row in cur:
e= row[4].extent
frames.append((row[0], row[1], row[2], row[3], e.XMin, e.YMin, e.XMax, e.YMax))
ifnot frames:
raisearcpy.ExecuteError(u"分幅框要素类没有记录!")
arcpy.AddMessage(u"读取分幅框 %s 个" % len(frames))
# ---------- 打开源mxd, 找地块图层 ----------
src= arcpy.mapping.MapDocument(src_mxd)
dk_lyr= None
if dk_name:
for lyr inarcpy.mapping.ListLayers(src):
if lyr.name == dk_name:
dk_lyr= lyr
break
if dk_lyr isNone:
arcpy.AddWarning(u"未找到图层名 '%s',改为自动查找" % dk_name)
if dk_lyr isNone:
for lyr inarcpy.mapping.ListLayers(src):
if lyr.name == SKIP_LAYER_NAME:
continue
try:
if lyr.isFeatureLayer andarcpy.Describe(lyr.dataSource).shapeType == "Polygon":
dk_lyr= lyr
break
exceptException:
continue
if dk_lyr isNone:
del src
raisearcpy.ExecuteError(u"源mxd中找不到地块面图层!")
arcpy.AddMessage(u"地块图层: %s" % dk_lyr.name)
prefix= dk_lyr.name
# ---------- 模板查找 ----------
def find_tpl(paper, orient, scale):
names= [
u"%s向%s米比例尺1:%s.mxd" % (orient, paper, scale),
u"%s向%s米比例尺1:%s .mxd" % (orient, paper, scale),
]
for n in names:
p= os.path.join(tpl_dir, n)
ifos.path.exists(p):
return p
returnNone
# ---------- 逐幅生成 ----------
for name, scale, paper, orient, xl, yb, xr, yt in frames:
scale_i= int(round(scale))
orient_c= u"横"ifu"横"in orient elseu"竖"
tpl= find_tpl(paper, orient_c, scale_i)
ifnot tpl:
arcpy.AddWarning(u"跳过图名%s: 找不到模板 纸张%s %s向 1:%s" % (name, paper, orient_c, scale_i))
continue
arcpy.AddMessage(u"处理图名%s: %s%s 1:%s 模板=%s" % (
name,paper, orient_c, scale_i, os.path.basename(tpl)))
m= arcpy.mapping.MapDocument(tpl)
df= m.activeDataFrame
for lyr inarcpy.mapping.ListLayers(m):
arcpy.mapping.RemoveLayer(df, lyr)
arcpy.mapping.AddLayer(df, dk_lyr, "TOP")
df.spatialReference= sr
df.extent= arcpy.Extent(xl, yb, xr, yt)
actual= df.scale
arcpy.AddMessage(u"自动scale=%s (目标1:%s)" % (round(actual, 4), scale_i))
out_mxd= os.path.join(out_dir, u"%s_图%s_%s%s_1_%s.mxd" % (prefix, name, paper, orient_c, scale_i))
m.saveACopy(out_mxd)
out_png= out_mxd.replace(".mxd", ".png")
arcpy.mapping.ExportToPNG(m, out_png, resolution=png_res)
arcpy.AddMessage(u"已生成: %s + %s" % (os.path.basename(out_mxd), os.path.basename(out_png)))
del m
del src
arcpy.AddMessage(u"完成! 共 %s 幅" % len(frames))
if __name__ == "__main__":
try:
main()
exceptExceptionas e:
import traceback
arcpy.AddError(u"错误: %s" % e)
arcpy.AddError(traceback.format_exc())
raise

夜雨聆风