Opened 13 hours ago
Last modified 12 hours ago
#5835 new defect
The variants of ST_Union gives results that are inconsistent with each other
Reported by: | nbvfgh | Owned by: | pramsey |
---|---|---|---|
Priority: | high | Milestone: | PostGIS 3.6.0 |
Component: | postgis | Version: | 3.5.x |
Keywords: | Cc: |
Description
CREATE TABLE t1(geom geometry); CREATE TABLE t2(geom geometry); INSERT INTO t1 VALUES('GEOMETRYCOLLECTION(POLYGON EMPTY, POINT EMPTY, LINESTRING(10 10, 10 10))'::geometry); INSERT INTO t2 VALUES('POINT(1 1)'::geometry); -- Two-input variant SELECT ST_AsText(ST_Union(t1.geom, t2.geom)) FROM t1, t2; -- result{GEOMETRYCOLLECTION(POLYGON EMPTY,POINT EMPTY,LINESTRING(0 0,0 0),POINT(1 1))} -- Array variant SELECT ST_AsText(ST_Union(ST_Collect(ARRAY[t1.geom, t2.geom]))) FROM t1, t2; -- result:{GEOMETRYCOLLECTION(POINT(1 1),LINESTRING EMPTY)}
Two-input variant returns redundant Empty Geometries, a Linestring of length 0 and a Point, while Array variant only returns an Empty Linestring of length 0 and a Point.
This will result in very inconsistent calculations. For example:
SELECT ST_Buffer(ST_Union(t1.geom, t2.geom), 10) FROM t1, t2; -- result{POLYGON((0.08966060458567 10.91033939541433,0.192147195967696 11.950903220161283,0.761204674887132 13.826834323650896,1.685303876974546 15.55570233019602,2.928932188134523 17.071067811865476,4.444297669803978 18.314696123025453,6.173165676349097 19.238795325112864,8.049096779838713 19.8078528040323,10 20,11.950903220161283 19.807852804032304,13.8268343236509 19.238795325112868,15.555702330196018 18.314696123025456,17.071067811865476 17.071067811865476,18.314696123025453 15.555702330196022,19.238795325112864 13.826834323650903,19.8078528040323 11.950903220161287,20 10,19.807852804032304 8.049096779838717,19.238795325112868 6.173165676349102,18.314696123025453 4.444297669803978,17.071067811865476 2.928932188134525,15.555702330196024 1.685303876974547,13.826834323650898 0.761204674887132,11.950903220161283 0.192147195967696,10.91033939541433 0.08966060458567,10.807852804032304 -0.950903220161282,10.238795325112868 -2.826834323650898,9.314696123025453 -4.555702330196022,8.071067811865476 -6.071067811865475,6.555702330196023 -7.314696123025453,4.826834323650898 -8.238795325112868,2.950903220161283 -8.807852804032304,1 -9,-0.950903220161282 -8.807852804032304,-2.826834323650897 -8.238795325112868,-4.55570233019602 -7.314696123025454,-6.071067811865475 -6.071067811865476,-7.314696123025453 -4.555702330196022,-8.238795325112868 -2.826834323650899,-8.807852804032304 -0.950903220161286,-9 1,-8.807852804032304 2.950903220161284,-8.238795325112868 4.826834323650896,-7.314696123025454 6.55570233019602,-6.071067811865477 8.071067811865476,-4.555702330196022 9.314696123025453,-2.826834323650903 10.238795325112864,-0.950903220161287 10.807852804032303,0.08966060458567 10.91033939541433))} SELECT ST_Buffer(ST_Union(ST_Collect(ARRAY[t1.geom, t2.geom])), 10) FROM t1, t2; --result:{POLYGON((11 1,10.807852804032304 -0.950903220161282,10.238795325112868 -2.826834323650898,9.314696123025453 -4.555702330196022,8.071067811865476 -6.071067811865475,6.555702330196023 -7.314696123025453,4.826834323650898 -8.238795325112868,2.950903220161283 -8.807852804032304,1 -9,-0.950903220161282 -8.807852804032304,-2.826834323650897 -8.238795325112868,-4.55570233019602 -7.314696123025454,-6.071067811865475 -6.071067811865476,-7.314696123025453 -4.555702330196022,-8.238795325112868 -2.826834323650899,-8.807852804032304 -0.950903220161286,-9 1,-8.807852804032304 2.950903220161284,-8.238795325112868 4.826834323650896,-7.314696123025454 6.55570233019602,-6.071067811865477 8.071067811865476,-4.555702330196022 9.314696123025453,-2.826834323650903 10.238795325112864,-0.950903220161287 10.807852804032303,1 11,2.950903220161283 10.807852804032304,4.8268343236509 10.238795325112866,6.555702330196018 9.314696123025454,8.071067811865474 8.071067811865477,9.314696123025453 6.555702330196022,10.238795325112864 4.826834323650904,10.807852804032303 2.950903220161287,11 1))}
The buffer of the ST-Union result set consists of two circular regions, while the buffer of the ST-UnaryUnion result set consists of one circular region. In order to see the difference more intuitively, I have uploaded the relevant attachments
version:POSTGIS="3.6.0dev 3.5.0-91-g593df9088" [EXTENSION] PGSQL="170" GEOS="3.13.0-CAPI-1.19.0" SFCGAL="SFCGAL 1.5.2, CGAL 5.6.1, BOOST 1.84.0"
Attachments (3)
Change History (6)
by , 13 hours ago
Attachment: | Snipaste_2025-01-09_12-37-01.png added |
---|
follow-up: 3 comment:1 by , 12 hours ago
Are you sure about the result of the two-input variant? I get:
SELECT ST_AsText(ST_Union( 'GEOMETRYCOLLECTION(POLYGON EMPTY, POINT EMPTY, LINESTRING(10 10, 10 10))'::geometry, 'POINT(1 1)'::geometry)); st_astext ---------------------------------------------------------------------------------- GEOMETRYCOLLECTION(POLYGON EMPTY,POINT EMPTY,LINESTRING(10 10,10 10),POINT(1 1))
Still inconsistent, of course.
comment:2 by , 12 hours ago
One bug is that the overlay operations should not return collections containing empty elements.
Apart from that, the inconsistency is probably due to two things:
- the implementation of
ST_Union(A, B)
may have a bug in handlingGeometryCollection
s - the implementation of
ST_Union(C)
likely strips zero-lengthLineString
s from the output. This is a GEOS bug documented here: https://github.com/libgeos/geos/issues/1136
comment:3 by , 12 hours ago
Replying to mdavis:
Are you sure about the result of the two-input variant? I get:
SELECT ST_AsText(ST_Union( 'GEOMETRYCOLLECTION(POLYGON EMPTY, POINT EMPTY, LINESTRING(10 10, 10 10))'::geometry, 'POINT(1 1)'::geometry)); st_astext ---------------------------------------------------------------------------------- GEOMETRYCOLLECTION(POLYGON EMPTY,POINT EMPTY,LINESTRING(10 10,10 10),POINT(1 1))Still inconsistent, of course.
Yes, I have double-checked it, and I am sure about the result of the two-input variant is
GEOMETRYCOLLECTION(POLYGON EMPTY,POINT EMPTY,LINESTRING(0 0,0 0),POINT(1 1))
Buffer of Array variant