Postgis - 如何检测受到攻击的更大区域的拦截

时间:2016-01-07 19:13:14

标签: postgresql postgis

我有两个地图加载到数据库中,一个地图具有状态的几何形状,另一个地图具有城市地区的几何形状。 我想制造和交叉以建立城市地区和州之间的关系,以了解哪个城市地区属于每个州。

问题在于一些城市地区占据两个州,市区属于州内几何区域内的更多区域。

我可以使用命令ST_Intersects,但它会添加城市与州相关的两种状态。

我必须使用什么sql命令?我已经阅读了文档 ST_CoveredByST_Within,但我不确定它们是否适用于我需要做的事情。

2 个答案:

答案 0 :(得分:1)

  • 首先在州和城市地区之间创建instersection对象并计算区域大小,使用ST_intersect上的JOIN将使用索引来避免开销。

  • 然后按区域大小为每个row_number订单分配urban_id

  • rn = 1表示只返回每个urban_id的最大区域。

WITH cte as (
    SELECT S.state_id, 
           U.urban_id, 
           ST_Area(ST_Intersection( S.geom, U.geom )) a_geom 
                 -- This create the intersect geom and calculate area
    FROM states S
    JOIN urban U
      ON ST_Intersects( S.geom, U.geom ) -- This is a boolean function
),
area as (
    SELECT state_id, 
           urban_id,                
           row_number() over (partition by urban_id order by a_geom desc) as rn
    FROM  cte
)
SELECT state_id,
       urban_id
FROM area
WHERE rn = 1

答案 1 :(得分:1)

您可以ST_Area使用ST_IntersectionLATERAL JOIN进行排序。

WITH states(id, geom) AS(
    VALUES  (1, ST_MakePolygon(ST_GeomFromText('LINESTRING(0 0, 1 0, 1 1, 0 1, 0 0)')))
        ,(2, ST_MakePolygon(ST_GeomFromText('LINESTRING(1 0, 2 0, 2 1, 1 1, 1 0)')))
),cities(id, geom) AS(
    VALUES  (1,ST_Buffer(ST_GeomFromText('POINT(0.5 0.5)'), 0.3))
        ,(2,ST_Buffer(ST_GeomFromText('POINT(1.5 0.5)'), 0.3))
        ,(3,ST_Buffer(ST_GeomFromText('POINT(1.1 0.5)'), 0.3))
)
SELECT c.id AS city, s.id AS state
FROM cities AS c
    CROSS JOIN LATERAL  (SELECT s.id, s.geom
                 FROM states AS s
                 WHERE ST_Intersects(s.geom, c.geom)
                 ORDER BY ST_AREA(ST_Intersection(s.geom,c.geom)) DESC
                 LIMIT 1) AS s