基于FME的高程点与等高线矛盾检查

基于FME的高程点与等高线矛盾检查

痛点场景

地形图中,高程点记录了该位置的地面高程,等高线反映了地形起伏趋势。按理说,高程点的高程值应该在它所在的等高线区间之内——比如某条等高线高程为10m、相邻一条为15m,那夹在中间的高程点高程应该在10~15m之间。

但实际生产中常有这种情况:高程点的ELEV值和它周围的等高线高程不一致,比如点标了20m,但周围的等高线才5m和10m。这种点线矛盾是 DLG 质检中的常见问题,靠人工逐图幅排查非常费时。

本文介绍如何通过 FME 自建自定义转换器实现点线矛盾的批量自动检查。

检查规则说明

适用的数据

数据层说明
DM_DGX_L等高线,ELEV 记录高程值
DM_GCZJD_P高程点,ELEV 记录高程值
CLASID编码字段,用于区分要素类型

涉及的参数

参数默认值说明
gccode0702010010高程点的 CLASID 编码
dgxcode0701010220,0701010120等高线的 CLASID 编码
tkcode0102010020内图廓编码(限定检查范围)
xjcode0605020120县界编码(可选,排除行政边界干扰)

核心思路

等高线之间围合成面,落到面内的高程点,其 ELEV 应在组成该面的等高线高程范围之内。超出范围即为点线矛盾。

网格化的原因

等高线是开曲线,大量不与图廓相交,直接构面会在不闭合区域失效。采用350m 网格制造闭合条件——网格四边是闭合框,等高线穿进网格后必然与网格边界相交,形成闭合条件,保证每个高程点都能定位到有明确等高线高程边界的包围面。

网格大小是经验值:太小了网格内可能没有等高线或只有单条,构不出有效面,大量区域无法判断;太大了起不到人工闭合的效果,接近不网格化。350m 在 1:10000 数据上是经验值,可根据等高线密度适当调整。

FME实现

整体流程如下:

流程结构

TestFilter → 按CLASID分流 ├── 高程点 → Tester确认编码 → SpatialFilter(Candidate) ├── 等高线 → 2DGridAccumulator(350m网格) → GeometryCoercer(转线) → Intersector │ └── 直接 → Intersector(原始等高线本身) ├── 内图廓 → Intersector └── 县界 → Intersector Intersector → AreaBuilder(线转面,List Name设为`E{}`,收集ELEV属性) ↓ ListDuplicateRemover(去重) ↓ ListConcatenator(拼接为逗号分隔字符串→_concatenated) ↓ SpatialFilter(BASE=面,Candidate=高程点) ↓ PASSED PythonCaller ↓ Tester筛选flag="点线矛盾" ↓ AttributeCreator(问题描述="点线矛盾") ↓ FeatureWriter

PythonCaller 核心代码

ListConcatenator 将去重后的E{}.ELEV拼接为逗号分隔字符串_concatenated(AreaBuilder 记录方向时会在列表中混入无高程值的 opposite 项,拼接能天然跳过空值,避免遍历列表时处理这些干扰项),SpatialFilter 把该属性合并到高程点上,PythonCaller 直接读:

definput(self,feature):try:elevs=feature.getAttribute('_concatenated')elev=feature.getAttribute('ELEV')# 高程值缺失 → 标矛盾ifelevisNoneorstr(elev).strip()=='':feature.setAttribute('flag','点线矛盾')self.pyoutput(feature)returnelev=float(elev)# 没有边界高程信息 → 无法判断ifnotelevsor','notinelevs:feature.setAttribute('flag','无法判断')self.pyoutput(feature)returnelev_values=[float(v)forvinelevs.split(',')]# 只有两条等高线夹出的面才做判断iflen(elev_values)!=2:feature.setAttribute('flag','无法判断')self.pyoutput(feature)returne0,e1=elev_values[0],elev_values[1]min_elev=e0ife0<e1elsee1 max_elev=e1ife0<e1elsee0ifmin_elev<elev<max_elev:feature.setAttribute('flag','正常')else:feature.setAttribute('flag','点线矛盾')exceptException:feature.setAttribute('flag','无法判断')self.pyoutput(feature)defclose(self):pass

判断逻辑说明

  • 两条等高线→ 范围明确,做开区间判断
  • 单条或≥3条→ 无法确定准确区间,标"无法判断"交人工复核
  • ELEV 为空→ 高程点数据本身有问题,标"点线矛盾"

输出结果

字段说明
问题描述“点线矛盾”
所在图层源要素类名
layerpoint_contradiction
GB国标分类码
CLASID要素编码

以上是基于FME的高程点与等高线矛盾检查的思路和实现,供同行参考。