使用arcpy从字段获取变量更新布局文本的问题咨询
问题根因
你用列表推导遍历arcpy.da.SearchCursor返回结果赋值的变量,哪怕目标要素类只有1条记录,得到的也始终是列表类型。字符串的replace()方法要求传入的替换内容为字符串类型,直接传列表就会触发类型不匹配报错,这就是你几行属性相关替换代码失效的原因。
修复方法
既然你确认要读取的要素类都仅含1条记录,直接取返回列表的第一个元素(Python索引从0开始,即下标[0]),就能拿到可直接用于文本替换的单个值。
另外你现有代码有两处明显的效率问题,可以一并修正:
- 同一个WS要素类你开了3次SearchCursor分别读3个字段,完全可以通过一次游标读取所有需要的字段,减少I/O消耗
- 你把
arcpy.RefreshActiveView()和mxd.save()写在了遍历文本元素的循环内部,每改一个文本就刷新、保存一次地图文档,执行速度会非常慢,挪到所有文本修改完成后执行一次即可
修正后的核心代码
import arcpy import os ID = arcpy.GetParameterAsText(1) city = arcpy.GetParameterAsText(3) WS = os.path.join('path to gdb', "WS") # 注意原代码中overview变量未提前赋值,使用前需要指定为对应要素类的正确路径 dfield = 'name' datefield = 'date' cfield = "county" # 单次游标读取WS要素类的两个目标字段,直接取第一行记录的值 with arcpy.da.SearchCursor(WS, [dfield, datefield]) as cur: for row in cur: wsname = row[0] wsdate = row[1] break # 仅需第一行,读完直接跳出循环 # 读取county字段值,同样取第一行即可 with arcpy.da.SearchCursor(overview, [cfield]) as cur: for row in cur: county = row[0] break # 遍历更新布局文本元素 for elm in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT"): elm.text = elm.text.replace('WS', str(wsname)) elm.text = elm.text.replace('City', city) elm.text = elm.text.replace('text2', f"words{ID} -more words") elm.text = elm.text.replace('Name', str(county)) elm.text = elm.text.replace('Date', str(wsdate)) # 所有修改完成后统一刷新视图、保存文档 arcpy.RefreshActiveView() mxd.save()
补充:如果你后续想改回数据驱动页面的动态文本方案,只需要在更新完对应索引/属性后,调用
mxd.dataDrivenPages.refresh()即可触发动态文本刷新,不需要手动逐个替换文本内容。
内容的提问来源于stack exchange,提问作者hosta
相关产品推荐
相关产品推荐

