【问题标题】:How to get around a GEOS error when doing st_union?执行 st_union 时如何解决 GEOS 错误?
【发布时间】:2021-11-25 16:10:37
【问题描述】:

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

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

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

返回 SQL 错误 [XX000] 的预期查询:错误:GEOSUnaryUnion:TopologyException:发现 LINESTRING (446659 422287、446661 422289) 和 LINESTRING (446659 422288、446660 422288) 之间的非节点交集在 446659.27994408668 处

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

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

有没有办法先使用首选查询,如果它在一行上返回错误,则使用另一个?比如:

case when st_length(st_union(t.geom)) = error then sum(st_length(t.geom))
else st_length(st_union(t.geom)) end

【问题讨论】:

    标签: sql postgresql intersection geos


    【解决方案1】:
    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 包含一个new overlay engine,因此如果您的select postgis_full_version(); 显示低于该值的任何内容和 GEOS 3.9.0,它可能是worthupgrading。即将推出的带有 GEOS 3.10.1 的 PostGIS 3.2.0 也应该在 validity checks 中提供一些改进。

    这是related thread

    【讨论】:

    • 1 - 我已经将 st_isvalid 作为 where 条件。在 st_union 之前或之后使用 st_makevalid 没有区别 2 - 执行 st_length(ST_UnaryUnion(ST_Collect(ST_MakeValid(t.geom)))) 会返回相同的错误 3 - 请您详细说明一下
    • @Luffydude 我已经用另一种解决方案、解释和文档链接以及相关线程更新了我的答案。如果您已经在使用ST_IsValid(),请编辑问题以反映这一点。 ST_IsValidwhere 中会过滤掉一些数据 ST_MakeValid 可能会修复 - 即使 ST_MakeValid 不能解决您的问题的所有实例,它也有可能修复一些问题,您可以应用不同的解决方案其余的。
    • 你的新 #4 工作了!谢谢!
    • 最新版本的 GEOS 和 PostGIS 包括一个重大改进的覆盖引擎。所以你应该尝试升级。如果您使用的是最新版本,请发布错误报告(带数据)
    • @dr_jts 谢谢。我已经添加了版本检查,其中包含指向您和 Paul Ramsey 关于该主题的精彩帖子的链接。我想我会在我的答案中保留有效性检查,以便任何偶然发现这个线程有相同问题但从不同几何类型开始的人。
    猜你喜欢
    • 1970-01-01
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-30
    • 1970-01-01
    • 1970-01-01
    • 2023-01-11
    相关资源
    最近更新 更多