在shp2pgsql中自动修复环自交叉

时间:2012-08-10 01:09:21

标签: import gis postgis shapefile self-intersection

我们将一大堆ArcGIS shapefile导入PostGIS,并使用shp2pgsql即时转换。问题是,如果shapefile有任何环自交叉,则导入扼流:

NOTICE:  Ring Self-intersection at or near point -80.1338 25.8102
ERROR:  new row for relation "place_shapes" violates
  check constraint "shape_is_valid"

我们如何解决这个问题?

3 个答案:

答案 0 :(得分:6)

此查询经常为我修复:

UPDATE place_shapes
  SET geometry=ST_Buffer(geometry, 0.0);

答案 1 :(得分:4)

虽然按零调整特征是自相交多边形的已知修复 - 这在shp文件中非常常见 - 正如Marcelo所建议的那样,还有用于此目的的ST_MakeValid函数。还有一个相关的函数,ST_IsValidReason将告知问题所在的位置,而不是盲目地尝试修复它。

实际上,使用ST_MakeValid(geom)或ST_Buffer(geom,0)可能会产生几何类型的混合,包括孤立点和线串。因此,进一步的改进可能是检查返回的几何类型,并且仅包括例如由ST_MakeValid产生的多边形。

create table valid_geoms as
with make_valid (id, geom) as 
   (select 
      row_number() over() as id, 
     (ST_Dump(ST_MakeValid(geom))).geom as geom from invalid_table
  )
select id, geom from make_valid where ST_GeometryType(geom)='ST_Polygon';

其中invalid_table是原始shp2pgsql导入产生的表。

我在这里包含一个生成的id,因为ST_MakeValid将从输入几何中产生多个多边形。可以重写查询以包含原始id字段,但不再保证它是唯一的。

答案 2 :(得分:0)

事实证明,运行此后处理步骤可以解决问题:

UPDATE place_shapes
  SET geometry=ST_SimplifyPreserveTopology(geometry, 0.0001)
  WHERE ST_IsValid(geometry) = false;

0.0001是以度为单位的容差,您可能需要根据自己的喜好进行调整,但对于看似合适的街道地图数据。

此外,如果你的形状表强制执行有效性(它应该),你需要使用shp2pgsql来创建一个临时的未经验证的表,在那里修复你的多边形,然后只将它们复制到主表