I'm using a PL/R function and PostGIS to generate voronoi polygons around a set of points. The function that I am using is defined here. When I use this function on a particular dataset I get the following error message:
Error : ERROR: R interpreter expression evaluation error
DETAIL: Error in pg.spi.exec(sprintf("SELECT %3$s AS id,
st_intersection('SRID='||st_srid(%2$s)||';%4$s'::text,'%5$s')
AS polygon FROM %1$s WHERE st_intersects(%2$s::text,'SRID='||st_srid(%2$s)||';%4$s');",
:error in SQL statement : Error performing intersection: TopologyException: found non-noded
intersection between LINESTRING (571304 310990, 568465 264611) and LINESTRING (568465
264611, 594406 286813) at 568465.05533706467 264610.82749605528
CONTEXT: In R support function pg.spi.exec In PL/R function r_voronoi
From examining this part of the error message:
Error performing intersection: TopologyException: found non-noded intersection between
LINESTRING (571304 310990, 568465 264611) and LINESTRING (568465 264611, 594406 286813)
at 568465.05533706467 264610.82749605528
This is what the problem listed above looks like:

I initially thought that this message might be caused by the existence of identical points, and tried to solve this using the st_translate() function, used in the following way:
ST_Translate(geom, random()*20, random()*20) as geom
This does fix the problem, but my concern is that I am now translating all points up to ~20m in the x/y direction. I also can't tell what an appropriate translation amount is need. For example, in this dataset through trial and error a 20m * random number is ok, but how can I tell if this needs to be bigger?
Based on the image above I think the problem is that the point is intersecting with the line while the algorithm is trying to intersect the point with a polygon. I'm not sure what I should be doing to ensure that the point is within a polygon, rather than intersecting with a line. The error is occurring on this line:
"SELECT
%3$s AS id,
st_intersection(''SRID=''||st_srid(%2$s)||'';%4$s''::text,''%5$s'') AS polygon
FROM
%1$s
WHERE
st_intersects(%2$s::text,''SRID=''||st_srid(%2$s)||'';%4$s'');"
I have read through this previous question, What is a "non-noded intersection"? to try to better understand this problem, and would appreciate any advice on how best to solve it.
Answer
Through a lot of trial and error I eventually realized that the non-noded intersection resulted from a self-intersection problem. I found a thread that suggested using ST_buffer(geom, 0) can be used to fix the problem (though it does make it a lot slower overall). I then tried to use ST_MakeValid() and when applied directly to the geometry before any other function. This seems to fix the problem robustly.
ipoint <- pg.spi.exec(
sprintf(
"SELECT
%3$s AS id,
st_intersection(ST_MakeValid(''SRID=''||st_srid(%2$s)||'';%4$s''::text), ST_MakeValid(''%5$s'', 0)) AS polygon
FROM %1$s
WHERE
ST_Intersects(ST_MakeValid(%2$s::text),ST_MakeValid(''SRID=''||st_srid(%2$s)||'';%4$s''));",
arg1,
arg2,
arg3,
curpoly,
buffer_set$ewkb[1]
)
)
I've marked this as the answer as it seems to be the only approach that fixes my problem.
No comments:
Post a Comment