Postgresql 如何解决 GEOSIntersects 错误?

问题描述

所以我有一个包含超过 1700 行的大型选择查询,它基本上从与多边形表相交的各种表(一些点,一些线,它们之间有各种条件)中提取数据

select a.id
(select count(*) from pointtable2 b where st_contains(a.geom,b.geom ) )
(select sum(st_length(st_intersection(a.geometry,r.geometry))) from linetable3 b where st_intersects(a.geom,b.geom ) ),(select a whole bunch of stuff from several other tables where multitude of conditions..)
from polygontable a
group by a.id,a.geom

特别是一个线层具有无效的几何图形,最初我通过添加 where 条件来处理这些几何图形

geometrytype(r.geom) <> 'MULTICURVE'::text AND st_isvalid(r.geom) is true

问题是,即使在这些条件下,我仍然收到以下错误

sql Error [XX000]: ERROR: Geosintersects: IllegalArgumentException: RobustDeterminant encountered non-finite numbers 
ERROR: Geosintersects: IllegalArgumentException: RobustDeterminant encountered non-finite numbers 
ERROR: Geosintersects: IllegalArgumentException: RobustDeterminant encountered non-finite numbers 

修复错误的几何图形将是长期解决方案,但该报告视图是紧急需要的,在忽略失败行的同时运行查询的最佳方法是什么?或者我如何能够发现哪些几何结构/哪些代码行失败了?

解决方法

这个问题很可能在最新的 PostGIS 版本中得到解决。请参阅下面的示例 using PostgreSQL 12 and PostGIS 3.0

WITH j(geom)AS (
  VALUES ('MULTICURVE((0 0,5 5))'::GEOMETRY),('POINT(0 0 42)'::GEOMETRY),('POLYGON((0 0,1 1,1 2,0 0))'::GEOMETRY),--invalid polygon
         ('POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 1))'::GEOMETRY)
  )
SELECT 
  ST_AsText(geom),ST_IsValidReason(geom),GeometryType(geom),ST_Intersection(ST_MakeValid(geom),'POINT(0 0)'::GEOMETRY)
FROM j
WHERE 
  ST_Intersects(geom,'POINT(0 0)'::GEOMETRY) AND 
  GeometryType(geom) <> 'MULTICURVE' 
  AND   ST_IsValid(geom); 

                      st_astext                       | st_isvalidreason | geometrytype |                      st_intersection                       
------------------------------------------------------+------------------+--------------+------------------------------------------------------------
 POINT Z (0 0 42)                                     | Valid Geometry   | POINT        | 0101000080000000000000000000000000000000000000000000004540
 POLYGON((0 0,1 1)) | Valid Geometry   | POLYGON      | 010100000000000000000000000000000000000000

进一步阅读: