空间数据预处理:数据清洗、坐标转换、拓扑检查

数据进来之后,第一件事不是急着分析,而是先“打扫屋子”。

我做空间图谱这些年,见过太多人拿着脏数据硬跑,结果出图全是漏洞。白白浪费时间。今天这节,咱们把预处理这三大块掰开揉碎讲清楚:数据清洗、坐标转换、拓扑检查。

数据清洗:把脏数据堵在门外

空间数据和普通表格最大的区别在于——它自带几何信息。所以清洗时,既要查属性,也要查几何。

清洗的四个维度

维度 检查内容 常见问题
属性完整性 必填字段是否为空 ID 缺失、名称字段空白
几何有效性 自相交、重复点、空几何 面要素自相交、线要素退化
逻辑一致性 分类编码是否符合规范 道路类型填成了建筑物代码
重复检测 空间与属性双重匹配 同一个点录了两遍

我个人习惯先用一个脚本扫描全库,把问题清单列出来,再挨个修。别上来就动手改,先看看问题分布。

空间数据的“空几何”是隐形杀手。一条线只有两个节点但坐标完全一样,这种数据做拓扑时会直接崩溃。检测命令很简单:

SELECT * FROM buildings
WHERE ST_IsValid(geom) = FALSE;

查出无效记录后,用ST_MakeValid()自动修复。

去过重的坑

我记得有一次处理全国POI数据,发现“北京大学”出现了三次,坐标却差了不到一米。为什么?

三个不同渠道的数据源合并时没有去重。我后来用空间距离加名称相似度做双重过滤,总算清干净。

去重时别只看空间重合,加一个名称模糊匹配更稳妥。可以用ST_DWithin()先圈出候选集,再用similarity()函数比字符串。

坐标转换:让数据说同一种语言

空间图谱最怕什么?坐标系不统一。

你想想看,一个图层用WGS84经纬度,另一个图层用北京54投影坐标,叠在一起完全错位。这不是数据错了,是坐标系没对齐。

坐标系的核心概念

类型 代表 特点
地理坐标系 WGS84、CGCS2000 用经纬度表示,单位度
投影坐标系 UTM、高斯-克吕格 用米表示,适合计算面积与距离
地方坐标系 城市独立坐标系 为局部区域定义,精度高

做转换时,我建议用EPSG编码。通用编码一查就知道参数,比如WGS84是4326,CGCS2000是4490。

千万不要直接用加常数来转!有些工程师图省事,给经纬度统一加一个固定偏移量,以为能对齐。实际上地球表面是曲面,线性偏移只能在小范围勉强可行,跨省就完全变形。我曾经接手过一个项目,前一个人就是这么干的,结果修复成本比重做还高。

转换的实操路径

用PostGIS做一步到位转换,是我最常用的方式:

-- WGS84 转 CGCS2000 投影带
SELECT ST_Transform(geom, 4490) AS cgcs_geom
FROM raw_points;

转换之前,先查一下源数据的SRID。很多人不设SRID,PostGIS默认是0,转换时直接报错。

一定要先设置正确的SRID,再执行ST_Transform。举例:SELECT ST_SetSRID(geom, 4326)。

拓扑检查:把逻辑漏洞补上

拓扑是什么?说白了就是空间元素之间的逻辑关系。面不能重叠,线不能悬空,点必须落在线上。

我刚开始做拓扑时,总觉得差不多就行。直到有一次做行政区划图,两个相邻地块重叠了几厘米,结果面积统计错了上千亩。从那以后,每批数据必过拓扑检查。

必须盯死的三类拓扑错误

  • 面重叠:两个地块的边界互相覆盖。修复需要用ST_Difference()切分。
  • 线悬空:道路的端点没有连接任何节点。一般是因为采集漏了一段。
  • 点脱离:井盖点不在管道线上。常发生在手动录入时坐标不小心拖错了。

检查面重叠的SQL:

SELECT a.id, b.id
FROM parcels a, parcels b
WHERE a.id < b.id
  AND ST_Overlaps(a.geom, b.geom);

拓扑检查一定要做“自相交排查”。有些面要素看起来正常,但实际上节点顺序错乱,导致多边形自相交。PostGIS里用ST_IsValidReason(geom)可以定位到具体哪个节点出了问题。

还有一种常见错误是“伪节点”。一条道路被切成了很多小段,中间节点多余但没实际分支。这会影响路径分析。我一般用ST_SimplifyPreserveTopology()来清理。

数据预处理流程总览

下面是本章三个核心步骤的关系图。理解了这个流程,你就知道预处理不是线性的,而是循环迭代——每修复一个问题,可能又需要回到清洗阶段重新检查。

空间数据预处理流程 原始空间数据 数据清洗 去重 · 有效性 · 完整性 坐标转换 EPSG统一 · 投影对齐 拓扑检查 面重叠 · 线悬空 · 自相交 干净的预处理数据 发现问题,回退修正 处理要点 • 清洗在前,转换在后 • 每次修复后重新过拓扑 • 保留原始数据备份

预处理避坑清单

这些年踩过的坑,我整理成了一张清单。你下次做预处理时直接拿过来对照,能省不少时间。

  1. 先备份再动手——我见过有人直接在原表上删记录,删完发现删错了。
  2. 坐标系先统一起步——不要混合坐标系做空间计算,结果全是错的。
  3. 拓扑检查设容差——面重叠里有一种叫“微小压盖”,肉眼看不出来,但统计时会被自动扣减。
  4. 日志要完整——每一步清理了多少条记录、修复了多少几何,都要记下来。
  5. 数据量一大,先切片——100万行的表跑一次ST_IsValid可能要半小时,先切到小比例尺试试。

特别注意:在坐标转换之后,一定要重新做一次拓扑检查。因为不同投影下的几何精度不同,WGS84下看起来没问题的多边形,转成高斯投影后可能产生自相交。这不是数据坏了,是投影变形导致的数学问题,用ST_SnapToGrid(geom, 0.001)可以缓解。

嗯,空间数据预处理这块其实挺琐碎的,但绝对值得花时间。数据洗干净了,后面的分析才会靠谱。别想着跳过这步直接出图——你想想看,报告写得再漂亮,底层数据有洞,谁信?

我建议你做个预处理脚本工具箱。把清洗、转换、检查三个步骤写成可复用的函数或者Python脚本,每次新项目来了,一键跑一遍。我自己就是这么做的,后来连参数都设好了默认值,团队其他成员直接调用,省心不少。