执行 st_union 时如何解决 GEOS 错误?

How to get around a GEOS error when doing st_union?

我有一个带有线条的大图层,以及一个需要计算这些线条的长度而不计算它们重叠的视图

完成一半工作的工作查询(但不考虑重叠,因此高估了数量)

select name, sum(st_length(t.geom)) from mytable t where st_isvalid(t.geom) group by name

returnsSQL错误[XX000]的预期查询:错误:GEOSUnaryUnion:TopologyException:发现LINESTRING(446659 422287、446661 422289)和LINESTRING(446659 422288, 446660 422288) 在 446659.27944086661 422288.0015405959

select name,st_length(st_union(t.geom)) from mytable t where st_isvalid(t.geom) group by name

问题是后者对前 200 行工作正常,只有当我尝试导出整个视图时才出现错误

是否有一种方法可以先使用首选查询,如果 returns 某行出现错误,则使用另一行?类似于:

case when st_length(st_union(t.geom)) = error then sum(st_length(t.geom))
else st_length(st_union(t.geom)) end
  1. 通过将它们包装在 ST_MakeValid() 中,确保合并前的几何图形 are valid。您还可以使用 select id, ST_IsValid(t.geom) from mytable; 查询他们的个人有效性,以过滤或更正受影响的人。如果你们中的一个几何本身以这种方式无效,它会有所帮助。这仍然会留下将多个有效几何组合在一起后出现无效的情况。
  2. 看看 ST_UnaryUnion(ST_Collect(ST_MakeValid(t.geom))) 是否改变了什么。它将 try to dissolve and node 组件线串。
  3. 当你真的绝望时,你可以对你的两个函数做一个PL/pgSQL包装,然后在异常块中切换到备用函数。
  4. 以牺牲一些精度和更高的性能为代价,您可以尝试 snapping them to grid ST_Union(ST_SnapToGrid(t.geom,1e-7)),逐渐将网格大小增加到 1e-61e-5.有些几何图形可能实际上并不相交,但非常接近,PostGIS 无法以其运行的精度来判断。您也可以尝试将此仅应用于有问题的几何形状,如果您可以查明它们的话。
  5. 正如 @dr_jts PostGIS 3.1.0 includes a new overlay engine, so if your select postgis_full_version(); shows anything below that and GEOS 3.9.0, it might be worth upgrading. The upcoming PostGIS 3.2.0 with GEOS 3.10.1 should also provide some iprovement in validity checks 提醒的那样。

这是一个related thread