Postgres / postgis-确保所有多边形均已封闭

时间:2018-07-12 18:26:46

标签: postgresql postgis sqlgeography sqlgeometry

我需要编写一个查询,查找所有未闭合的多边形,并通过复制第一个点并创建另一个终点来闭合它们。

我能够选择无效的行:

SELECT delivery_zone_id, polygon from delivery_zone WHERE ST_IsClosed(polygon::geometry) = FALSE;

我能够转储来自每个多边形的各个点:

SELECT delivery_zone_id, ST_AsText((dp).geom) FROM
    (SELECT delivery_zone_id, ST_DumpPoints(polygon::geometry) AS dp 
        FROM delivery_zone 
        WHERE ST_IsClosed(polygon::geometry) = FALSE
    ) AS coords;

结果如下:

1   POINT(-96.80037 33.09812)  ## Copy this point and add it to the set
1   POINT(-96.80427 33.0956)
1   POINT(-96.80401 33.09219)
1   POINT(-96.79603 33.09222)
1   POINT(-96.79346 33.09647)
1   POINT(-96.80037 33.09857)

4   POINT(-96.80037 33.099)    ## Copy this point and add it to the set
4   POINT(-96.80427 33.0956)
4   POINT(-96.80401 33.09219)
4   POINT(-96.79603 33.09222)
4   POINT(-96.79346 33.09647)
4   POINT(-96.80037 33.09923)

这是我的SQL技能所欠缺的地方。我需要一些帮助来复制第一个点并使用该数据创建一个新的终点。欢迎使用伪查询-我只需要查看它的外观,即可填补空白。


更新:最终解决方案

由于下面的JGH提供了答案,因此我能够创建以下更新查询。这将找到所有未封闭的多边形,并通过复制第一个点来添加新的终点。

  

注意:这仅适用于简单的“单个”多边形。如果您有复杂的外部和内部多边形,则需要对该查询进行一些大的更改。

UPDATE delivery_zone dz
SET polygon=ST_MakePolygon(ST_AddPoint(subquery.openline, ST_PointN(subquery.openline, 1), -1))
FROM (
  SELECT delivery_zone_id, ST_ExteriorRing(polygon::geometry) AS openline 
  FROM delivery_zone WHERE ST_IsClosed(polygon::geometry) = FALSE
) AS subquery
WHERE dz.delivery_zone_id = subquery.delivery_zone_id;

1 个答案:

答案 0 :(得分:2)

您可以尝试使用直线添加点,然后转换为多边形。

请注意,不可能创建一个不封闭的多边形...不太确定如何获得多边形,希望您一开始就能将其转换为线。

因此,想法是得到线,然后在最后一个位置(-1)处添加一个点。该点将与该线的第一点(位置1)相同。最后,您可以转换为多边形

WITH src AS (
    SELECT ST_GeomFromText('LINESTRING(0 0, 0 1, 1 1, 1 0)') As openline)
SELECT st_asText(openline), 
        st_asText(ST_MakePolygon(st_addPoint(openline,st_PointN(openline,1),-1)))
FROM src;



      st_astext          |           st_astext
-----------------------------+--------------------------------
 LINESTRING(0 0,0 1,1 1,1 0) | POLYGON((0 0,0 1,1 1,1 0,0 0))
(1 row)