You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PostgreSQL(PostGIS)中找出仅点接触的不重复多边形对

解决PostGIS中仅单点接触的多边形对(无重复)问题

嘿,这个需求我熟!你已经搭好了基础的CTE框架,现在就差最后一步去掉重复的反向对,而且咱们还可以从源头优化,避免生成多余的结果行。

方法一:从源头避免重复(推荐,性能更优)

直接在关联的时候用a.id < b.id代替a.id != b.id,这样就不会生成(cn2, cn1)这种反向的重复对,从一开始就保证每对只出现一次:

WITH kms AS (
    SELECT 
        a.county AS cn1, 
        b.county AS cn2,
        -- 可选:把接触点也查出来,方便后续验证
        ST_Intersection(a.geom, b.geom) AS touch_point
    FROM spatial.us_counties AS a
    JOIN spatial.us_counties AS b
        ON ST_Touches(a.geom, b.geom)
        AND a.id < b.id  -- 核心逻辑:避免生成反向重复对
        AND ST_GeometryType(ST_Intersection(a.geom, b.geom)) = 'ST_Point'
)
SELECT cn1, cn2, touch_point
FROM kms;

方法二:对已有CTE结果去重

如果不想修改原CTE结构,也可以在后续查询里通过比较名称(或ID)的顺序来过滤重复:

WITH kms AS (
    SELECT 
        a.county AS cn1, 
        b.county AS cn2,
        a.id AS id1,
        b.id AS id2
    FROM spatial.us_counties AS a, spatial.us_counties AS b
    WHERE ST_Touches(a.geom, b.geom) = 'true'
        AND a.id != b.id
        AND ST_GeometryType(ST_Intersection(a.geom,b.geom)) = 'ST_Point'
)
SELECT cn1, cn2
FROM kms t1
WHERE t1.id1 < t1.id2  -- 用ID比用名称更可靠(避免重名 county)
GROUP BY t1.cn1, t1.cn2;

额外注意点

  • 关于ST_GeometryType:如果两个多边形通过多个离散点接触,ST_Intersection会返回ST_MultiPoint,这个条件会自动排除这类情况,刚好符合你“仅通过单个点接触”的需求。
  • 性能优化:一定要确保us_counties表的geom字段创建了空间索引(CREATE INDEX idx_us_counties_geom ON spatial.us_counties USING GIST(geom);),不然数据量大时关联查询会非常慢。
  • 结果验证:可以把接触点字段保留,导入GIS工具可视化,确认确实是单个点接触的多边形对。

内容的提问来源于stack exchange,提问作者braveoldworld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:46:04