Shapely判断点面包含与相交
Shapely 判断点与面的关系,核心用 contains 和 intersects:contains 要求点完全落在面的内部(不含边界),intersects 只要共享任意一点(内部或边界)就返回 True。边界上的点 contains 为 False、intersects 为 True;若希望边界也算“在内”,改用 covers。对象方法(如 poly.contains(point))与顶层函数效果一致,基于 DE-9IM,适用于笛卡尔平面几何。

contains、intersects、covers 怎么选
这三个谓词回答的问题不同,选错就会把边界点判丢或误收。contains(a, b) 为 True 的条件是:b 没有任何点落在 a 的外部,且 b 的内部至少有一点落在 a 的内部;因此面不包含自己的边界。intersects(a, b) 只要 a、b 有任何公共点(边界或内部)即为 True,它蕴含了 touches、overlaps、within 等多种关系。covers(a, b) 比 contains 更宽松:只要 b 没有点在 a 外部即可,边界点也算被覆盖。
| 谓词 | 边界点是否算“在内” | 典型用途 | 互逆关系 |
|---|---|---|---|
| contains | 否 | 严格内部判定、排除边界噪声 | within |
| covers | 是 | 面域归属、行政区划落点 | covered_by |
| intersects | 是(有交即 True) | 碰撞检测、候选集过滤 | disjoint 为其反义 |
点在多边形顶点或边上时:contains=False,covers=True,intersects=True。含孔洞的面不会 contains/covers 孔洞边界上的点,也不会把孔洞内的点判为内部。更多几何关系写法可对照本站Shapely 判断点在面内与几何关系计算一文。
点面判断代码怎么写
先构造几何对象,再调用谓词。步骤如下:
- 导入:from shapely import Point, Polygon, contains, intersects, covers(或 from shapely.geometry 兼容写法)。
- 建面:poly = Polygon([(0, 0), (10, 0), (10, 10), (0, 10)]);可选孔洞时第二个参数传内环坐标列表。
- 建点:pt_in = Point(5, 5);pt_on = Point(10, 5);pt_out = Point(15, 5)。
- 判定:poly.contains(pt_in) 为 True;poly.contains(pt_on) 为 False;poly.intersects(pt_on) 与 poly.covers(pt_on) 均为 True。
- 批量时用向量化:shapely.contains(poly, points_array) 或 contains_xy(poly, xs, ys),后者对单几何会自动做准备优化。
对象方法与顶层函数结果相同。空几何或 None 参与运算通常返回 False。Shapely 只做平面运算,忽略 Z;若输入是经纬度,面积、距离、缓冲区都会失真,需先投影,详见Shapely 计算面积与投影转换说明。
边界、孔洞、无效几何和浮点误差怎么处理
边界点是最常见坑:业务要求“落在面内(含边)”时,不要用 contains,改用 covers 或 intersects。孔洞内的点对 contains/covers 都是 False;孔洞边界点同样不被包含。
- 浮点近边界:因精度,点可能被判在外部。可用 poly.buffer(1e-9).contains(point),或先算 point.distance(poly) < epsilon;也可用 shapely.set_precision 统一网格精度。
- 无效几何:自相交、环未闭合会导致 is_valid=False,谓词结果不可靠。先查 geom.is_valid / is_valid_reason,再 shapely.make_valid(geom) 或临时 buffer(0) 修复。缓冲区生成与修复细节见Shapely 几何计算与缓冲区生成。
- 验收:对已知内部点、边界点、外部点、孔洞内点各测一次 contains/covers/intersects,结果应符合上表;修复后再次 is_valid 应为 True。
大量点怎么加速:prepare 与索引
单个复杂 Polygon 对成千上万个 Point 时,反复 contains/intersects 会慢。做法:
- 对固定的面执行 shapely.prepare(poly),预建索引;之后同一 poly 的 contains、intersects、covers、within 都会加速。
- 几何被修改后必须重新 prepare;可用 shapely.is_prepared 检查。
- 单几何坐标数组场景优先 contains_xy / intersects_xy(内部会自动准备)。
- 多对面、多对点时,再配合 STRtree 做候选过滤,再对候选做精确谓词。
截至 2026 年 10 月,稳定版为 2.2.0(支持 Python >=3.11,wheels 捆绑较新 GEOS),标量性能也有提升;版本变更可在 Shapely GitHub Releases 核对。多线程下不要并发修改同一已 prepare 的几何。
常见问题
点明明在边上,为什么 contains 是 False?
这是规范行为:contains 不含边界。改用 covers 或 intersects;若业务要严格内部,则保持 contains 并接受边界为 False。
带孔洞的面,孔里的点会不会被判在内?
不会。孔洞属于 exterior,contains 与 covers 对孔内点都返回 False;孔洞边界点也不被包含。
结果偶发错误,怀疑浮点或无效环怎么办?
先 geom.is_valid,无效则 make_valid 或 buffer(0);近边界用小 buffer 或 distance 阈值,或 set_precision 统一精度后再判。
向量化数组和单个对象方法可以混用吗?
可以。单对象用 poly.contains(pt),数组用 shapely.contains(poly, pts) 或 contains_xy;大量重复查询同一面时先 prepare。
点面关系优先分清业务要不要边界:要严格内部用 contains,要含边界用 covers,只要有交用 intersects;批量场景对固定面 prepare,并先处理无效几何与投影。建议把内部点、边界点、外部点写成固定用例,每次改代码后跑一遍验收,避免边界和孔洞踩坑。