空间数据预处理:数据清洗、坐标转换、拓扑检查
数据进来之后,第一件事不是急着分析,而是先“打扫屋子”。
我做空间图谱这些年,见过太多人拿着脏数据硬跑,结果出图全是漏洞。白白浪费时间。今天这节,咱们把预处理这三大块掰开揉碎讲清楚:数据清洗、坐标转换、拓扑检查。
数据清洗:把脏数据堵在门外
空间数据和普通表格最大的区别在于——它自带几何信息。所以清洗时,既要查属性,也要查几何。
清洗的四个维度
| 维度 | 检查内容 | 常见问题 |
|---|---|---|
| 属性完整性 | 必填字段是否为空 | 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()来清理。
数据预处理流程总览
下面是本章三个核心步骤的关系图。理解了这个流程,你就知道预处理不是线性的,而是循环迭代——每修复一个问题,可能又需要回到清洗阶段重新检查。
预处理避坑清单
这些年踩过的坑,我整理成了一张清单。你下次做预处理时直接拿过来对照,能省不少时间。
- 先备份再动手——我见过有人直接在原表上删记录,删完发现删错了。
- 坐标系先统一起步——不要混合坐标系做空间计算,结果全是错的。
- 拓扑检查设容差——面重叠里有一种叫“微小压盖”,肉眼看不出来,但统计时会被自动扣减。
- 日志要完整——每一步清理了多少条记录、修复了多少几何,都要记下来。
- 数据量一大,先切片——100万行的表跑一次ST_IsValid可能要半小时,先切到小比例尺试试。
特别注意:在坐标转换之后,一定要重新做一次拓扑检查。因为不同投影下的几何精度不同,WGS84下看起来没问题的多边形,转成高斯投影后可能产生自相交。这不是数据坏了,是投影变形导致的数学问题,用ST_SnapToGrid(geom, 0.001)可以缓解。
嗯,空间数据预处理这块其实挺琐碎的,但绝对值得花时间。数据洗干净了,后面的分析才会靠谱。别想着跳过这步直接出图——你想想看,报告写得再漂亮,底层数据有洞,谁信?
我建议你做个预处理脚本工具箱。把清洗、转换、检查三个步骤写成可复用的函数或者Python脚本,每次新项目来了,一键跑一遍。我自己就是这么做的,后来连参数都设好了默认值,团队其他成员直接调用,省心不少。