获取ArcMap要素图层的字段取值
在 ArcMap 中如果需要快速获得一个图层对应的字段数据,获得一个数据概览,可以考虑使用 python 对话框来实现。例如下图中呈现的是 CHGISv6 数据库中我国历代府城及以上治所的部分点要素数据,如果需要获取所有的行政区划类型(TYPE_CH),比较常规的方法是通过汇总统计工具导出一个新表,从而查看字段的取值。
以上方法可以说非常繁琐,需要在卡顿的界面中的大量搜寻和多次点选,还要在文件夹中导出新的表文件。种种操作不仅费时费力,临时导出的表文件也会污染文件夹。因此需要一个更方便的方法,输入一段代码,直接在对话框中返回结果,同时还能直接以文本的形式进行复制粘贴。
查找字段值可以通过 arcpy 中提供的游标功能实现,查找所有值可以通过 python 自带的 set 集合实现。具体的实现如下:
# -*- coding: UTF-8 -*-
# apiglio/src/codetool/feature.py
import arcpy
def to_set(dataset, field):
res = set()
cursor = arcpy.da.SearchCursor(dataset, [field])
for row in cursor:
res.add(row[0])
del row,cursor
return res
以上代码保存在 K:/python/ apiglio/src/codetool/feature.py 之中,定义了一个 to_set 函数,带有 dataset 和 field 两个参数。其中第一个参数需要 ArcMap 中的一个图层名,第二个参数需要要素的字段名。第 5 行创建了一个临时的集合 res,第 6-8 行在图层要素中依次获取 field 字段的值,并将其纳入集合 res。第 9 行清除查找字段值所使用的游标,第 10 行 res 作为结果成为函数的返回值。由于集合内部的元素是唯一的,所以不会出现重复的记录。
在 ArcMap 的 python 对话框中调用以上函数,具体方法如下:
# 我将 apiglio 模块的文件夹放在 K:/python 的路径中
sys.path.append("K:/python")
import apiglio.src.codetool.feature
dataset = "v6_time_pref_pts_utf_wgs84"
res = apiglio.src.codetool.feature.to_set(dataset, "TYPE_CH")
print " ".join(res)
#>>> 省 直隶县 厅 邑 属国都尉 将军辖区 军 侨郡 府 王国 军民府 宣抚司 南部都尉 Fu 章京辖区 军民指挥使 指挥司 宣慰司 侯国 尹 万户府 逻 连 施 县 苴 所 镇 jp 节度 诏 城 招讨司 直隶厅 道 都督府 长官司 都督 千户所 川 典农校尉 州 郡 监 直隶州 都监 属国 卫 路 总管府 万户 安抚司 軍民指揮使 国 卿
可以发现,函数返回的结果包含了“府”“军民府”“都督府”“总管府”和“万户府”等不同包含“府”字的概念,如果只关注最后一个字,则可以继续改进方法,在计入集合之前先进行一个函数运算:
value_1 = u"府"
value_2 = u"军民府"
value_3 = u"都督府"
func = lambda x:x[-1]
print func(value_1)
#>>> 府
print func(value_2)
#>>> 府
print func(value_3)
#>>> 府
以上展示了匿名函数 func 对不同字段值的修改效果,可以将 func 作为参数传递给 to_set 函数。因此可以追加一个 key 参数,用于传递诸如 func 的字段值修改参数,具体修改方法如下:
# -*- coding: UTF-8 -*-
# apiglio/src/codetool/feature.py
import arcpy
def to_set(dataset, field, key=None):
res = set()
cursor = arcpy.da.SearchCursor(dataset, [field])
if key == None:
key = lambda x:x
for row in cursor:
res.add(key(row[0]))
del row,cursor
return res
新的 to_set 函数只是增加了一个带默认值的 key 函数参数,若其值为默认值 None ,则与先前的效果相同;若带有函数参数,则字段值会先根据函数计算,并返回函数结果的统计情况。前文需要统计字段值中的最后一个汉字,可以通过以下代码实现:
# 在已经执行上文代码的前提下,保存代码后只需重新加载模块即可
reload(apiglio.src.codetool.feature)
res = apiglio.src.codetool.feature.to_set(dataset, "TYPE_CH",lambda x:x[-1])
print " ".join(res)
#>>> 省 厅 尉 邑 军 府 度 户 尹 卿 逻 连 施 县 所 镇 诏 城 监 道 川 州 郡 督 区 卫 路 p u 苴 司 国 使
如果打字比鼠标点选快很多的话,这样应该会方便不少。
(完)
网上 python 和 arcpy 的资料可谓相当丰富了,本文更多作为代码备忘和思路分享,涉及的功能会在 Gitee/GitHub 中相应更新以供借鉴, 可以访问以下网址查看 ,也欢迎大家共同提交 修改:
https://gitee.com/apiglio/ApiglioArcpyTool
https://github.com/Apiglio/ApiglioArcpyTool
本期代码在 src/codetool/feature.py 中。
本文编号:GIS-2023-01