[postgis-tickets] [PostGIS] #5392: Aggregate ST_Union fails to join some "circles" when radius is too large - lwgeom_unaryunion_prec: GEOS Error: TopologyException

PostGIS trac at osgeo.org
Fri Jun 2 10:28:57 PDT 2023


#5392: Aggregate ST_Union fails to join some "circles" when radius is too large -
lwgeom_unaryunion_prec: GEOS Error: TopologyException
----------------------+---------------------------
  Reporter:  rotten   |      Owner:  pramsey
      Type:  defect   |     Status:  closed
  Priority:  medium   |  Milestone:  PostGIS 3.3.4
 Component:  postgis  |    Version:  3.3.x
Resolution:  invalid  |   Keywords:
----------------------+---------------------------
Changes (by pramsey):

 * status:  new => closed
 * resolution:   => invalid

Comment:

 This is less interesting than it appears to be on first inspection (but it
 is still pretty interesting). Because the SQL starts by taking buffers of
 points, which intuitively should be easy-to-process circles, the result is
 surprising to our eyes.

 However, taking the SQL apart into something a little more step wise, the
 real problem is just the normal boring one of feeding invalid inputs to
 the overlay functions.

 {{{
 create table polys (name text, geom geometry);

 insert into polys values ('kpc', ST_Buffer(
             ST_Point(-166.9324011::float8, 65.154889::float8,
 4326)::geography,
             290086::integer
         )::geometry);

 insert into polys values ('tonga', ST_Buffer(
             ST_Point(-177.2519031::float8, -18.5973127::float8,
 4326)::geography,
             290086::integer
         )::geometry);

 select name, st_isvalid(geom) from polys;
 }}}

 The main thing to note is that taking large buffers of objects in
 geography may yield invalid outputs, since the buffer function in
 geography is a nasty hack. In geometry of course a buffer of a point is a
 circle and never invalid, but that's not what is happening here.

 There is still an "interesting" bit left, and that is is that the pairwise
 and the aggregate versions of union are returning different results.

 {{{
 select st_union(geom) from polys;

 select st_union(a.geom, b.geom)
 from polys a
 cross join polys b
 where a.name = 'kpc' and b.name = 'tonga';
 }}}

 If you backtrace from inside the overlay code where that TopologyException
 is thrown, you'll find that the process is actually going through
 different code lines. The aggregate goes through the cascaded union, which
 is very complex, while the pairwise just goes straight into the overlay
 code.

 If you make valid inputs, you can get a result from both the aggregate and
 pairwise union code lines.

 {{{
 insert into polys
 select name || ' valid', st_makevalid(geom) as geom
 from polys
 where name in ('kpc', 'tonga');

 select st_area(st_union(geom)) from polys where name ~ 'valid';

 select st_area(st_union(a.geom, b.geom))
 from polys a
 cross join polys b
 where a.name = 'kpc valid'
 and b.name = 'tonga valid'
 }}}

 Note however, that if you compare the result of the pairwise union of the
 invalid inputs to the result for the valid inputs, the answer is wrong.

 {{{
 select st_area(st_union(a.geom, b.geom))
 from polys a
 cross join polys b
 where a.name = 'kpc'
 and b.name = 'tonga'
 }}}

 So the moral of the story is not "pairwise union is more resistant to
 invalid inputs than aggregate union", it is "invalid inputs can fail in
 different ways through different code lines, so you really want to avoid
 invalid inputs".

 I sometimes wonder if we should do automagical makevalid as part of the
 try/catch block on the overlay code, so the case of the TopologyException
 would end up actually working, automagically (catch exception, make valid,
 retry). But seeing the silent failure of the pairwise code makes me
 question that. Automagical makevalid would make those cases of silent
 failure even more likely to just slide by people's notice.
-- 
Ticket URL: <https://trac.osgeo.org/postgis/ticket/5392#comment:5>
PostGIS <http://trac.osgeo.org/postgis/>
The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project.


More information about the postgis-tickets mailing list