执行 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
- 通过将它们包装在
ST_MakeValid()
中,确保合并前的几何图形 are valid。您还可以使用 select id, ST_IsValid(t.geom) from mytable;
查询他们的个人有效性,以过滤或更正受影响的人。如果你们中的一个几何本身以这种方式无效,它会有所帮助。这仍然会留下将多个有效几何组合在一起后出现无效的情况。
- 看看
ST_UnaryUnion(ST_Collect(ST_MakeValid(t.geom)))
是否改变了什么。它将 try to dissolve and node 组件线串。
- 当你真的绝望时,你可以对你的两个函数做一个PL/pgSQL包装,然后在异常块中切换到备用函数。
- 以牺牲一些精度和更高的性能为代价,您可以尝试 snapping them to grid
ST_Union(ST_SnapToGrid(t.geom,1e-7))
,逐渐将网格大小增加到 1e-6
、1e-5
.有些几何图形可能实际上并不相交,但非常接近,PostGIS 无法以其运行的精度来判断。您也可以尝试将此仅应用于有问题的几何形状,如果您可以查明它们的话。
- 正如 @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。
我有一个带有线条的大图层,以及一个需要计算这些线条的长度而不计算它们重叠的视图
完成一半工作的工作查询(但不考虑重叠,因此高估了数量)
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
- 通过将它们包装在
ST_MakeValid()
中,确保合并前的几何图形 are valid。您还可以使用select id, ST_IsValid(t.geom) from mytable;
查询他们的个人有效性,以过滤或更正受影响的人。如果你们中的一个几何本身以这种方式无效,它会有所帮助。这仍然会留下将多个有效几何组合在一起后出现无效的情况。 - 看看
ST_UnaryUnion(ST_Collect(ST_MakeValid(t.geom)))
是否改变了什么。它将 try to dissolve and node 组件线串。 - 当你真的绝望时,你可以对你的两个函数做一个PL/pgSQL包装,然后在异常块中切换到备用函数。
- 以牺牲一些精度和更高的性能为代价,您可以尝试 snapping them to grid
ST_Union(ST_SnapToGrid(t.geom,1e-7))
,逐渐将网格大小增加到1e-6
、1e-5
.有些几何图形可能实际上并不相交,但非常接近,PostGIS 无法以其运行的精度来判断。您也可以尝试将此仅应用于有问题的几何形状,如果您可以查明它们的话。 - 正如 @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。