5.1 空间关系与拓扑判断


5.1 空间关系与拓扑判断

本节摘要:空间分析的基础是判断几何关系。本节讲 DE-9IM 模型、相交/包含/相邻等空间关系——GIS 算法的基石。

核心问题

阅读完本节,你应当能够:

  1. 理解 DE-9IM 模型
  2. 区分主要空间关系
  3. 用 PostGIS 做空间判断

概念脉络

一、为什么需要空间关系

GIS 要回答"这块地和那块地相邻吗"、"这个点在哪个区内"等问题。空间关系判断是空间查询、叠加分析、拓扑验证的基础。

二、DE-9IM 模型

DE-9IM(Dimensionally Extended 9-Intersection Model)用两个几何的内部(I)、边界(B)、外部(E)的 9 个交集维度判断空间关系:

图 5-1 DE-9IM 空间关系

图 5-1 DE-9IM 空间关系

关系 含义
Intersects 有任何公共点
Contains A 完全包含 B
Within A 在 B 内
Touches 边界相切,内部不相交
Overlaps 同维交集,非包含
Crosses 内部相交,不同维
Equals 完全重合

三、PostGIS 空间判断

-- 点在哪个区 SELECT name FROM districts WHERE ST_Contains(geom, ST_Point(116.4, 39.9)); -- 两块地相邻 SELECT a.name, b.name FROM parcels a JOIN parcels b ON ST_Touches(a.geom, b.geom); -- 范围内要素 SELECT name FROM pois WHERE ST_DWithin(geom, ST_Point(116.4, 39.9), 1000);

PostGIS 用 ST_ 前缀函数做空间判断,底层用 GEOS 库实现 DE-9IM。

四、空间索引加速

空间判断慢,加空间索引加速。PostGIS 用 GiST 索引:

CREATE INDEX idx_pois_geom ON pois USING GIST(geom);

空间索引用 R-树,先粗筛候选(边界框相交),再精确判断,快几个数量级。

五、坐标系注意

空间关系判断要在合适坐标系:

  • 平面关系:投影坐标系(如 EPSG:3857 米单位)
  • 球面关系:地理坐标系(EPSG:4326 度单位)用球面公式

PostGIS 在 4326 上用 ST_DWithin 会用球面距离,但 ST_Area 要投影到平面才准。

⚠️ 常见坑:在 4326 上做面积/距离量算——4326 是度单位,结果不准。投影到平面坐标系(如 3857 或 UTM)再算。

💡 关键直觉:DE-9IM 用内部/边界/外部 9 交集定义空间关系。PostGIS 用 ST_ 函数判断,加 GiST 空间索引加速。量算要投影到平面坐标系。

六、DE-9IM 矩阵怎么看

DE-9IM 的 9 个值分别是两个几何的内部(I)、边界(B)、外部(E)两两求交的维度:-1 表示不相交,0 表示交于点,1 表示交于线,2 表示交于面。PostGIS 可以用 ST_Relate 拿到矩阵,调试空间关系时非常有用:

-- 返回两个几何的 DE-9IM 矩阵 SELECT ST_Relate( ST_GeomFromText('POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))', 4326), ST_GeomFromText('POINT(1 1)', 4326) ); -- 点在面内时结果为 FF2F110212 等形态,可从矩阵反推关系

常见关系的矩阵模式可以记一个:包含关系一般满足 T*****FF*,相交满足 T********,相邻满足 FT*******。实际开发中直接调用 ST_Contains、ST_Intersects 就够了,矩阵主要用于理解函数行为和排查边界情况。

七、拓扑错误与修复

空间关系判断的前提是数据拓扑正确。常见的拓扑错误有:

  • 悬挂节点:线的端点没接到其他线上,形成断头路。
  • 重复节点:同一位置出现重复点,导致自相交。
  • 缝隙与重叠:相邻面之间有缝或叠,行政区统计会重算或漏算。
  • 自相交:一个面自己交叉,面积计算出错。

PostGIS 提供检查和修复函数:

-- 检查几何是否有效 SELECT id, ST_IsValidReason(geom) FROM parcels WHERE NOT ST_IsValid(geom); -- 修复无效几何(去掉自相交部分) UPDATE parcels SET geom = ST_MakeValid(geom) WHERE NOT ST_IsValid(geom);

