空间谓词用拓扑关系回答查询
从内部、边界和外部理解相交、包含、覆盖等空间谓词,并辨清边界条件。
空间谓词用拓扑关系回答查询
空间谓词回答两个几何对象是否相交、包含、位于内部或彼此分离。它们返回布尔关系,看似简单,结果却取决于几何的内部、边界和外部怎样定义。点落在多边形边界上,与点落在多边形内部并不是同一关系;忽略这一区别会造成边界对象遗漏或重复归属。
内部、边界和外部构成关系基础
简单要素模型把每个几何划分为内部、边界和外部。线的内部通常不含端点,多边形的内部不含外环与内环边界,点的边界为空。两个对象的这些部分是否相交,构成九交模型的基本判断。
DE-9IM 用矩阵描述 A 的内部、边界、外部与 B 对应部分交集的维度或空性。常见谓词是若干矩阵模式的命名形式。理解这一基础比背函数名可靠,因为不同谓词的差异常发生在边界。
几何有效性是前提。自交多边形的内部可能不明确,空间谓词可能报错或返回实现相关结果。查询前应确认数据类型、维度和有效性。
相交与分离覆盖最宽关系
只要两个几何有任何共同点,通常就满足相交,包括内部相交、边界接触和一个对象位于另一个内部。分离则表示它们没有任何共同点。相交适合初步筛选,却不能说明交集发生在哪里或具有多大维度。
两条线在端点相接和沿一段重合都属于相交,但网络含义不同;一个面与另一个面仅共享边界,也与面积重叠不同。需要进一步使用接触、重叠、交叉或交集几何判断。
浮点坐标和采集误差可能让看似相接的对象留下微小间隙。谓词不会自动应用业务容差。先缓冲或吸附可以改变结果,也会修改几何语义,必须按数据精度和用途决定。
包含、内部与覆盖的边界语义不同
“点在多边形里”常被理解为包含,但某些包含谓词要求对象内部之间有交集,且被包含对象不能位于外部。落在多边形边界上的点可能不满足严格内部或包含,却满足覆盖关系。
覆盖通常允许被覆盖对象位于内部或边界,因此在行政区边界分配中会出现一个边界点被相邻多个面共同覆盖。业务若要求唯一归属,还需制定边界规则,不能期望拓扑谓词自动决定。
包含与位于内部通常是相反方向的关系,调用参数顺序不能互换。函数名相近时应查看官方文档的矩阵定义和边界说明,而不是根据自然语言猜测。
接触、交叉和重叠受维度约束
接触通常表示两个几何有共同点,但内部不相交,例如相邻多边形共享边界。重叠要求对象具有相同维度,交集与双方同维但不等于任何一方;两个部分重叠的面可以满足,点与面则不会按同一定义重叠。
交叉用于描述交集维度低于至少一个输入的某些关系,例如两条线在内部交于一点,或线穿过多边形。具体适用组合由标准和实现规定。仅凭地图视觉判断,很容易把接触、交叉和重叠混为一类。
空间网络构建尤其需要区分:道路线在平面交叉不代表实际连通,高架属性和层级仍需参与。几何谓词回答空间关系,不替代领域语义。
包围盒筛选不是最终谓词
空间数据库通常先用索引中的包围盒找到可能满足条件的候选,再执行精确几何关系判断。包围盒相交只表示矩形范围有重合,凹多边形或带洞面可能在包围盒重合时实际分离。
PostGIS 的许多空间谓词会自动利用可用索引执行候选筛选。手工只写包围盒运算符可能提高筛选速度,却会产生假阳性;它适合粗筛,不能替代精确判断。
查询计划是否使用索引还取决于函数、参数、统计信息和数据分布。正确性应先由精确谓词保证,再通过执行计划优化性能。
坐标参考与精度仍然重要
拓扑谓词主要依据坐标关系,不直接计算距离,但错误 CRS 会让本应叠加的对象处于不同坐标空间。数据库若不阻止不同 SRID 比较,也可能产生无意义结果;即使阻止,也不能发现标签正确、坐标实际错误的数据。
二维简单要素谓词通常只考虑 X、Y,Z 或 M 可能被保留却不参与关系。两条线路在平面交叉但高度不同,二维谓词仍会认为相交。需要三维语义时,应使用明确支持的类型和函数,并核对实现边界。
坐标精度降低、重投影和几何简化都可能改变边界关系。处理前后应重新运行拓扑质量检查,而不是沿用旧关系结果。
查询设计要对应业务问题
选择谓词前应把问题写清楚:边界是否算在区域内,线端点相接是否构成连接,面积重叠需要大于多少,洞内对象是否排除。一个布尔谓词无法同时表达容差、比例和唯一归属。
对高价值流程,应建立边界、洞、多部件、无效几何和精度误差测试样本。结果需要与标准定义和数据库版本核对,尤其在升级几何库后执行回归测试。
空间谓词提供了可计算的拓扑语言。它们可靠的前提是有效几何、一致 CRS、明确边界语义和业务规则。函数名只是入口,内部、边界与外部的关系才是判断依据。
资料依据
- Open Geospatial Consortium:Simple Feature Access,https://www.ogc.org/standards/sfa/
- PostGIS Project:PostGIS Manual,https://www.postgis.net/documentation/manual/