"一起学习Arcade"
属性规则:什么才叫自动化?
计算规则、约束规则、验证规则
属性规则可改善地理数据库数据集的编辑体验并提高数据完整性。
这些规则可用于自动填充属性、在编辑操作期间限制无效编辑,以及对现有要素执行质量保证检查。
属性规则分为3类:计算、约束和验证。
Part.01
How To Use
属性规则开启方法:点击图层后,在【数据】标签下,点击【属性规则】,打开属性规则对话框:
选择【计算】标签,点击【添加规则】,选择【添加实时计算规划】。(批处理计算规则待研究):
打开规则栏后,输入要计算的字段、表达式以及触发器这3个参数,其它参数可以随意填或不填。
点击【保存】,正常情况下无法保存,可以看到这样的错误:
原因是少了全局ID。刚开始我也很懵,后来在系统工具里找了个【添加全局ID】的工具,直接给它用上:
工具执行后,查看属性表,多了一个【GlobalID】字段,再保存属性规则就不会报错了。
后面最主要的工作就是写表达式了,下面看几个有意思的例子。
Part.02
Calculation Rule
计算规则可用于对字段值进行自动计算。
计算规则的触发器一般都设置为【插入+更新】。
01
简单计算
最简单的字段计算,比如目标字段根据另外两个字段的值进行赋值:
$feature.DLBM + $feature.DLMC
修改DLBM或DLMC时,目标字段会自动更新:
02
字段属性映射
比如说在一个字段里输入DLBM,结果字段里生成DLMC。
这需要你准备一个【DLBM和DLMC】一一对应的字典,也就是属性映射表,写到代码里:
(对照表我只写了一小段示例而已,需要自行补充完整)
var key = $feature.DLBM
var dic = Dictionary('0101', '水田', '0102', '水浇地', '0103', '旱地');
if(HasKey(dic, key)){
return dic[key]
}
修改DLBM时,DLMC会自动更新:
03
计算要素的属性
Arcade可以直接计算出要素的的一些属性,基本等效于【计算几何属性】工具。
这个示例计算面要素的部件数,是否有Z值、M值。其它属性的计算类似。
// 部件数
var partCount = Count(Geometry($feature)["rings"])
// Z、M值
var hasZ = Decode(Geometry($feature)["hasZ"],true,"有Z值","无Z值")
var hasM = Decode(Geometry($feature)["hasM"],true,"有M值","无M值")
return `部件数:${partCount},${hasZ},${hasM}`
在编辑中修改或创建要素时,目标字段会自动更新:
04
计算地块容积率
一般情况下,要计算地块容积率需要地块面积以及地块范围内建筑的总面积,这2个数据位于2个要素内,正常做法是用【空间连接】工具将2个要素关联起来再计算。
Arcade通过【FeaatureSetByName($datastore,...)】可以直接引用同一数据库的数据,这就意味着可以在地块图斑上直接计算。
首先准备数据:
在表达式中输入:
// 获取建筑要素
var features = FeatureSetByName($datastore, "建筑", ["建筑面积"], true);
// 获取相关部分
var int_geo = Intersects($feature,features);
// 计算相交部分总建筑面积【shape_area*层数】
var total_area = Sum(int_geo,"建筑面积")
// 计算容积率
var f = round(total_area/$feature.Shape_Area,2)
return f
在编辑中修改或创建要素时,目标字段会自动更新:
Part.03
Constraint Rule
约束规则用于指定要素上允许的属性配置和一般关系。
与计算规则不同,约束规则不用于填充属性,而是用于确保要素满足特定条件。
简单理解,约束规则就是约束你的编辑操作在什么情况下可执行。
如果出现不符合规则的操作,就会报错,操作中断。
01
禁止删除特定的要素
如果你想控制你的编辑操作,避免某些图斑被误删除,就可以设定这样的规则。
比如在用地图斑中,我不想【耕地】被删除,可以将触发器选择为【删除】,在表达式中输入:
if ($feature.DLMC != "耕地")
{
return true;
}
删除的图斑如果【DLMC】的字段值为“耕地”,就会弹出错误。
02
限制编辑内容在特定范围内
比如数据库里有2个图层,(因为代码要通过数据库这一共同联系作为媒介,所以2个图层一定要在同一数据库内)。
限制设施点必须在用地范围的边界内。
将触发器选择为【插入、更新】,在表达式中输入:
// 从同一个数据库里找到“用地范围”
var fw = FeatureSetByName($datastore, "用地范围", null, false);
// 用地范围和当前编辑的设施点相交,如果结果不为空(数量大于0),就给予通过。
// 否则就报错
return Count(Intersects(fw, Geometry($feature))) > 0
新创建的设施点如果在用地范围外,就会弹出错误。
03
禁止碎面
可以通过限制图斑的面积来禁止碎面的产生。
将触发器选择为【插入、更新】,在表达式中输入:
// 获取图斑面积
var mj = area(geometry($feature));
// 如果面积大于1平方米,就通过
if(mj>1)
return true
新创建或修改的图斑面积小于1平方米,就会弹出错误:
点击【保存】,正常情况下无法保存,可以看到这样的错误:
04
禁止超短线
通过计算相邻点之间的距离,可以禁止画出超短线。
将触发器选择为【插入、更新】,在表达式中输入:
// 获取环
var rings = geometry($feature)["rings"]
// 逐环处理
for(var i in rings){
// 环内每个点处理
for(var j=0; j < count(rings[i])-1; j++) {
// 算距离
var dis = Distance(rings[i][j],rings[i][j+1],'meters')
if(dis>1)
return true
}
}
创建或修改的时候,如果边界点之间的距离小于1米,就会弹出错误:
05
禁止尖锐角
通过计算相邻3个点之间的角度,可以禁止画出尖锐角。
将触发器选择为【插入、更新】,在表达式中输入:
// 获取环
var rings = geometry($feature)["rings"]
// 逐环处理
for(var i in rings){
// 环内每个点处理
for(var j=0; j < count(rings[i])-2; j++) {
// 算角度
var ang = Angle(rings[i][j],rings[i][j+1],rings[i][j+2])
// 保证在180度内
if(ang>180)
ang = 360-ang
// 小于20度就报错
if(ang<20)
return false
}
}
return true
这里我省略了计算最后一个点的情况,要计算的话,需要把第一个点加到列表末尾,有兴趣的可以自己试试。
创建或修改的时候,如果边界点的角度小于20度,就会弹出错误:
Part.04
Validation Rule
验证规则用于验证数据集中的错误。根据规则对现有要素进行评估,如果违反规则,则会创建错误要素。
表达式写法和计算、约束差不多。
这部分软件预制了许多规则,点击即用型规则,可以看到如下:
但是我试用过后,发现过程繁琐,而且有疑似bug,总之不太好用,有兴趣的可以自行尝试。
后面有空可以专门出一篇关于属性规则使用步骤的文章。
敬请期待。
【fin】
都看到这里了,给点个关注呗