基于FME的高程点与等高线矛盾检查
基于FME的高程点与等高线矛盾检查
痛点场景
地形图中,高程点记录了该位置的地面高程,等高线反映了地形起伏趋势。按理说,高程点的高程值应该在它所在的等高线区间之内——比如某条等高线高程为10m、相邻一条为15m,那夹在中间的高程点高程应该在10~15m之间。
但实际生产中常有这种情况:高程点的ELEV值和它周围的等高线高程不一致,比如点标了20m,但周围的等高线才5m和10m。这种点线矛盾是 DLG 质检中的常见问题,靠人工逐图幅排查非常费时。
本文介绍如何通过 FME 自建自定义转换器实现点线矛盾的批量自动检查。
检查规则说明
适用的数据
| 数据层 | 说明 |
|---|---|
| DM_DGX_L | 等高线,ELEV 记录高程值 |
| DM_GCZJD_P | 高程点,ELEV 记录高程值 |
| CLASID | 编码字段,用于区分要素类型 |
涉及的参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| gccode | 0702010010 | 高程点的 CLASID 编码 |
| dgxcode | 0701010220,0701010120 | 等高线的 CLASID 编码 |
| tkcode | 0102010020 | 内图廓编码(限定检查范围) |
| xjcode | 0605020120 | 县界编码(可选,排除行政边界干扰) |
核心思路
等高线之间围合成面,落到面内的高程点,其 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(问题描述="点线矛盾") ↓ FeatureWriterPythonCaller 核心代码
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 为空→ 高程点数据本身有问题,标"点线矛盾"
输出结果
| 字段 | 说明 |
|---|---|
| 问题描述 | “点线矛盾” |
| 所在图层 | 源要素类名 |
| layer | point_contradiction |
| GB | 国标分类码 |
| CLASID | 要素编码 |
以上是基于FME的高程点与等高线矛盾检查的思路和实现,供同行参考。