作者:Dist 时间: 2020-10-16
主要检查图层的完整性,主要错误有:
(1) 图层缺失;
(2) 图层别名与标准不一致;
(3) 图层类型与标准不一致;
(4) 图层冗余。
遍历构建端画布中配置的所有图层名,在图层标准中找到相应图层信息,判断该图层是否在质检数据中存在,如存在,则比对图层别名、图层类型,如果不存在,则为缺失。
获取图层标准中所有图层名,遍历质检数据所有图层、表,并判断其名称是否在标准中存在,如不存在,则为冗余。
代码问题(dzw):涉嫌多次打开图层;对象未释放;在图层标准中查找相应图层信息时用的是遍历,如改成 HashTable 或 Dictionary 去查找应该会更快(此处计算量较少,也可不计)。
按上面的“代码问题”提出的思路修改。先进行冗余检测,遍历打开所有图层、表并存储在字典中,再进行其他检测,检测时要用到的图层、表不用另外打开,直接从字典获取;在图层标准中查找相应图层信息时不用遍历,改成 Dictionary 去查找。速度提升三倍以上。
检查图层属性字段的结构,主要错误有:
(1) 字段数量不正确;
(2) 字段名称不准确导致字段缺失;
(3) 字段别名与标准字段别名不匹配;
(4) 字段长度不准确;
(5) 字段类型与标准不匹配;
(6) 字段小数位数与标准不匹配。
遍历配置的各个图层待检查字段集合,解析出当前图层、待检查字段集合,获取构建端的图层标准,打开图层,遍历当前待检查字段集合,在循环内获取当前图层的字段标准,由此得到当前字段的标准信息,在图层里查找该字段并获取字段类型、别名等信息,将二者进行比较,不符合的即为错误。
代码问题(dzw):在循环内获取当前图层的字段标准没必要,放在循环外即可。
按上面的“代码问题”提出的思路修改。
主要错误:
(1) 实际坐标系与标准坐标系不一致;
(2) 实际高程系与标准高程系不一致。
获取质检数据所有图层,去除不在标准中的,遍历图层,将高程系与标准比对,记录不一致的,再遍历图层,将坐标系与配置的标准坐标系比对,记录不一致的。
代码问题(dzw):遍历一次图层即可;标准高程系应该是通过读取配置获取,不知为何现在是在代码里写死的。
将坐标系、高程系的比较放在同一个函数内,将原先的两次遍历化成一次遍历,由于数据量小,速度只是略有提升。
V3-feeling
配置界面修改:
增加 xy 坐标系检查时,是检查的地理坐标系或者投影坐标系,如果是检查投影坐标系,需要配置三个参数值:投影、中央经线、椭球体
算法检查:
XY 坐标系检查:
地理坐标系:与 GCGS2000(代码中创建)对比名称是否一致
投影坐标系:检查坐标系中三个参数是否与配置的一样:投影、中央经线、椭球体
高程坐标系:于高程 1985(代码中创建)对比名称是否一致
**算法优化:**考虑到数据集下图层坐标系一定与数据集坐标系一致,所以这里先获取数据集和游离在数据集外的图层的坐标系列表,然后与目标坐标系比对,而不是遍历每个图层对比坐标系,速度提高五倍
主要错误:
(1) 数据中的要素超出行政区划范围。
获取构建端配置中参与算法的所有图层,遍历,验证它们是否在同一个数据集内,如果是,判断行政区划是否也在其中,如果不是,将行政区划拷贝进去。构建质检信息,将质检信息序列化为文件,启动质检进程,在进程内反序列化获取质检信息,遍历进行拓扑检查,将结果序列化为文件,再调用该进程的代码里反序列化,存进质检结果文件。
质检进程中可能是因为 arcengine 不稳定,导致有时不必要的失败,针对这种情况,重启质检进程(重启有次数限制),降低不必要失败的发生率。
主要错误:
(1) 图形自相交;
(2) 图形有不正确的环走向;
(3) 数据中有空图形。
暂时没用到。
主要错误:
(1) 图形完全重叠,判定图形重复;
(2) 图形完全重叠,且经过多个字段值判断后,多个字段值都一致,判定图形重复。
调 GP 工具。后面应该用不上。
主要错误:
(1) 图形是多部件。
遍历待检测图层,遍历图层中要素,当要素图形由小于 1 个部分构成或面状要素外环数目小于 2 时,认定该要素为正常,否则为多部件。
代码中用到 Search(IQueryFilter QueryFilter, bool Recycling),将 Recycling 设为 true;代码中获取要素图形用的是 pFeature.ShapeCopy,改为 pFeature.Shape。以此大幅提升质检速度。
主要错误:
(1) 同一层线要素相互重叠;
(2) 同一层线要素相互相交;
(3) 线要素自重叠;
(4) 线要素自相交;
(5) 同一层面要素相互重叠;
(6) 不同层面要素相互重叠。
获取图层标准,遍历规则数组,将其中的图层别名转化成图层名称;遍历数据集及图层,获取数据集和图层名称关系;遍历画布中配置的图层,验证图层是否存在且是否属于同一数据集,如果不是,则失败;再次遍历画布中配置的图层并打开,获取要素数目,如果数目为 0,则直接返回成功。遍历规则数组,构建拓扑规则,将信息序列化为文件,启动质检进程,在进程内反序列化获取质检信息,遍历进行拓扑检查,将结果序列化为文件,在调用该进程的代码里反序列化,存进质检结果文件。
代码问题(dzw):相同的图层被打开多次。
去除遍历数据集及图层的代码,在遍历画布中配置的图层时获取数据集名,并判断这些图层的数据集是否一致,不一致则失败,同时判断图层内的要素数目,为 0 则返回成功。这样保证一个图层只被打开一次,而不像之前被打开三次。经测试,某数据的质检时间在修改前为 10 分 12 秒,修改后为 5 分 25 秒。
质检进程中可能是因为 arcengine 不稳定,导致有时不必要的失败,针对这种情况,重启质检进程(重启有次数限制),降低不必要失败的发生率。
主要错误:
(1) 面要素面积小于设定的阈值,判定为面碎屑;
(2) 面要素面积小于设定的阈值,且经过多个字段值判断后,多个字段值都为空,判定为面碎屑。
先打开图层,如打开为空,则算法返回 false。根据配置信息构建过滤条件,将 OID 字段名设为 Subfields,遍历过滤结果,得到质检错误信息。
释放适宜的对象。另,发现执行该算法的图层比较多时,如果计算完毕后不释放已打开的表,速度快一倍多一点,且不会占用质检数据。
主要错误:
(1) 线要素长度小于设定的阈值,判定为线碎屑;
(2) 线要素长度小于设定的阈值,且经过多个字段值判断后,多个字段值都为空,判定为线碎屑。
先打开图层,如打开为空,则算法返回 false。根据配置信息构建过滤条件,将 OID 字段名设为 Subfields,遍历过滤结果,得到质检错误信息。
释放适宜的对象。另,发现执行该算法的图层比较多时,如果计算完毕后不释放已打开的表,速度快一倍多一点,且不会占用质检数据。
主要错误:
(1) 图形的检查字段的值为空。
根据图层名打开表,遍历配置信息,获取表中存在的字段名、字段类型、字段索引号列表,根据检测类型、字段名列表、字段类型列表构建查询空值的过滤条件并查询,根据标准信息获取字段名、字段别名字典。对于检测类型为 0 的,遍历查询出来的游标,在循环内构建错误信息,获取当前记录的唯一值,再添加到数据质检的错误信息中。对于检测类型为 1 的,遍历查询出来的游标,在循环内遍历字段索引列表,判断出值为空的字段,构建错误信息,获取当前记录的唯一值,再添加到数据质检的错误信息中。
代码问题(dzw):对于检测类型为 0 的,错误信息可在循环外构建,因为都一样;某些对象未释放。
按 V1 的“代码问题”进行了修改,检测类型为 0 的情况没测,效率应该提升不大,毕竟目前的数据循环不多。另,发现执行该算法的图层比较多时,如果计算完毕后不释放已打开的表,速度快一倍多一点,且不会占用质检数据。
主要错误:
(1) 多个图形的检查字段的值一样,造成该字段值不唯一。
遍历配置的待检测字段,如果是 gdb 文件,用 DataStatisticsClass 统计当前字段唯一值数目,再查询 count(当前字段),前者小于后者则有误。如果不是 gdb,根据当前字段分组且组中记录数大于 0,如查询到这样的记录,则有误。
代码问题(dzw):对象未释放。
释放适宜的对象。另,发现执行该算法的图层比较多时,如果计算完毕后不释放已打开的表,速度快一倍多一点,且不会占用质检数据。
主要错误:
(1) 代码字段值(如行政区代码)不在设定的字典库中;
(2) 代码字段值(如行政区代码)和名称字段值(如行政区名称)不匹配。
遍历对比项,获取对比字典,存入 Dictionary,如未配置名称字段且对比字典数目少于等于 1000,则过滤出编码字段不在字典 key 值中的记录;否则,根据对比字典生成临时表,将 key、value 加起来存入一个字段 A 中,如果质检文件为 gdb,过滤出编码字段值加名称字段值不在字段 A 值里的记录,这些记录视为错误,如果不是 gdb,将待质检图层与临时表 join,过滤出名称字段值与 value 值不同或编码字段值、key 字段值为空的记录,这些记录视为错误。
代码问题(dzw):某些对象释放得不好;某些代码可以写在遍历外;可以不建立临时表,如果字典数目大于 1000,可以将 not in 拆成多个。
按 V1 的“代码问题”修改。如果是 gdb 格式的质检数据不生成临时表,速度提升 3 倍左右。等有 mdb 的数据,再做相应修改。
将代码中用到的 IQueryDef 换成 IQueryDef2,将原先调的函数 Evaluate()换成 Evaluate2(true),速度大幅提升。原先针对某数据,该算法执行了 10 分钟左右,改之后只要 2 分钟不到。
主要错误:
(1) 源图层某一字段值满足符合查询条件,如:标准要求’BSM’字段的值大于零,sql 语句设定查询’BSM’的值小于或等于零的要素即为错误
根据配置的过滤条件筛选出记录,这些记录视为错误。
释放适宜的对象。另,发现执行该算法的图层比较多时,如果计算完毕后不释放已打开的表,速度快一倍多一点,且不会占用质检数据。
主要错误:
(1) 源图层某一数值型字段值总和大于(或小于、等于、大于等于、小于等于)目标表某一字段值,不满足图数一致性。
根据过滤条件过滤图层,遍历游标,对某字段值累加;根据过滤条件过滤指标表,对某字段值累加。将二者比较,并根据配置的操作符判断对错。
代码问题(dzw):没必要通过遍历的方式去做累加,可以用 sum 函数;某些对象未释放。
按 V1 的“代码问题”修改。质检数据的数据量太小,效率提升不明显。
用 IQueryDef2 做查询统计时不需要打开图层或表,将代码中打开图层、表的代码屏蔽。经测试,某数据进行该检查的时间由 44 秒提升为 11 秒。
V4-feeling
先前只固定支持图层与表,现在修改为也支持表与表之间的对比
主要错误:
(1) 源图层某一字段值与目标图层目标字段值不一致,如:生态保护红线图层中的多个要素,行政区代码字段值要与省级行政区图层中要素的行政区代码字段不一致即为错误
获取目标表的目标字段的所有可能值,存入 HashSet。遍历所有待质检图层,如果 HashSet 数目不大于 1000,则构建过滤条件,找出待质检图层源字段值不在目标表的目标字段值内的记录,这些记录视为错误;如果数目大于 1000,遍历待质检图层所有记录,如果源字段值不在 HashSet 内,则为错误。中间有段代码,遍历当前待质检图层,如源字段值为空,则为错误。
代码问题(dzw):如果 HashSet 数目大于 1000,可以将 not in 拆成多个,没必要全部遍历一遍;上面提到的“中间有段代码”很奇怪;对象释放得不好。
按 V1 的“代码问题”修改。中间的奇怪代码已去除,构建过滤条件时加上“目标字段 is null”条件;目标表的目标字段的所有可能值目前只有 1 个,且待检测的图层里的数据很少,效率提升不明显。经测试,该规则计算需要 15 秒左右,去除主体算法,只遍历打开图层,仍需要 13 秒左右。
主要错误:
(1) 代码字段值(如行政区代码)不在设定的字典库中;
(2) 名称字段值(如行政区名称)不在设定的字典库中。
遍历待检测字段,获取相应字典并构建出过滤条件,用该条件过滤出待检测图层中某字段值不在值域的记录。
代码问题(dzw):用 not in 未考虑里面的元素超过 1000 个的情况;对象释放得不好。
按 V1 的“代码问题”修改。遍历待检测字段时,会获取字段标准,再根据当前字段别名获取字段名,这里改掉,在循环外获取字段标准,并将字段名称、别名存入字典,再在循环内根据字段别名获取字段名,由于数据量太小,效率提升不明显。经测试,绝大多数时间都花在打开图层上。
主要错误:
(1) 字段有 X 个重复值,不满足设定的频度范围:大于等于 X,并且小于等于 X
遍历配置的字段,构建过滤条件,遍历过滤结果,获得不同字段值出现的数目,并根据配置的信息判断这个出现的数目是否符合条件,不符合则为错误。
代码问题(dzw):对象释放得不好。
只是释放了对象。
主要错误:
(1) 字段属性值中存在设定的非法字符,如:*、¥、#、%等
根据配置构建过滤条件,过滤出错误的记录。
代码问题(dzw):对象释放得不好。
只是释放了对象。
主要错误:
(2) 检查图层内要素间的缝隙
打开配置里的擦除图层,遍历待检测图层,用擦除图层擦除当前检测图层,将结果图层炸开,打开炸开后的图层,删除 shape_area 大于阈值的要素,其余要素即为缝隙,遍历这些要素并写入错误结果。
一次质检可能涉及到很多算法,一个图层可能会被多次打开,如果专门写个类,对这些图层进行管理,保证一次质检只打开一次应该会提高效率。很多算法对打开的图层未进行释放操作,如果有这个类,可以统一释放。这个会涉及到所有算法,暂时只是设想。
XXX like ‘ww%’,这样的 sql 在 gdb 中可行,在 mdb 中需要把%换成*