6

我们正在将一大堆 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"

我们如何解决这个问题?

4

3 回答 3

8

这个查询经常为我修复它:

UPDATE place_shapes
  SET geometry=ST_Buffer(geometry, 0.0);
于 2012-08-11T09:47:07.377 回答
7

虽然将要素缓冲为零是自相交多边形的已知修复方法(这在 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 字段,但不再保证它是唯一的。

于 2014-01-25T19:33:28.400 回答
0

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

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

0.0001是度数的容差,您可能需要根据自己的喜好进行调整,但街道地图数据似乎是正确的。

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

于 2012-08-10T01:09:20.673 回答