数据入库前先跑一遍有效性检查,能省掉大量后续排查时间。

八、关系判断的索引配合

空间关系函数能否用索引,取决于写法。像 ST_Intersects(a.geom, b.geom) 这类函数底层是"索引粗筛 + 精算",只要两边几何列都有 GiST 索引就能提速。但要注意:把几何包进函数再比较(如 ST_Intersects(ST_Buffer(a.geom,10), b.geom))会让优化器无法直接利用索引,性能骤降。大数据量下,先把缓冲范围算出来存字段,再建索引,是常见优化手段。

九、实际业务中的关系判断

业务场景里空间关系很少单独出现,通常是组合判断。例如选址分析:找"位于规划区 A 内、距离主干道 200 米以内、且不与生态红线相交"的地块:

SELECT p.id, p.name FROM parcels p JOIN districts a ON ST_Contains(a.geom, p.geom) JOIN roads r ON ST_DWithin(p.geom, r.geom, 200) LEFT JOIN eco_redline e ON ST_Intersects(p.geom, e.geom) WHERE a.name = '规划区A' AND e.id IS NULL GROUP BY p.id, p.name;

这类 SQL 把关系判断、距离判断、排除逻辑揉在一起,是 GIS 业务查询的常见形态,值得熟练掌握。

十、空间关系的边界情况

空间关系判断在边界上最容易出问题,几个典型场景:

  • 点在边界上:点在多边形的边界上,ST_Contains 返回 false(边界不算内部),ST_Covers 返回 true。业务上"这个点属不属于该区"要用 ST_Covers 才符合直觉。
  • 精度容差:浮点计算导致两个本该相交的几何差一点点不相交。生产数据先做有效性检查和简化,必要时用 ST_Snap 或 ST_Buffer(geom, 0) 消除微缝。
  • 多几何要素:MULTIPOLYGON 等复合几何的关系判断按整体算,拆开看单个部件可能结果不同。查询前明确数据是单要素还是复合要素。
  • 空几何:几何列允许空值时,空间判断要加 IS NOT NULL 条件,否则空几何参与运算会得到奇怪结果或报错。

十一、与其他算法的关系

空间关系判断是其他空间算法的基础构件:叠加分析用相交判断决定哪些要素参与裁剪;网络分析用点和线的包含关系把起点投影到网络上;空间统计按包含关系把属性聚合到区域。学这一节时不要把函数当孤立知识,遇到后面的叠加、缓冲、网络章节时,会不断回头用到"两个几何关系是什么"这个基本功。这也是本教程把空间关系放在第 5 章第一小节的原因。

十二、验证与调试技巧

写空间关系 SQL 调试时,推荐一套组合拳:

-- 第一步:看两个几何的实际形状(用文本或转 GeoJSON 检查) SELECT ST_AsText(geom) FROM parcels WHERE id = 100; -- 第二步:算两个几何的最小距离,确认是"差一点相交"还是"完全不相干" SELECT ST_Distance(a.geom, b.geom) FROM parcels a, parcels b WHERE a.id=100 AND b.id=200; -- 第三步:逐个关系函数验证 SELECT ST_Intersects(a.geom, b.geom), ST_Within(a.geom, b.geom), ST_Touches(a.geom, b.geom) FROM parcels a, parcels b WHERE a.id=100 AND b.id=200;

配合 QGIS 打开数据目视检查,绝大部分"关系判断结果不符合预期"都能快速定位:要么是数据本身有拓扑问题,要么是坐标系统一没做好,要么是对函数语义理解偏差。

要点速记

  • 空间关系:GIS 算法基石,判断几何间关系。
  • DE-9IM:内部/边界/外部 9 交集模型定义关系。
  • 主要关系:相交、包含、在内、相邻、重叠、交叉、相等。
  • PostGIS:ST_ 函数判断,底层 GEOS。
  • 空间索引:GiST R-树粗筛加速。
  • 坐标系:量算投影到平面,4326 用球面公式。

下一节讲叠加分析和缓冲区。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U