多边形之间PostGIS的递归相交(PostGIS recursive intersection b

2019-08-18 00:19发布

我试图在空间表执行所有的多边形之间的相交递归,并获得所得到的(多)pololygons和约每个交叉点为他们每个人的信息。

图像(不是真的在规模)来解释它:

假设有A, B, C表中的正方形。 我想有A, B, C, A+B, A+C, B+C, A+B+C在输出多边形和我需要知道A+B是的交点AB和等等。

到目前为止,我有执行交叉查询,但它并没有“切断”原多边形的相交部分。 例如:

Polygon A should be      A - (A+B) - (A+C) - (A+B+C)
Polygon A+C should be    A+C - (A+B+C)

结果我现在得到了的图像AA+C多边形:

下面是测试脚本,使用方格中的图像数据。 纵观area列,显然有些递归ST_Difference丢失,我只是无法弄清楚如何。 任何想法表示欢迎。

-- Create a test table
CREATE TABLE test (
    name text PRIMARY KEY,
    geom geometry(POLYGON)
);

-- Insert test data
INSERT INTO test (name, geom) VALUES 
    ('A', ST_GeomFromText('POLYGON((1 2, 1 6, 5 6, 5 2, 1 2))')),
    ('B', ST_GeomFromText('POLYGON((0 0, 0 4, 4 4, 4 0, 0 0))')),
    ('C', ST_GeomFromText('POLYGON((2 0, 2 4, 6 4, 6 0, 2 0))'));


-- Query    
WITH RECURSIVE 
source (rownum, geom, ret) AS (
    SELECT row_number() OVER (ORDER BY name ASC), ST_Multi(geom), ARRAY[name] FROM test 
),
r (rownum, geom, ret, incroci) AS (
    SELECT rownum, geom, ret, 0 FROM source 
    UNION ALL
    SELECT s.rownum, ST_CollectionExtract(ST_Intersection(s.geom, r.geom), 3), (r.ret || s.ret), (r.incroci + 1) 
        FROM source AS s INNER JOIN r ON s.rownum > r.rownum AND ST_Intersects(s.geom, r.geom) AND ST_Area(ST_Intersection(s.geom, r.geom)) > 0.5
),
result (geom, ret) AS (
    SELECT ST_Union(geom) AS geom, ret FROM r GROUP BY ret
)
SELECT geom, ST_Area(geom) AS area, ret FROM result ORDER BY ret

窗口函数是不是当然的这个特殊的例子绝对必要的,但是这个代码是我的真实情况,这的确就在身边多了一些东西的简化版本。

我使用PostgreSQL 9.2和2.0的PostGIS

Answer 1:

ST_DIFFRENCE不必是递归的,你已经把所有的多边形,使从每一个GEOM你要哪个。减去包含RET,但不等于它的其他geoms的工会。 这工作,所以你应该这样做有点像:

    WITH RECURSIVE 
source (rownum, geom, ret) AS (
    SELECT row_number() OVER (ORDER BY name ASC), ST_Multi(geom), ARRAY[name] FROM test 
),
r (rownum, geom, ret, incroci) AS (
    SELECT rownum, geom, ret, 0 FROM source 
    UNION ALL
    SELECT s.rownum, ST_CollectionExtract(ST_Intersection(s.geom, r.geom), 3), (r.ret || s.ret), (r.incroci + 1) 
        FROM source AS s INNER JOIN r ON s.rownum > r.rownum AND ST_Intersects(s.geom, r.geom) AND ST_Area(ST_Intersection(s.geom, r.geom)) > 0.5
),
result (geom, ret) AS (
    SELECT ST_Difference(ST_Union(r.geom),q.geom) AS geom, r.ret FROM r JOIN (SELECT r.ret,ST_UNION(COALESCE(r2.geom,ST_GeomFromText('POLYGON EMPTY'))) as geom FROM r LEFT JOIN r AS r2 ON r.ret<@r2.ret AND r.ret!=r2.ret GROUP BY r.ret) AS q on r.ret=q.ret GROUP BY r.ret,q.geom
)
SELECT geom, ST_Area(geom) AS area, ret FROM result ORDER BY ret


文章来源: PostGIS recursive intersection between polygons